예제 #1
0
        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
                );
        }
예제 #2
0
        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;
        }
예제 #3
0
        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));
        }
예제 #4
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
                );
        }
예제 #5
0
        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
                );
        }