public SoundEffect Load(Stream fobj) { using (var stream = new NVorbis.VorbisReader(fobj, false)) { //Stopwatch is used to calculate load times in a debug build. #if DEBUG Stopwatch sw = new Stopwatch(); sw.Start(); Logger.Log($"Reading Vorbis file..."); #endif //We need to know whether this is a Mono or Stereo audio file. MonoGame only supports 1-channel or 2-channel audio data, so if it's anything else, throw an error. AudioChannels channels; switch (stream.Channels) { case 1: channels = AudioChannels.Mono; break; case 2: channels = AudioChannels.Stereo; break; default: throw new InvalidDataException($"Unsupported channel count {stream.Channels} (must be mono or stereo)."); } //This is our sample buffer. We don't wanna read the entire file all at once, that's a RAM killer. So we'll read chunks into a buffer this size. var samps = new float[stream.Channels * stream.SampleRate / 5]; #if DEBUG Logger.Log($"TotalSamples = {stream.TotalSamples}"); #endif //This is where we'll write the raw PCM data for MonoGame. using (var ms = new MemoryStream()) { //This is how we'll write the raw PCM data for MonoGame. using (var write = new BinaryWriter(ms)) { //Keep reading the Vorbis file until we've got nothing left to read. while (stream.DecodedPosition < stream.TotalSamples - 1) { //Read data from the Vorbis stream into our sample buffer. ReadSamples() returns how many samples were written to the buffer. //We'll use that to know how many samples to convert to PCM instead of blindly writing to the PCM stream causing audible hitches at the end of the sound effect due to duplicate sample data being written. int read = stream.ReadSamples(samps, 0, samps.Length); for (int i = 0; i < read; i++) { write.Write((short)(samps[i] * sc16)); // convert to S16 int PCM } } } //Deallocate the read buffer samps = null; //Force garbage collection GC.Collect(); #if DEBUG sw.Stop(); Logger.Log($"Done: {sw.Elapsed}"); #endif return(new SoundEffect(ms.ToArray(), stream.SampleRate, channels)); } } }
public static AudioClip ToAudioClip(string name) { var vorbis = new NVorbis.VorbisReader(GameAPI.instance.fileSystem.GetStreamFromPath(Path.Combine("sounds", name + ".ogg")), true); var channels = vorbis.Channels; var sampleRate = vorbis.SampleRate; var totalSamples = vorbis.TotalSamples; AudioClip clip = AudioClip.Create(name, (int)totalSamples, channels, sampleRate, false); var readBuffer = new float[channels * sampleRate / 5]; var totalBuffer = new float[channels * totalSamples]; int rd = 0; int prev = 0; while ((rd = vorbis.ReadSamples(readBuffer, 0, readBuffer.Length)) > 0) { Buffer.BlockCopy(readBuffer, 0, totalBuffer, prev * sizeof(float), rd * sizeof(float)); prev += rd; } clip.SetData(totalBuffer, 0); vorbis.Dispose(); return(clip); }
private unsafe OggVorbisData _readOggVorbis(Stream stream) { using (var vorbis = new NVorbis.VorbisReader(stream, false)) { var sampleRate = vorbis.SampleRate; var channels = vorbis.Channels; var totalSamples = vorbis.TotalSamples; var readSamples = 0; var buffer = new float[totalSamples * channels]; while (readSamples < totalSamples) { var read = vorbis.ReadSamples(buffer, readSamples * channels, (int)totalSamples - readSamples); if (read == 0) { break; } readSamples += read; } return(new OggVorbisData(totalSamples, sampleRate, channels, buffer)); } }
/// <summary> /// Reads a block of audio samples from the <see cref="VorbisReader.BaseStream"/> and writes the data to given array of samples. /// </summary> /// <param name="samples">Sample array to fill.</param> /// <param name="count">Maximum number of samples to read.</param> /// <returns>The number of samples actually read.</returns> /// <inheritdoc/> public override long Read(short[] samples, long count) { float[] buffer = new float[count]; int read = reader.ReadSamples(buffer, 0, (int)count); DecodeSamples(buffer, samples, read); return(read); }
/* * static void WavStreamFromOgz(string path, Stream wavStream) * { * Muddle.Decrypt(path, out Stream oggStream); * WavStreamFromOgg(oggStream, wavStream); * oggStream.Dispose(); * } */ static void WavStreamFromOgg(Stream oggStream, Stream wavStream) { // NVorbis is already included with MonoGame. Otherwise it'd have to be added as a NuGet package. //using (var vorbis = new NVorbis.VorbisReader(path)) using (var vorbis = new NVorbis.VorbisReader(oggStream, false)) //using (MemoryStream wavStream = new MemoryStream()) using (var writer = new BinaryWriter(wavStream, Encoding.UTF8, true)) { writer.Write(Encoding.ASCII.GetBytes("RIFF")); writer.Write(0); writer.Write(Encoding.ASCII.GetBytes("WAVE")); writer.Write(Encoding.ASCII.GetBytes("fmt ")); writer.Write(18); writer.Write((short)1); // PCM format writer.Write((short)vorbis.Channels); writer.Write(vorbis.SampleRate); writer.Write(vorbis.SampleRate * vorbis.Channels * 2); // avg bytes per second writer.Write((short)(2 * vorbis.Channels)); // block align writer.Write((short)16); // bits per sample writer.Write((short)0); // extra size writer.Write(Encoding.ASCII.GetBytes("data")); writer.Flush(); var dataPos = wavStream.Position; writer.Write(0); var buf = new float[vorbis.SampleRate / 10 * vorbis.Channels]; int count; while ((count = vorbis.ReadSamples(buf, 0, buf.Length)) > 0) { for (int i = 0; i < count; i++) { var temp = (int)(32767f * buf[i]); if (temp > 32767) { temp = 32767; } else if (temp < -32768) { temp = -32768; } writer.Write((short)temp); } } writer.Flush(); writer.Seek(4, SeekOrigin.Begin); writer.Write((int)(wavStream.Length - 8L)); writer.Seek((int)dataPos, SeekOrigin.Begin); writer.Write((int)(wavStream.Length - dataPos - 4L)); writer.Flush(); return; } }
public void ProduceFullAudioClipData(FullAudioClipData fullAudioClipData) { string ResourcesRootDirectory = BmsChartFolder; BmsAudioGenerator bmsAudioGenerator = new BmsAudioGenerator(44100, 2); int TotalCount = NativeBmsChart.Events.Count; int LoadedCount = 0; foreach (BMSEvent Event in NativeBmsChart.Events) { switch (Event.type) { case BMSEventType.LongNoteEnd: case BMSEventType.LongNoteStart: case BMSEventType.Note: case BMSEventType.WAV: BMSResourceData resourceData = new BMSResourceData(); if (!NativeBmsChart.TryGetResourceData(ResourceType.wav, Event.data2, out resourceData)) { continue; } string FileName = Path.GetFileNameWithoutExtension(resourceData.dataPath); string OggResourcePath = (ResourcesRootDirectory + "/" + FileName + ".ogg").Replace("\\", "/"); string WavResourcePath = (ResourcesRootDirectory + "/" + FileName + ".wav").Replace("\\", "/"); if (File.Exists(OggResourcePath)) { NVorbis.VorbisReader vorbisReader = new NVorbis.VorbisReader(OggResourcePath); float[] oggData = new float[vorbisReader.TotalSamples * vorbisReader.Channels]; vorbisReader.ReadSamples(oggData, 0, (int)(vorbisReader.TotalSamples * vorbisReader.Channels)); bmsAudioGenerator.PutAudioAt((float)Event.time.TotalSeconds, oggData); } else if (File.Exists(WavResourcePath)) { List <float> wavData = new List <float>(); NAudio.Wave.WaveFileReader waveFileReader = new NAudio.Wave.WaveFileReader(WavResourcePath); float[] wavFrame; while (true) { wavFrame = waveFileReader.ReadNextSampleFrame(); if (wavFrame == null) { break; } wavData.AddRange(wavFrame); } bmsAudioGenerator.PutAudioAt((float)Event.time.TotalSeconds, wavData.ToArray()); } break; } LoadedCount++; fullAudioClipData.Percent = 100f * LoadedCount / TotalCount; } fullAudioClipData.Data = bmsAudioGenerator.Data; fullAudioClipData.IsCompleted = true; }
static void TestRaw() { using (var vorbis = new NVorbis.VorbisReader(@"..\..\..\TestFiles\2test.ogg")) using (var outFile = System.IO.File.Create(@"..\..\..\TestFiles\2test.wav")) using (var writer = new System.IO.BinaryWriter(outFile)) { writer.Write(Encoding.ASCII.GetBytes("RIFF")); writer.Write(0); writer.Write(Encoding.ASCII.GetBytes("WAVE")); writer.Write(Encoding.ASCII.GetBytes("fmt ")); writer.Write(18); writer.Write((short)1); // PCM format writer.Write((short)vorbis.Channels); writer.Write(vorbis.SampleRate); writer.Write(vorbis.SampleRate * vorbis.Channels * 2); // avg bytes per second writer.Write((short)(2 * vorbis.Channels)); // block align writer.Write((short)16); // bits per sample writer.Write((short)0); // extra size writer.Write(Encoding.ASCII.GetBytes("data")); writer.Flush(); var dataPos = outFile.Position; writer.Write(0); var buf = new float[vorbis.SampleRate / 10 * vorbis.Channels]; int count; while ((count = vorbis.ReadSamples(buf, 0, buf.Length)) > 0) { for (int i = 0; i < count; i++) { var temp = (int)(32767f * buf[i]); if (temp > 32767) { temp = 32767; } else if (temp < -32768) { temp = -32768; } writer.Write((short)temp); } } writer.Flush(); writer.Seek(4, System.IO.SeekOrigin.Begin); writer.Write((int)(outFile.Length - 8L)); writer.Seek((int)dataPos, System.IO.SeekOrigin.Begin); writer.Write((int)(outFile.Length - dataPos - 4L)); writer.Flush(); } }
public static AudioFile Load(string filename) { using (var vorbis = new NVorbis.VorbisReader(filename)) { var channels = vorbis.Channels; var sampleRate = vorbis.SampleRate; var channelSize = sampleRate * vorbis.TotalTime.TotalSeconds; var bufferSize = (int)Math.Ceiling(channels * channelSize); var readBuffer = new float[bufferSize]; vorbis.ReadSamples(readBuffer, 0, bufferSize); return(new AudioFile { SampleRate = sampleRate, Stereo = channels == 2, Buffer = readBuffer }); } }
public int Read(float[] buffer, int offset, int count) { return(_reader.ReadSamples(buffer, offset, count)); // This is for "ConcatenateStreams" support (which we're not doing currently) //var readCount = _reader.ReadSamples(buffer, offset, count); //if (readCount < count) //{ // // we're almost certainly at the end of the stream... maybe try to read the next stream? // if (ConcatenateStreams) // { // if (_reader.SwitchStreams(_reader.StreamIndex)) // { // readCount += Read(buffer, offset + readCount, count - readCount); // } // } //} //return readCount; }
public static float[][] ReadAllSamples(Stream strm) { //lock (lockObject) { float[] buf; int ch; try { using (var vreader = new NVorbis.VorbisReader(strm, true)) { ch = vreader.Channels; buf = new float[vreader.TotalSamples * ch]; vreader.ReadSamples(buf, 0, (int)(vreader.TotalSamples * ch)); } // ↓謎の変換作業↓ float[][] buf2 = new float[ch][]; for (int i = 0; i < ch; i++) { buf2[i] = new float[buf.Length / ch]; } for (int i = 0; i < buf.Length; i++) { buf2[i % ch][i / ch] = buf[i]; } return(buf2); } catch { return(new float[][] { new float[] { 0 } }); // ひどすぎる } } }
/** * Reads an OGG audio clip and converts it to *.raw file * */ public static void ConvertOggToRAW(String srcoggfile, String dstrawfile) { srcoggfile = Path.GetFullPath(srcoggfile); dstrawfile = Path.GetFullPath(dstrawfile); Debug.Log("[CSLMusic] Convert " + srcoggfile + " to " + dstrawfile); try { using (var vorbis = new NVorbis.VorbisReader(srcoggfile)) { using (var fileStream = new FileStream(dstrawfile, FileMode.Create)) { //NVorbis data int channels = vorbis.Channels; int sampleRate = vorbis.SampleRate; var duration = vorbis.TotalTime; if (channels != 2 || sampleRate != 44100) { Debug.LogError("[CSLMusic] Error: Input file " + srcoggfile + " must have 2 channels and 44100Hz sample rate!"); //Add to list //ConversionManager.Info_NonConvertedFiles.Add(srcoggfile); return; } var buffer = new float[16384]; int count; //From SavWav Int16[] intData = new Int16[buffer.Length]; //converting in 2 float[] steps to Int16[], //then Int16[] to Byte[] Byte[] bytesData = new Byte[buffer.Length * 2]; //bytesData array is twice the size of //dataSource array because a float converted in Int16 is 2 bytes. int rescaleFactor = 32767; //to convert float to Int16 while ((count = vorbis.ReadSamples(buffer, 0, buffer.Length)) > 0) { // Do stuff with the samples returned... // Sample value range is -0.99999994f to 0.99999994f // Samples are interleaved (chan0, chan1, chan0, chan1, etc.) for (int i = 0; i < buffer.Length; i++) { intData[i] = (short)(buffer[i] * rescaleFactor); Byte[] byteArr = new Byte[2]; byteArr = BitConverter.GetBytes(intData[i]); byteArr.CopyTo(bytesData, i * 2); } fileStream.Write(bytesData, 0, bytesData.Length); } } } } catch (InvalidDataException ex) { Debug.LogError("... ERROR: Could not read file! " + ex.Message); //Add to list //CSLMusicModSettings.Info_NonConvertedFiles.Add(srcoggfile); return; } Debug.Log("... done."); }
public int Read(float[] buffer, int offset, int count) { return(_reader.ReadSamples(buffer, offset, count)); }
/** * Reads an OGG audio clip and converts it to *.raw file * */ public static void ConvertOggToRAW(String srcoggfile, String dstrawfile) { srcoggfile = Path.GetFullPath(srcoggfile); dstrawfile = Path.GetFullPath(dstrawfile); Debug.Log("[CSLMusic] Convert " + srcoggfile + " to " + dstrawfile); try { using (var vorbis = new NVorbis.VorbisReader(srcoggfile)) { using (var fileStream = new FileStream(dstrawfile, FileMode.Create)) { //NVorbis data int channels = vorbis.Channels; int sampleRate = vorbis.SampleRate; var duration = vorbis.TotalTime; if(channels != 2 || sampleRate != 44100) { Debug.LogError("[CSLMusic] Error: Input file " + srcoggfile + " must have 2 channels and 44100Hz sample rate!"); //Add to list //ConversionManager.Info_NonConvertedFiles.Add(srcoggfile); return; } var buffer = new float[16384]; int count; //From SavWav Int16[] intData = new Int16[buffer.Length]; //converting in 2 float[] steps to Int16[], //then Int16[] to Byte[] Byte[] bytesData = new Byte[buffer.Length * 2]; //bytesData array is twice the size of //dataSource array because a float converted in Int16 is 2 bytes. int rescaleFactor = 32767; //to convert float to Int16 while ((count = vorbis.ReadSamples(buffer, 0, buffer.Length)) > 0) { // Do stuff with the samples returned... // Sample value range is -0.99999994f to 0.99999994f // Samples are interleaved (chan0, chan1, chan0, chan1, etc.) for (int i = 0; i<buffer.Length; i++) { intData[i] = (short)(buffer[i] * rescaleFactor); Byte[] byteArr = new Byte[2]; byteArr = BitConverter.GetBytes(intData[i]); byteArr.CopyTo(bytesData, i * 2); } fileStream.Write(bytesData, 0, bytesData.Length); } } } } catch (InvalidDataException ex) { Debug.LogError("... ERROR: Could not read file! " + ex.Message); //Add to list //CSLMusicModSettings.Info_NonConvertedFiles.Add(srcoggfile); return; } Debug.Log("... done."); }
public bool Decode(Stream stream) { NVorbis.VorbisReader vorbis = new NVorbis.VorbisReader(stream, true); float[] buffer = new float[1024]; List<byte> result = new List<byte>(); int count; while ((count = vorbis.ReadSamples(buffer, 0, buffer.Length)) > 0) { for (int i = 0; i < count; i++) { short temp = (short)(32767f * buffer[i]); if (temp > 32767) { result.Add(0xFF); result.Add(0x7F); } else if (temp < -32768) { result.Add(0x80); result.Add(0x00); } result.Add((byte)temp); result.Add((byte)(temp >> 8)); } } this.Channels = (ushort)vorbis.Channels; this.SamplesPerSecond = (uint)vorbis.SampleRate; this.Data = result.ToArray(); return true; }