private void process64() { byte[] outBuffer = null; MemoryStream PcmStream = null; int PcmBytes = 0; WaveFormat waveFormat; AudioBuffer[] theBuffers = null; int nextBuffer = 0; bool firstLoop = false; bool startedSourceVoice = false; while (true) { //This is the outer loop //which controls looping in //64-bit ogg decoding. lock (lockObject) preparing = true; outBuffer = new Byte[4096]; if (byteStream == null) { oggFile = new OggVorbisFileStream(fileNames[playPointer]); } else { oggStream = new OggVorbisEncodedStream(byteStream); } PcmBytes = -1; //AverageBytesPerSecond = 0; //BlockAlign = 0; PcmStream = new MemoryStream(); waveFormat = new WaveFormat(); theBuffers = new AudioBuffer[maxBuffers]; nextBuffer = 0; firstLoop = true; startedSourceVoice = false; // Decode the Ogg Vorbis data into its PCM data while (PcmBytes != 0) { // Get the next chunk of PCM data, pin these so the GC can't while (true) { PcmBytes = (oggStream == null) ? oggFile.Read(outBuffer, 0, outBuffer.Length) : oggStream.Read(outBuffer, 0, outBuffer.Length); if (PcmBytes == 0) //Reached the end { break; } PcmStream.Flush(); PcmStream.Position = 0; PcmStream.Write(outBuffer, 0, PcmBytes); PcmStream.Position = 0; if (theBuffers[nextBuffer] != null) { theBuffers[nextBuffer].Stream.Dispose(); theBuffers[nextBuffer] = null; } theBuffers[nextBuffer] = new AudioBuffer(SharpDX.DataStream.Create <byte>(PcmStream.ToArray(), true, true)); theBuffers[nextBuffer].AudioBytes = PcmBytes; theBuffers[nextBuffer].LoopCount = 0; if (firstLoop) { VorbisInfo info = (oggStream == null) ? oggFile.Info : oggStream.Info; //BlockAlign = info.Channels * (bitsPerSample / 8); //AverageBytesPerSecond = info.Rate * BlockAlign; //waveFormat.AverageBytesPerSecond = AverageBytesPerSecond; //waveFormat.BitsPerSample = (short)bitsPerSample; //waveFormat.BlockAlignment = (short)BlockAlign; //waveFormat.Channels = (short)info.Channels; //waveFormat.SamplesPerSecond = info.Rate; waveFormat = new WaveFormat(info.Rate, bitsPerSample, info.Channels); //waveFormat.Encoding= WaveFormatEncoding.Pcm; sourceVoice = new SourceVoice(device, waveFormat); sourceVoice.SetVolume(volume); } //if first time looping, create sourcevoice sourceVoice.SubmitSourceBuffer(theBuffers[nextBuffer], null); if (nextBuffer == theBuffers.Length - 1) { nextBuffer = 0; } else { nextBuffer++; } //If we're done filling the buffer for the first time if (!startedSourceVoice && sourceVoice.State.BuffersQueued == maxBuffers) { sourceVoice.Start(); startedSourceVoice = true; lock (lockObject) { playing = true; preparing = false; } //lock } firstLoop = false; if (startedSourceVoice) { while (sourceVoice.State.BuffersQueued > maxBuffers - 1) { if (stopNow) { break; } Thread.Sleep(5); } } //if started source voice if (stopNow) { break; } } //while if (stopNow) { break; } //We don't have any more data but file could still be playing the remaining data. if (PcmBytes == 0 /*&& !loop*/) { if (!stopNow) { while (sourceVoice.State.BuffersQueued > 0 && !stopNow) { Thread.Sleep(10); } } //if doesn't want to stop ogg break; //exit the loop since we ran out of data and don't want to loop back } //if we ran out of data } //while more data //Clean everything up for another loop. //Must do clean up here since in 64-bit implementation, //we need to recreate all the objects. if (sourceVoice != null) { sourceVoice.ExitLoop(); //stop looping if looping sourceVoice.Stop(); } sourceVoice.Dispose(); sourceVoice = null; if (oggFile != null) { oggFile.Close(); oggFile = null; } outBuffer = null; for (int i = 0; i < theBuffers.Length; i++) { if (theBuffers[i] != null) { theBuffers[i].Stream.Dispose(); theBuffers[i] = null; } } theBuffers = null; if (oggStream != null) { oggStream.Close(); oggStream = null; } PcmStream.Dispose(); PcmStream = null; //We must loop this way, //since unlike the 32-bit implementation, //64-bit does not support native seek. if (PcmBytes == 0 && loop) { if (!stopNow) { continue; } else { break; } } else { //if we're not looping break; } //if we ran out of data but want to loop back } //outer loop to control //loop of file on 64-bit implementation //Finally, notify calling thread //that we're done playing. if (stopEvent != null) { stopEvent(); } } //method
private void process() { lock (lockObject) preparing = true; byte[] outBuffer = new Byte[4096]; if (byteStream == null) { oggFile = new OggVorbisFileStream(fileNames[playPointer]); } else { oggStream = new OggVorbisEncodedStream(byteStream); } MemoryStream PcmStream = null; int PcmBytes = -1; PcmStream = new MemoryStream(); WaveFormat waveFormat = new WaveFormat(); AudioBuffer[] theBuffers = new AudioBuffer[maxBuffers]; int nextBuffer = 0; bool firstLoop = true; bool startedSourceVoice = false; // Decode the Ogg Vorbis data into its PCM data while (PcmBytes != 0) { // Get the next chunk of PCM data, pin these so the GC can't while (true) { PcmBytes = (oggStream == null) ? oggFile.Read(outBuffer, 0, outBuffer.Length) : oggStream.Read(outBuffer, 0, outBuffer.Length); if (PcmBytes == 0) //Reached the end { break; } PcmStream.Flush(); PcmStream.Position = 0; PcmStream.Write(outBuffer, 0, PcmBytes); PcmStream.Position = 0; if (theBuffers[nextBuffer] != null) { theBuffers[nextBuffer].Stream.Dispose(); theBuffers[nextBuffer] = null; } theBuffers[nextBuffer] = new AudioBuffer(SharpDX.DataStream.Create <byte>(PcmStream.ToArray(), true, false)); theBuffers[nextBuffer].AudioBytes = PcmBytes; theBuffers[nextBuffer].LoopCount = 0; if (firstLoop) { VorbisInfo info = (oggStream == null) ? oggFile.Info : oggStream.Info; //BlockAlign = info.Channels * (bitsPerSample / 8); //AverageBytesPerSecond = info.Rate * BlockAlign; //waveFormat.AverageBytesPerSecond = AverageBytesPerSecond; //waveFormat.BitsPerSample = (short)bitsPerSample; //waveFormat.BlockAlignment = (short)BlockAlign; //waveFormat.Channels = (short)info.Channels; //waveFormat.SamplesPerSecond = info.Rate; waveFormat = new WaveFormat(info.Rate, bitsPerSample, info.Channels); //waveFormat.Encoding= WaveFormatEncoding.Pcm; sourceVoice = new SourceVoice(device, waveFormat); sourceVoice.SetVolume(volume); } //if first time looping, create sourcevoice sourceVoice.SubmitSourceBuffer(theBuffers[nextBuffer], null); if (nextBuffer == theBuffers.Length - 1) { nextBuffer = 0; } else { nextBuffer++; } //If we're done filling the buffer for the first time if (!startedSourceVoice && sourceVoice.State.BuffersQueued == maxBuffers) { sourceVoice.Start(); startedSourceVoice = true; lock (lockObject) { playing = true; preparing = false; } //lock } firstLoop = false; if (startedSourceVoice) { while (sourceVoice.State.BuffersQueued > maxBuffers - 1) { if (stopNow) { break; } Thread.Sleep(5); } } //if started source voice if (stopNow) { break; } } //while if (stopNow) { break; } //We don't have any more data but file could still be playing the remaining data. if (PcmBytes == 0 /*&& !loop*/) { if (!stopNow) { while (sourceVoice.State.BuffersQueued > 0 && !stopNow) { Thread.Sleep(10); } } //if doesn't want to stop ogg if (!loop) { break; //exit the loop since we ran out of data and don't want to loop back } } //if we ran out of data if (PcmBytes == 0 && loop) { PcmBytes = -1; if (oggFile != null) { oggFile.Position = 0; } if (oggStream != null) { oggStream.Position = 0; } } //if we ran out of data but want to loop back } //while more data //Done playing, or file requested stop, //so clean up and tell calling thread that //buffer has stopped and cleaned up. //calling thread doesn't know buffer has stopped until we clean things up //so we don't lose memory //Clean up the resources if (sourceVoice != null) { sourceVoice.ExitLoop(); //stop looping if looping sourceVoice.Stop(); } sourceVoice.Dispose(); sourceVoice = null; if (oggFile != null) { oggFile.Close(); oggFile = null; } outBuffer = null; for (int i = 0; i < theBuffers.Length; i++) { if (theBuffers[i] != null) { theBuffers[i].Stream.Dispose(); theBuffers[i] = null; } } theBuffers = null; if (oggStream != null) { oggStream.Close(); oggStream = null; } PcmStream.Dispose(); PcmStream = null; if (stopEvent != null) { stopEvent(); } } //method