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; }
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)); }
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 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; }