public object Read(ContentStream stream, object existingObject) { if (existingObject == null) { BinaryReader binaryReader = new BinaryReader(stream); bool flag = binaryReader.ReadBoolean(); int channelsCount = binaryReader.ReadInt32(); int samplingFrequency = binaryReader.ReadInt32(); int bytesCount = binaryReader.ReadInt32(); if (flag) { MemoryStream memoryStream = new MemoryStream(); using (StreamingSource streamingSource = Ogg.Stream(stream)) { streamingSource.CopyTo(memoryStream); if (memoryStream.Length > int.MaxValue) { throw new InvalidOperationException("Audio data too long."); } memoryStream.Position = 0L; return(new SoundBuffer(memoryStream, (int)memoryStream.Length, channelsCount, samplingFrequency)); } } return(new SoundBuffer(stream, bytesCount, channelsCount, samplingFrequency)); } throw new NotSupportedException(); }
public void Write(string projectDirectory, Stream stream) { using (Stream stream2 = Storage.OpenFile(Storage.CombinePaths(projectDirectory, Sound), OpenFileMode.Read)) { if (Ogg.IsOggStream(stream2)) { StreamingSource streamingSource = Ogg.Stream(stream2); if (OggCompressed) { if (stream2.Length > int.MaxValue) { throw new InvalidOperationException("Audio data too long."); } BinaryWriter binaryWriter = new BinaryWriter(stream); binaryWriter.Write(OggCompressed); binaryWriter.Write(streamingSource.ChannelsCount); binaryWriter.Write(streamingSource.SamplingFrequency); binaryWriter.Write((int)stream2.Length); stream2.Position = 0L; stream2.CopyTo(stream); } else { WritePcm(stream, streamingSource); } } else { if (!Wav.IsWavStream(stream2)) { throw new InvalidOperationException("Unrecognized sound format."); } if (OggCompressed) { throw new InvalidOperationException("Ogg compression not available for WAV format sound files."); } WritePcm(stream, Wav.Stream(stream2)); } } }
static void ClipTestB(uint[] b, int vals, int bits, uint[] comp, int compsize) { int bytes; byte *buffer; Ogg.oggpackB_reset(ref o); for (int i = 0; i < vals; i++) { Ogg.oggpackB_write(ref o, b[i], bits > 0 ? bits : iLog(b[i])); } buffer = Ogg.oggpackB_get_buffer(ref o); bytes = Ogg.oggpackB_bytes(ref o); if (bytes != compsize) { throw new Exception("wrong number of bytes!"); } for (int i = 0; i < bytes; i++) { if (buffer[i] != comp[i]) { for (int j = 0; j < bytes; j++) { Console.WriteLine(buffer[j] + " , " + comp[j]); } throw new Exception("wrote incorrect value!"); } } Ogg.oggpackB_readinit(ref r, buffer, bytes); for (int i = 0; i < vals; i++) { int tbit = bits > 0 ? bits : iLog(b[i]); if (Ogg.oggpackB_look(ref r, tbit) == -1) { throw new Exception("out of data!"); } if (Ogg.oggpackB_look(ref r, tbit) != (b[i] & mask[tbit])) { throw new Exception("looked at incorrect value!"); } if (tbit == 1) { if (Ogg.oggpackB_look1(ref r) != (b[i] & mask[tbit])) { throw new Exception("looked at single bit incorrect value!"); } } if (tbit == 1) { if (Ogg.oggpackB_read1(ref r) != (b[i] & mask[tbit])) { throw new Exception("read incorrect single bit value!"); } } else if (Ogg.oggpackB_read(ref r, tbit) != (b[i] & mask[tbit])) { throw new Exception("read incorrect value!"); } } if (Ogg.oggpackB_bytes(ref r) != bytes) { throw new Exception("leftover bytes after read!"); } }
static public void Test() { byte *buffer; int bytes = 0; /* Test read/write together */ /* Later we test against pregenerated bitstreams */ Ogg.oggpack_writeinit(ref o); Console.Write("Small preclipped packing (LSb): "); ClipTest(testBuffer1, testSize1, 0, one, oneSize); Console.WriteLine("ok."); Console.Write("Null bit call (LSb): "); ClipTest(testBuffer3, testSize3, 0, two, twoSize); Console.WriteLine("ok."); Console.Write("Large preclipped packing (LSb): "); ClipTest(testBuffer2, testSize2, 0, three, threeSize); Console.WriteLine("ok."); Console.Write("32 bit precliiped packing (LSb): "); { Ogg.oggpack_reset(ref o); for (int i = 0; i < testSize2; i++) { Ogg.oggpack_write(ref o, large[i], 32); } buffer = Ogg.oggpack_get_buffer(ref o); bytes = Ogg.oggpack_bytes(ref o); Ogg.oggpack_readinit(ref r, buffer, bytes); for (int i = 0; i < testSize2; i++) { if (Ogg.oggpack_look(ref r, 32) == -1) { throw new Exception("out of data. failed!"); } if (Ogg.oggpack_look(ref r, 32) != large[i]) { throw new Exception("read incorrect value! " + Ogg.oggpack_look(ref r, 32) + " != " + large[1]); } Ogg.oggpack_adv(ref r, 32); } if (Ogg.oggpack_bytes(ref r) != bytes) { throw new Exception("leftover bytes after read!"); } Console.WriteLine("ok."); } Console.Write("Small unclipped packing (LSb): "); ClipTest(testBuffer1, testSize1, 7, four, fourSize); Console.WriteLine("ok."); Console.Write("Large unclipped packing (LSb): "); ClipTest(testBuffer2, testSize2, 17, five, fiveSize); Console.WriteLine("ok."); Console.Write("Single bit unclipped packing (LSb): "); ClipTest(testBuffer3, testSize3, 1, six, sixSize); Console.WriteLine("ok."); Console.Write("Testing read past end (LSb): "); { byte *temp = (byte *)Ogg._ogg_malloc(8); try { for (int i = 0; i < 8; i++) { temp[i] = 0; } Ogg.oggpack_readinit(ref r, temp, 8); for (int i = 0; i < 64; i++) { if (Ogg.oggpack_read(ref r, 1) != 0) { throw new Exception("failed; got -1 prematurely."); } } if (Ogg.oggpack_look(ref r, 1) != -1 || Ogg.oggpack_read(ref r, 1) != -1) { throw new Exception("failed; read past end without -1"); } for (int i = 0; i < 8; i++) { temp[i] = 0; } Ogg.oggpack_readinit(ref r, temp, 8); if (Ogg.oggpack_read(ref r, 30) != 0 || Ogg.oggpack_read(ref r, 16) != 0) { throw new Exception("failed 2; got -1 prematurely."); } if (Ogg.oggpack_look(ref r, 18) != 0 || Ogg.oggpack_look(ref r, 18) != 0) { throw new Exception("failed 3; got -1 prematurely."); } if (Ogg.oggpack_look(ref r, 19) != -1 || Ogg.oggpack_look(ref r, 19) != -1) { throw new Exception("failed 3; got -1 prematurely."); } if (Ogg.oggpack_look(ref r, 32) != -1 || Ogg.oggpack_look(ref r, 32) != -1) { throw new Exception("failed 3; got -1 prematurely."); } Ogg.oggpack_writeclear(ref o); Console.WriteLine("ok."); } finally { Ogg._ogg_free(temp); } } /********** lazy, cut-n-paste retest with MSb packing ***********/ /* Test read/write together */ /* Later we test against pregenerated bitstreams */ Ogg.oggpackB_writeinit(ref o); Console.Write("Small preclipped packing (MSb): "); ClipTestB(testBuffer1, testSize1, 0, oneB, oneSize); Console.WriteLine("ok."); Console.Write("Null bit call (LSb): "); ClipTestB(testBuffer3, testSize3, 0, twoB, twoSize); Console.WriteLine("ok."); Console.Write("Large preclipped packing (LSb): "); ClipTestB(testBuffer2, testSize2, 0, threeB, threeSize); Console.WriteLine("ok."); Console.Write("32 bit precliiped packing (LSb): "); { Ogg.oggpackB_reset(ref o); for (int i = 0; i < testSize2; i++) { Ogg.oggpackB_write(ref o, large[i], 32); } buffer = Ogg.oggpackB_get_buffer(ref o); bytes = Ogg.oggpackB_bytes(ref o); Ogg.oggpackB_readinit(ref r, buffer, bytes); for (int i = 0; i < testSize2; i++) { if (Ogg.oggpackB_look(ref r, 32) == -1) { throw new Exception("out of data. failed!"); } if (Ogg.oggpackB_look(ref r, 32) != large[i]) { throw new Exception("read incorrect value! " + Ogg.oggpackB_look(ref r, 32) + " != " + large[1]); } Ogg.oggpackB_adv(ref r, 32); } if (Ogg.oggpackB_bytes(ref r) != bytes) { throw new Exception("leftover bytes after read!"); } Console.WriteLine("ok."); } Console.Write("Small unclipped packing (LSb): "); ClipTestB(testBuffer1, testSize1, 7, fourB, fourSize); Console.WriteLine("ok."); Console.Write("Large unclipped packing (LSb): "); ClipTestB(testBuffer2, testSize2, 17, fiveB, fiveSize); Console.WriteLine("ok."); Console.Write("Single bit unclipped packing (LSb): "); ClipTestB(testBuffer3, testSize3, 1, sixB, sixSize); Console.WriteLine("ok."); Console.Write("Testing read past end (LSb): "); { byte *temp = (byte *)Ogg._ogg_malloc(8); try { for (int i = 0; i < 8; i++) { temp[i] = 0; } Ogg.oggpackB_readinit(ref r, temp, 8); for (int i = 0; i < 64; i++) { if (Ogg.oggpackB_read(ref r, 1) != 0) { throw new Exception("failed; got -1 prematurely."); } } if (Ogg.oggpackB_look(ref r, 1) != -1 || Ogg.oggpackB_read(ref r, 1) != -1) { throw new Exception("failed; read past end without -1"); } for (int i = 0; i < 8; i++) { temp[i] = 0; } Ogg.oggpackB_readinit(ref r, temp, 8); if (Ogg.oggpackB_read(ref r, 30) != 0 || Ogg.oggpackB_read(ref r, 16) != 0) { throw new Exception("failed 2; got -1 prematurely."); } if (Ogg.oggpackB_look(ref r, 18) != 0 || Ogg.oggpackB_look(ref r, 18) != 0) { throw new Exception("failed 3; got -1 prematurely."); } if (Ogg.oggpackB_look(ref r, 19) != -1 || Ogg.oggpackB_look(ref r, 19) != -1) { throw new Exception("failed 3; got -1 prematurely."); } if (Ogg.oggpackB_look(ref r, 32) != -1 || Ogg.oggpackB_look(ref r, 32) != -1) { throw new Exception("failed 3; got -1 prematurely."); } Ogg.oggpackB_writeclear(ref o); Console.WriteLine("ok."); } finally { Ogg._ogg_free(temp); } } }
private void TagTestWithSave (ref Ogg.XiphComment tag, TagTestFunc testFunc) { testFunc (tag, "Before Save"); tag = new Ogg.XiphComment (tag.Render (true)); testFunc (tag, "After Save"); }
public static void Write(byte[] data, string file) { Unity_Studio.EndianStream stream = new Unity_Studio.EndianStream(new System.IO.MemoryStream(data), Unity_Studio.EndianType.LittleEndian); // Because constructor is broken stream.endian = Unity_Studio.EndianType.LittleEndian; string magic = stream.ReadASCII(4); if (!magic.Equals("FSB5")) { return; } uint version = stream.ReadUInt32(); uint numSamples = stream.ReadUInt32(); uint sampleHeadersSize = stream.ReadUInt32(); uint nameTableSize = stream.ReadUInt32(); uint dataSize = stream.ReadUInt32(); uint mode = stream.ReadUInt32(); string zero = stream.ReadASCII(8); string hash = stream.ReadASCII(16); string dummy = stream.ReadASCII(8); long nameOffset = stream.Position + sampleHeadersSize; long baseOffset = nameOffset + nameTableSize; // Only support Vorbis if (mode != (int)FSBAudioFormat.FMOD_SOUND_FORMAT_VORBIS) { return; } for (int i = 0; i < numSamples; i++) { Ogg ogg = new Ogg(); uint offset = stream.ReadUInt32(); bool extraHeaders = (offset & 0x01) != 0; uint type = offset & ((1 << 7) - 1); offset = (offset >> 7) * 0x20; ogg.channels = (type >> 5) + 1; ogg.frequency = 44100; switch ((type >> 1) & ((1 << 4) - 1)) { case 0: ogg.frequency = 4000; break; case 1: ogg.frequency = 8000; break; case 2: ogg.frequency = 11000; break; case 3: ogg.frequency = 12000; break; case 4: ogg.frequency = 16000; break; case 5: ogg.frequency = 22050; break; case 6: ogg.frequency = 24000; break; case 7: ogg.frequency = 32000; break; case 8: ogg.frequency = 44100; break; case 9: ogg.frequency = 48000; break; case 10: ogg.frequency = 96000; break; default: ogg.frequency = 44100; break; } uint unknown = stream.ReadUInt32() >> 2; while (extraHeaders) { byte dataByte = stream.ReadByte(); extraHeaders = (dataByte & 0x01) != 0; long extraLen = dataByte >> 1; extraLen += stream.ReadByte() << 7; extraLen += stream.ReadByte() << 15; dataByte = stream.ReadByte(); if (dataByte == 0x02) { ogg.channels = stream.ReadByte(); extraLen -= 1; } if (dataByte == 0x04) { ogg.frequency = stream.ReadUInt32(); extraLen -= 4; } if (dataByte == 0x06) { ogg.loopStart = stream.ReadUInt32(); ogg.loopEnd = stream.ReadUInt32(); extraLen -= 8; } if (dataByte == 0x16) { ogg.crc32 = stream.ReadUInt32(); extraLen -= 4; } stream.Position += extraLen; } long nextFilePos = stream.Position; long size = stream.ReadUInt32(); if (size == 0) { size = dataSize + baseOffset; } else { size = ((size >> 7) * 0x20) + baseOffset; } if (size < 0 || size > data.Length) { size = data.Length; } long fileOffset = baseOffset + offset; size -= fileOffset; if (i == 0) { WriteFile(stream, file, (int)fileOffset, (int)size, ogg); } else { WriteFile(stream, file + i, (int)fileOffset, (int)size, ogg); } stream.Position = nextFilePos; } stream.Dispose(true); }
public static void RebuildHeader(Ogg ogg) { // out id comment setup }
public static void WriteFile(Unity_Studio.EndianStream stream, string file, int offset, int size, Ogg ogg) { // Write to disk using (BinaryWriter writer = new BinaryWriter(File.Open(file, FileMode.Create))) { // Only support header CRC 3605052372 for now OggVorbisHeader head = new OggVorbisHeader(); HeaderPacketBuilder hpb = new HeaderPacketBuilder(); CodecSetup cSetup = new CodecSetup(null); cSetup.BlockSizes[0] = 256; cSetup.BlockSizes[1] = 2048; VorbisInfo info = new VorbisInfo(cSetup, (int)ogg.channels, (int)ogg.frequency, 0); OggPacket headerInfo = hpb.BuildInfoPacket(info); Comments comments = new Comments(); if (ogg.loopStart > 0 && ogg.loopEnd > 0) { comments.AddTag("LOOP_START", ogg.loopStart.ToString()); comments.AddTag("LOOP_END", ogg.loopEnd.ToString()); } OggPacket headerComment = hpb.BuildCommentsPacket(comments); OggPacket headerSetup = new OggPacket(OggVorbisHeader.GetHeader(ogg.crc32), false, 0, 2); OggStream output = new OggStream(1); output.PacketIn(headerInfo); output.PacketIn(headerComment); output.PacketIn(headerSetup); stream.Position = offset; UInt16 packetSize = stream.ReadUInt16(); int prevPacketNo = 2; int prevGranulePos = 0; while (packetSize > 0) { OggPacket packet = new OggPacket(stream.ReadBytes(packetSize), false, 0, prevPacketNo + 1); byte firstByte = packet.PacketData[0]; // OK for stereo int granuleSize = 128; if ((firstByte & 2) != 0) { granuleSize = 1024; } if (ogg.channels == 1) { granuleSize /= 4; } packet.GranulePosition = prevGranulePos + granuleSize; if (stream.Position + 2 < offset + size) { packetSize = stream.ReadUInt16(); } else { packetSize = 0; } packet.EndOfStream = packetSize == 0; prevGranulePos = packet.GranulePosition; prevPacketNo = packet.PacketNumber; output.PacketIn(packet); OggPage page = null; if (output.PageOut(out page, true)) { writer.Write(page.Header); writer.Write(page.Body); } } //float vorbis_quality = ((ogg.quality - 1) + (ogg.quality - 100) * 0.1f) / 99.0f; //VorbisInfo.InitVariableBitRate(ogg.channels, ogg.frequency, ogg.) //writer.Write(); writer.Close(); } }