using Amphora;
using System;
using System.IO;
using System.Linq;
using UnitTestSharp;
using static Susurrus.UnitTests.TestSounds;
namespace Susurrus.UnitTests
{
public class SoundDecoderTests : TestFixture
{
public const string OpusMessage =
"This is an Ogg Opus file, but Susurrus loads only Ogg Vorbis and WAV. Convert it first with " +
"python Scripts/convertaudio.py ";
public const string Mp3Message =
"This is an MP3 file, but Susurrus loads only Ogg Vorbis and WAV. Convert it first with " +
"python Scripts/convertaudio.py ";
public const string UnrecognizedMessage = "This isn't in an audio format Susurrus recognizes.";
public static byte[] WavFile()
{
return WavDecoderTests.Riff(WavDecoderTests.Pcm16MonoFormat(),
WavDecoderTests.Chunk("data", WavDecoderTests.ThreePcm16MonoFrames()));
}
public static byte[] NotAudio()
{
return WavDecoderTests.Ascii("This is just some text, not sound.");
}
public class DecodeBytesTests : TestFixture
{
public void DefaultView_Throws()
{
CheckThrow(typeof(ArgumentException));
SoundDecoder.Decode(default(ByteView));
}
public void ViewOfALargerArray_SniffsAndDecodesOnlyTheWindow()
{
byte[] file = WavFile();
byte[] padded = new byte[file.Length + 30];
Array.Copy(file, 0, padded, 20, file.Length);
DecodedSound sound = SoundDecoder.Decode(new ByteView(padded, startIndex: 20,
endIndex: 20 + file.Length)).Value;
CheckEqual(3, sound.FrameCount);
}
public void Wav_IsDecoded()
{
CheckEqual(3, DecodeAny(WavFile()).Value.FrameCount);
}
public void OggVorbis_IsDecoded()
{
CheckEqual(4410, DecodeAny(LoadFixture("Mono441Hz.ogg")).Value.FrameCount);
}
public void OggOpus_IsRejectedByName()
{
StatusOr result = DecodeAny(LoadFixture("OpusInOgg.ogg"));
CheckEqual(SoundFailures.UnsupportedFormat, KindOf(result));
CheckEqual(OpusMessage, result.Status.Describe());
}
public void Mp3_IsRejectedByName()
{
StatusOr result = DecodeAny(LoadFixture("Mp3WithoutTag.mp3"));
CheckEqual(SoundFailures.UnsupportedFormat, KindOf(result));
CheckEqual(Mp3Message, result.Status.Describe());
}
public void UnrecognizedBytes_AreRejectedAsUnrecognized()
{
StatusOr result = DecodeAny(NotAudio());
CheckEqual(SoundFailures.UnrecognizedFormat, KindOf(result));
CheckEqual(UnrecognizedMessage, result.Status.Describe());
}
public void NoBytes_AreRejectedAsUnrecognized()
{
CheckEqual(SoundFailures.UnrecognizedFormat, KindOf(DecodeAny(new byte[0])));
}
public void ABrokenWav_FailsWithTheWavDecodersFailure()
{
byte[] riffHeaderOnly = WavDecoderTests.Ascii("RIFF\0\0\0\0WAVE");
CheckEqual(SoundFailures.WavMalformed, KindOf(DecodeAny(riffHeaderOnly)));
}
public void ABrokenOgg_FailsWithTheOggDecodersFailure()
{
byte[] cutShort = OggDecoderTests.Truncated(LoadFixture("Mono441Hz.ogg"), 3000);
CheckEqual(SoundFailures.OggFailed, KindOf(DecodeAny(cutShort)));
}
}
public class DecodeStreamTests : TestFixture
{
public void NullStream_Throws()
{
CheckThrow(typeof(ArgumentNullException));
SoundDecoder.Decode((Stream)null);
}
public void SeekableWav_IsDecoded()
{
CheckEqual(3, SoundDecoder.Decode(new MemoryStream(WavFile())).Value.FrameCount);
}
public void SeekableOgg_IsDecoded()
{
using (Stream stream = OpenFixture("Mono441Hz.ogg"))
{
CheckEqual(4410, SoundDecoder.Decode(stream).Value.FrameCount);
}
}
public void SeekableStreamStartingMidWay_DecodesFromItsPosition()
{
MemoryStream stream = new MemoryStream(new byte[7].Concat(WavFile()).ToArray());
stream.Position = 7;
CheckEqual(3, SoundDecoder.Decode(stream).Value.FrameCount);
}
public void ForwardOnlyWav_IsDecoded()
{
CheckEqual(3, SoundDecoder.Decode(new TrickleStream(WavFile(), bytesPerRead: 1)).Value.FrameCount);
}
public void ForwardOnlyOgg_IsDecoded()
{
byte[] file = LoadFixture("Mono441Hz.ogg");
CheckEqual(4410, SoundDecoder.Decode(new TrickleStream(file, bytesPerRead: 200)).Value.FrameCount);
}
public void SeekableUnsupportedFormat_IsRejectedByName()
{
StatusOr result = SoundDecoder.Decode(new MemoryStream(LoadFixture("OpusInOgg.ogg")));
CheckEqual(SoundFailures.UnsupportedFormat, KindOf(result));
CheckEqual(OpusMessage, result.Status.Describe());
}
public void ForwardOnlyUnsupportedFormat_IsRejectedByName()
{
StatusOr result =
SoundDecoder.Decode(new TrickleStream(LoadFixture("OpusInOgg.ogg"), bytesPerRead: 50));
CheckEqual(SoundFailures.UnsupportedFormat, KindOf(result));
CheckEqual(OpusMessage, result.Status.Describe());
}
public void SeekableUnrecognizedBytes_AreRejectedAsUnrecognized()
{
StatusOr result = SoundDecoder.Decode(new MemoryStream(NotAudio()));
CheckEqual(SoundFailures.UnrecognizedFormat, KindOf(result));
CheckEqual(UnrecognizedMessage, result.Status.Describe());
}
public void ForwardOnlyUnrecognizedBytes_AreRejectedAsUnrecognized()
{
StatusOr result = SoundDecoder.Decode(new TrickleStream(NotAudio(), bytesPerRead: 5));
CheckEqual(SoundFailures.UnrecognizedFormat, KindOf(result));
CheckEqual(UnrecognizedMessage, result.Status.Describe());
}
}
}
}