internal void QueueBuffer(object sender, EventArgs args) { int bs; int cur = 0; int total = 0; do { cur = (int)Vorbisfile.ov_read( vorbisFile, bufferPtr + total, 4096, 0, 2, 1, out bs ); total += cur; } while (cur > 0 && total < (MAX_SAMPLES - 4096)); // If we're at the end of the file, stop! if (total == 0) { eof = true; soundStream.BufferNeeded -= QueueBuffer; return; } // Send the filled buffer to the stream. soundStream.SubmitBuffer( vorbisBuffer, 0, total ); }
internal Song(string fileName) { Vorbisfile.ov_fopen(fileName, out vorbisFile); Vorbisfile.vorbis_info fileInfo = Vorbisfile.ov_info( vorbisFile, 0 ); // TODO: ov_comment() -flibit Name = Path.GetFileNameWithoutExtension(fileName); TrackNumber = 0; Duration = TimeSpan.FromSeconds( Vorbisfile.ov_time_total(vorbisFile, 0) ); soundStream = new DynamicSoundEffectInstance( (int)fileInfo.rate, (AudioChannels)fileInfo.channels ); // FIXME: 60 is arbitrary for a 60Hz game -flibit chunkSize = (int)(fileInfo.rate * fileInfo.channels / 60); chunkStep = chunkSize / VisualizationData.Size; IsDisposed = false; }
internal Song(string fileName) { Vorbisfile.ov_fopen(fileName, out vorbisFile); Vorbisfile.vorbis_info fileInfo = Vorbisfile.ov_info( vorbisFile, 0 ); // Thanks sizeof(long) -flibit int fileRate = (int)(fileInfo.rate.ToInt64() & 0xFFFFFFFF); // TODO: ov_comment() -flibit Name = Path.GetFileNameWithoutExtension(fileName); TrackNumber = 0; Duration = TimeSpan.FromSeconds( Vorbisfile.ov_time_total(vorbisFile, 0) ); soundStream = new DynamicSoundEffectInstance( fileRate, (AudioChannels)fileInfo.channels ); // FIXME: I need this to bypass XNA's gain clamp... -flibit soundStream.INTERNAL_isXACTSource = true; // FIXME: 60 is arbitrary for a 60Hz game -flibit chunkSize = (int)(fileRate * fileInfo.channels / 60); chunkStep = chunkSize / VisualizationData.Size; IsDisposed = false; }
private void QueueBuffer(object source, EventArgs ea) { // The original method refers to Int64 Vorbisfile.ov_read(IntPtr, IntPtr, Int32, Int32, Int32, Int32, Int32 ByRef), // which has been changed in newer FNA releases. The last parameter is now out, not ref. int pos = 0; int read; do { int current_section; read = (int)Vorbisfile.ov_read(vorbisFile, bufferPtr + pos, 4096, 0, 2, 1, out current_section); pos += read; }while (read > 0 && pos < 187904); if (pos != 0) { soundEffect.SubmitBuffer(vorbisBuffer, 0, pos); return; } if (IsLooped) { Vorbisfile.ov_time_seek(vorbisFile, 0.0); QueueBuffer(source, ea); return; } hitEof = true; soundEffect.BufferNeeded -= OnBufferNeeded; }
public static unsafe SoundEffect Decode(byte *start, byte *end) { FakeFile file = new FakeFile { start = start, position = start, end = end }; int sampleCount = *(int *)file.position; // <- We encoded this, before the packets start, because Vorbis doesn't know [not sure if this is still true for Ogg, haven't checked -AR] file.position += 4; int loopStart = *(int *)file.position; file.position += 4; int loopLength = *(int *)file.position; file.position += 4; // TODO: Consider modifying vorbisfile binding so we can stackalloc `vf` IntPtr vf; Vorbisfile.ov_open_callbacks((IntPtr)(&file), out vf, IntPtr.Zero, IntPtr.Zero, staticCallbacks); Vorbisfile.vorbis_info info = Vorbisfile.ov_info(vf, 0); byte[] audioData = new byte[sampleCount * info.channels * 2]; // *2 for 16-bit audio (as required by XNA) fixed(byte *writeStart = audioData) { byte *writePosition = writeStart; byte *writeEnd = writePosition + audioData.Length; while (true) { int currentSection; int result = (int)Vorbisfile.ov_read(vf, (IntPtr)writePosition, (int)(writeEnd - writePosition), 0, 2, 1, out currentSection); if (result == 0) // End of file { break; } else if (result > 0) { writePosition += result; } if (writePosition >= writeEnd) { break; } } Debug.Assert(writePosition == writeEnd); // <- If this fires, something went terribly wrong. (TODO: Throw exception?) } Vorbisfile.ov_clear(ref vf); return(new SoundEffect(audioData, 0, audioData.Length, (int)info.rate, (AudioChannels)info.channels, loopStart, loopLength)); }
void Dispose(bool disposing) { if (disposing) { Stop(); soundStream.Dispose(); soundStream = null; Vorbisfile.ov_clear(ref vorbisFile); } IsDisposed = true; }
internal void Stop() { PlayCount = 0; #if !NO_STREAM_THREAD exitThread = true; if (songThread != null && Thread.CurrentThread != songThread) { songThread.Join(); } #endif soundStream.Stop(); soundStream.BufferNeeded -= QueueBuffer; Vorbisfile.ov_time_seek(vorbisFile, 0.0); }
internal void QueueBuffer(object sender, EventArgs args) { // Fill a List (ugh) with a series of ov_read blocks. List <byte> totalBuf = new List <byte>(); int bs; long len = 0; do { len = Vorbisfile.ov_read( ref vorbisFile, vorbisBuffer, vorbisBuffer.Length, 0, 2, 1, out bs ); if (len == vorbisBuffer.Length) { totalBuf.AddRange(vorbisBuffer); } else if (len > 0) { // UGH -flibit byte[] smallBuf = new byte[len]; Array.Copy(vorbisBuffer, smallBuf, len); totalBuf.AddRange(smallBuf); } } while (len > 0 && totalBuf.Count < 16384); // 8192 16-bit samples // If we're at the end of the file, stop! if (totalBuf.Count == 0) { soundStream.BufferNeeded -= QueueBuffer; OnFinishedPlaying(); return; } // Send the filled buffer to the stream. soundStream.SubmitBuffer( totalBuf.ToArray(), 0, totalBuf.Count ); }
private void Initialize() { // The original method refers to long vorbis_info.rate, which has been changed to IntPtr in newer FNA releases. Vorbisfile.vorbis_info vorbis_info = Vorbisfile.ov_info(vorbisFile, -1); soundEffect = new DynamicSoundEffectInstance((int)vorbis_info.rate, (vorbis_info.channels == 1) ? AudioChannels.Mono : AudioChannels.Stereo); Volume = 1f; ToPrecache.Enqueue(this); if (ThreadedPrecacher == null) { ThreadedPrecacher = new Thread(PrecacheStreams) { Priority = ThreadPriority.Lowest }; ThreadedPrecacher.Start(); } WakeUpPrecacher.Set(); }
internal void QueueBuffer(object sender, EventArgs args) { int bs; int cur = 0; int total = 0; do { cur = (int)Vorbisfile.ov_read( vorbisFile, bufferPtr + total, 4096, 0, 2, 1, out bs ); total += cur; } while (cur > 0 && total < (MAX_SAMPLES - 4096)); // If we're at the end of the file, stop! if (total == 0) { eof = true; if ((sender as DynamicSoundEffectInstance).PendingBufferCount == 0) { soundStream.BufferNeeded -= QueueBuffer; MediaPlayer.SongFinishedPlaying(); } return; } // Send the filled buffer to the stream. soundStream.SubmitBuffer( vorbisBuffer, 0, total ); }
internal Song(string fileName) { Vorbisfile.ov_fopen(fileName, out vorbisFile); Vorbisfile.vorbis_info fileInfo = Vorbisfile.ov_info( vorbisFile, 0 ); // TODO: ov_comment() -flibit Name = Path.GetFileNameWithoutExtension(fileName); TrackNumber = 0; Duration = TimeSpan.FromSeconds( Vorbisfile.ov_time_total(vorbisFile, 0) ); soundStream = new DynamicSoundEffectInstance( (int)fileInfo.rate, (AudioChannels)fileInfo.channels ); IsDisposed = false; }
internal void Stop() { PlayCount = 0; if (!DISABLE_THREADS) { exitThread = true; if (songThread != null && Thread.CurrentThread != songThread) { songThread.Join(); songThread = null; } } timer.Stop(); timer.Reset(); if (!IsDisposed) { soundStream.Stop(); soundStream.BufferNeeded -= QueueBuffer; Vorbisfile.ov_time_seek(vorbisFile, 0.0); } }