private static void InitOggStream(int sampleRate, int channels, out OggStream oggStream, out ProcessingState processingState) { // Stores all the static vorbis bitstream settings var info = VorbisInfo.InitVariableBitRate(channels, sampleRate, 0.5f); // set up our packet->stream encoder var serial = new Random().Next(); oggStream = new OggStream(serial); // ========================================================= // HEADER // ========================================================= // Vorbis streams begin with three headers; the initial header (with // most of the codec setup parameters) which is mandated by the Ogg // bitstream spec. The second header holds any comment fields. The // third header holds the bitstream codebook. var comments = new Comments(); comments.AddTag("ARTIST", "TTS"); var infoPacket = HeaderPacketBuilder.BuildInfoPacket(info); var commentsPacket = HeaderPacketBuilder.BuildCommentsPacket(comments); var booksPacket = HeaderPacketBuilder.BuildBooksPacket(info); oggStream.PacketIn(infoPacket); oggStream.PacketIn(commentsPacket); oggStream.PacketIn(booksPacket); // ========================================================= // BODY (Audio Data) // ========================================================= processingState = ProcessingState.Create(info); }
public void Convert(string inputFile, string outputFile) { using (var outputStream = File.Create(outputFile)) { var channels = AudioSampleReader.ReadChannels(inputFile, out var waveFormat); var oggStream = new OggStream(StaticRandom.Rng.Next()); // Build header var headerBuilder = new HeaderPacketBuilder(); var audioInfo = VorbisInfo.InitVariableBitRate(channels.Count, waveFormat.SampleRate, 0.1f); var infoPacket = headerBuilder.BuildInfoPacket(audioInfo); var commentsPacket = headerBuilder.BuildCommentsPacket(new Comments()); var booksPacket = headerBuilder.BuildBooksPacket(audioInfo); oggStream.PacketIn(infoPacket); oggStream.PacketIn(commentsPacket); oggStream.PacketIn(booksPacket); WriteHeader(oggStream, outputStream); // Store audio var processingState = ProcessingState.Create(audioInfo); var normalizedChannels = Normalize(channels); processingState.WriteData(normalizedChannels, normalizedChannels[0].Length); processingState.WriteEndOfStream(); WriteAudio(oggStream, outputStream, processingState); } }
/// <summary> /// VorbisFileWriter that actually writes to a stream /// </summary> /// <param name="outStream">Stream to be written to</param> /// <param name="sampleRate">The sample rate to use</param> /// <param name="channels">The number of channels to use</param> /// <param name="quality">The base quality for Vorbis encoding</param> public VorbisFileWriter(Stream outStream, int sampleRate, int channels, float quality = 0.5f) { this.outStream = outStream; SampleRate = sampleRate; Channels = channels; if (!startBuffers.ContainsKey(sampleRate)) { throw new InvalidOperationException($"Vorbis writer does not support {sampleRate} sample rate."); } // Stores all the static vorbis bitstream settings Console.WriteLine($"Initiating variable bit rate: {channels} channels, {sampleRate} sample rate, {quality} quality"); var info = VorbisInfo.InitVariableBitRate(channels, sampleRate, quality); // set up our packet->stream encoder var serial = MainWindow.MainRandom.Next(); oggStream = new OggStream(serial); // ========================================================= // HEADER // ========================================================= // Vorbis streams begin with three headers; the initial header (with // most of the codec setup parameters) which is mandated by the Ogg // bitstream spec. The second header holds any comment fields. The // third header holds the bitstream codebook. var headerBuilder = new HeaderPacketBuilder(); var comments = new Comments(); var infoPacket = headerBuilder.BuildInfoPacket(info); var commentsPacket = headerBuilder.BuildCommentsPacket(comments); var booksPacket = headerBuilder.BuildBooksPacket(info); oggStream.PacketIn(infoPacket); oggStream.PacketIn(commentsPacket); oggStream.PacketIn(booksPacket); // Flush to force audio data onto its own page per the spec FlushPages(oggStream, outStream, true); // ========================================================= // BODY (Audio Data) // ========================================================= processingState = ProcessingState.Create(info); // Append some zeros at the start so the result has the same length as the input int bufferSize = startBuffers[sampleRate]; float[][] outSamples = new float[channels][]; for (int ch = 0; ch < channels; ch++) { outSamples[ch] = new float[bufferSize]; } processingState.WriteData(outSamples, bufferSize); }
private static byte[] GenerateFile(float[][] floatSamples, int sampleRate, int channels) { using MemoryStream outputData = new MemoryStream(); // Stores all the static vorbis bitstream settings var info = VorbisInfo.InitVariableBitRate(channels, sampleRate, 0.5f); // set up our packet->stream encoder var serial = new Random().Next(); var oggStream = new OggStream(serial); // ========================================================= // HEADER // ========================================================= // Vorbis streams begin with three headers; the initial header (with // most of the codec setup parameters) which is mandated by the Ogg // bitstream spec. The second header holds any comment fields. The // third header holds the bitstream codebook. var comments = new Comments(); comments.AddTag("ARTIST", "TEST"); var infoPacket = HeaderPacketBuilder.BuildInfoPacket(info); var commentsPacket = HeaderPacketBuilder.BuildCommentsPacket(comments); var booksPacket = HeaderPacketBuilder.BuildBooksPacket(info); oggStream.PacketIn(infoPacket); oggStream.PacketIn(commentsPacket); oggStream.PacketIn(booksPacket); // Flush to force audio data onto its own page per the spec FlushPages(oggStream, outputData, true); // ========================================================= // BODY (Audio Data) // ========================================================= var processingState = ProcessingState.Create(info); for (int readIndex = 0; readIndex <= floatSamples[0].Length; readIndex += WriteBufferSize) { if (readIndex == floatSamples[0].Length) { processingState.WriteEndOfStream(); } else { processingState.WriteData(floatSamples, WriteBufferSize, readIndex); } while (!oggStream.Finished && processingState.PacketOut(out OggPacket packet)) { oggStream.PacketIn(packet); FlushPages(oggStream, outputData, false); } } FlushPages(oggStream, outputData, true); return(outputData.ToArray()); }
private static void Main() { var stdin = new FileStream(@"unencoded.raw", FileMode.Open, FileAccess.Read); var stdout = new FileStream(@"encoded.ogg", FileMode.Create, FileAccess.Write); // StripWavHeader(stdin); // Stores all the static vorbis bitstream settings var info = VorbisInfo.InitVariableBitRate(2, 44100, 0.1f); // set up our packet->stream encoder var serial = new Random().Next(); var oggStream = new OggStream(serial); // ========================================================= // HEADER // ========================================================= // Vorbis streams begin with three headers; the initial header (with // most of the codec setup parameters) which is mandated by the Ogg // bitstream spec. The second header holds any comment fields. The // third header holds the bitstream codebook. var headerBuilder = new HeaderPacketBuilder(); var comments = new Comments(); comments.AddTag("ARTIST", "TEST"); var infoPacket = headerBuilder.BuildInfoPacket(info); var commentsPacket = headerBuilder.BuildCommentsPacket(comments); var booksPacket = headerBuilder.BuildBooksPacket(info); oggStream.PacketIn(infoPacket); oggStream.PacketIn(commentsPacket); oggStream.PacketIn(booksPacket); // Flush to force audio data onto its own page per the spec OggPage page; while (oggStream.PageOut(out page, true)) { stdout.Write(page.Header, 0, page.Header.Length); stdout.Write(page.Body, 0, page.Body.Length); } // ========================================================= // BODY (Audio Data) // ========================================================= var processingState = ProcessingState.Create(info); var buffer = new float[info.Channels][]; buffer[0] = new float[SampleSize]; buffer[1] = new float[SampleSize]; var readbuffer = new byte[SampleSize * 4]; while (!oggStream.Finished) { var bytes = stdin.Read(readbuffer, 0, readbuffer.Length); if (bytes == 0) { processingState.WriteEndOfStream(); } else { var samples = bytes / 4; for (var i = 0; i < samples; i++) { // uninterleave samples buffer[0][i] = (short)((readbuffer[i * 4 + 1] << 8) | (0x00ff & readbuffer[i * 4])) / 32768f; buffer[1][i] = (short)((readbuffer[i * 4 + 3] << 8) | (0x00ff & readbuffer[i * 4 + 2])) / 32768f; } processingState.WriteData(buffer, samples); } OggPacket packet; while (!oggStream.Finished && processingState.PacketOut(out packet)) { oggStream.PacketIn(packet); while (!oggStream.Finished && oggStream.PageOut(out page, false)) { stdout.Write(page.Header, 0, page.Header.Length); stdout.Write(page.Body, 0, page.Body.Length); } } } stdin.Close(); stdout.Close(); }
// OGG-Conversion private void OGGConversion() { progBarVisible = true; try { FileStream stdin; FileStream stdout; if (!ConvUsespreset) { stdin = new FileStream(ConvTitle + ".wav", FileMode.Open, FileAccess.Read); stdout = new FileStream(ConvTitle + ".ogg", FileMode.Create, FileAccess.Write); } else { stdin = new FileStream(Filepath + "\\" + ConvTitle + ".wav", FileMode.Open, FileAccess.Read); stdout = new FileStream(Filepath + "\\" + ConvTitle + ".ogg", FileMode.Create, FileAccess.Write); } var info = VorbisInfo.InitVariableBitRate(2, 48000, 0.1f); var serial = new Random().Next(); var oggStream = new OggStream(serial); var headerBuilder = new HeaderPacketBuilder(); var comments = new Comments(); comments.AddTag("ARTIST", ""); var infoPacket = headerBuilder.BuildInfoPacket(info); var commentsPacket = headerBuilder.BuildCommentsPacket(comments); var booksPacket = headerBuilder.BuildBooksPacket(info); oggStream.PacketIn(infoPacket); oggStream.PacketIn(commentsPacket); oggStream.PacketIn(booksPacket); OggPage page; while (oggStream.PageOut(out page, true)) { stdout.Write(page.Header, 0, page.Header.Length); stdout.Write(page.Body, 0, page.Body.Length); } var processingState = ProcessingState.Create(info); var buffer = new float[info.Channels][]; buffer[0] = new float[SampleSize]; buffer[1] = new float[SampleSize]; var readbuffer = new byte[SampleSize * 4]; while (!oggStream.Finished) { var bytes = stdin.Read(readbuffer, 0, readbuffer.Length); if (bytes == 0) { processingState.WriteEndOfStream(); } else { var samples = bytes / 4; progBarMax = samples; progBarWEE = false; for (var i = 0; i < samples; i++) { // uninterleave samples buffer[0][i] = (short)((readbuffer[i * 4 + 1] << 8) | (0x00ff & readbuffer[i * 4])) / 32768f; buffer[1][i] = (short)((readbuffer[i * 4 + 3] << 8) | (0x00ff & readbuffer[i * 4 + 2])) / 32768f; progBarValue = i; } progBarWEE = true; processingState.WriteData(buffer, samples); } OggPacket packet; while (!oggStream.Finished && processingState.PacketOut(out packet)) { oggStream.PacketIn(packet); while (!oggStream.Finished && oggStream.PageOut(out page, false)) { stdout.Write(page.Header, 0, page.Header.Length); stdout.Write(page.Body, 0, page.Body.Length); } } } stdin.Close(); stdout.Close(); if (!ConvUsespreset) { File.Delete(ConvTitle + ".wav"); } else { File.Delete(Filepath + "\\" + ConvTitle + ".wav"); } } catch (Exception error) { errortext = Convert.ToString(error); } progBarVisible = false; Thread.CurrentThread.Abort(); }
public byte[] ConvertWaveBytes(byte[] waveBytes) { // Stores all the static vorbis bitstream settings VorbisInfo info = VorbisInfo.InitVariableBitRate(2, 44100, 0.1f); // set up our packet->stream encoder int serial = new Random().Next(); OggStream oggStream = new OggStream(serial); MemoryStream streamIn = new MemoryStream(waveBytes); MemoryStream streamOut = new MemoryStream(); // Vorbis streams begin with three headers; the initial header (with // most of the codec setup parameters) which is mandated by the Ogg // bitstream spec. The second header holds any comment fields. The // third header holds the bitstream codebook. var headerBuilder = new HeaderPacketBuilder(); var comments = new Comments(); var infoPacket = headerBuilder.BuildInfoPacket(info); var commentsPacket = headerBuilder.BuildCommentsPacket(comments); var booksPacket = headerBuilder.BuildBooksPacket(info); oggStream.PacketIn(infoPacket); oggStream.PacketIn(commentsPacket); oggStream.PacketIn(booksPacket); // Flush to force audio data onto its own page per the spec OggPage page; while (oggStream.PageOut(out page, true)) { streamOut.Write(page.Header, 0, page.Header.Length); streamOut.Write(page.Body, 0, page.Body.Length); } var processingState = ProcessingState.Create(info); var buffer = new float[info.Channels][]; buffer[0] = new float[SampleSize]; buffer[1] = new float[SampleSize]; var readbuffer = new byte[SampleSize]; while (!oggStream.Finished) { int bytes = streamIn.Read(readbuffer, 0, readbuffer.Length); if (bytes == 0) { processingState.WriteEndOfStream(); } else { var samples = bytes; for (var i = 1; i < samples; i += 2) { buffer[0][i] = (short)((readbuffer[i] << 8) | (0x00ff & readbuffer[i - 1])) / 32768f; buffer[1][i] = buffer[0][i]; } processingState.WriteData(buffer, bytes); } while (!oggStream.Finished && processingState.PacketOut(out OggPacket packet)) { oggStream.PacketIn(packet); while (!oggStream.Finished && oggStream.PageOut(out page, false)) { streamOut.Write(page.Header, 0, page.Header.Length); streamOut.Write(page.Body, 0, page.Body.Length); } } } byte[] oggBytes = streamOut.ToArray(); streamIn.Close(); streamOut.Close(); return(oggBytes); }
public static string ConvertMp3toOgg(string mp3Path, string outputDir) { var oggName = Path.GetFileNameWithoutExtension(mp3Path) + ".ogg"; try { using (var mp3 = new Mp3FileReader(mp3Path)) using (var wav = WaveFormatConversionStream.CreatePcmStream(mp3)) using (var ogg = new FileStream(Path.Combine(outputDir, oggName), FileMode.Create, FileAccess.Write)) { const int SampleSize = 4096; // Here's a reference for the code below: // https://github.com/SteveLillis/.NET-Ogg-Vorbis-Encoder/blob/master/OggVorbisEncoder.Example/Encoder.cs var info = VorbisInfo.InitVariableBitRate(2, wav.WaveFormat.SampleRate, 0.5f); // set up our packet->stream encoder var serial = new Random().Next(); var oggStream = new OggStream(serial); // ========================================================= // HEADER // ========================================================= // Vorbis streams begin with three headers; the initial header (with // most of the codec setup parameters) which is mandated by the Ogg // bitstream spec. The second header holds any comment fields. The // third header holds the bitstream codebook. var comments = new Comments(); // comments.AddTag("ARTIST", "TEST"); var infoPacket = HeaderPacketBuilder.BuildInfoPacket(info); var commentsPacket = HeaderPacketBuilder.BuildCommentsPacket(comments); var booksPacket = HeaderPacketBuilder.BuildBooksPacket(info); oggStream.PacketIn(infoPacket); oggStream.PacketIn(commentsPacket); oggStream.PacketIn(booksPacket); // Flush to force audio data onto its own page per the spec OggPage page; while (oggStream.PageOut(out page, true)) { ogg.Write(page.Header, 0, page.Header.Length); ogg.Write(page.Body, 0, page.Body.Length); } // ========================================================= // BODY (Audio Data) // ========================================================= var processingState = ProcessingState.Create(info); var buffer = new float[info.Channels][]; buffer[0] = new float[SampleSize]; buffer[1] = new float[SampleSize]; var readbuffer = new byte[SampleSize * 4]; while (!oggStream.Finished) { var bytes = wav.Read(readbuffer, 0, readbuffer.Length); if (bytes == 0) { processingState.WriteEndOfStream(); } else { var samples = bytes / 4; for (var i = 0; i < samples; i++) { // uninterleave samples buffer[0][i] = (short)((readbuffer[i * 4 + 1] << 8) | (0x00ff & readbuffer[i * 4])) / 32768f; buffer[1][i] = (short)((readbuffer[i * 4 + 3] << 8) | (0x00ff & readbuffer[i * 4 + 2])) / 32768f; } processingState.WriteData(buffer, samples); } while (!oggStream.Finished && processingState.PacketOut(out OggPacket packet)) { oggStream.PacketIn(packet); while (!oggStream.Finished && oggStream.PageOut(out page, false)) { ogg.Write(page.Header, 0, page.Header.Length); ogg.Write(page.Body, 0, page.Body.Length); } } } } } catch (NAudio.MmException e) { Console.WriteLine(e); // Just retry return(ConvertMp3toOgg(mp3Path, outputDir)); } catch (InvalidOperationException e) { Console.WriteLine(e); Console.WriteLine("Error while converting to " + oggName); return(oggName); } return(oggName); }