コード例 #1
0
ファイル: Program.cs プロジェクト: withsalt/SoundIOSharpCore
        static void ReadCallback(SoundIOInStream instream, int frameCountMin, int frameCountMax)
        {
            SoundIORingBuffer   ringBuffer = ringBuffers[instream.UserData];
            SoundIOChannelAreas areas;
            SoundIoError        err;

            IntPtr writePtr  = ringBuffer.WritePointer;
            int    freeBytes = ringBuffer.FreeCount;
            int    freeCount = freeBytes / instream.BytesPerFrame;

            if (frameCountMin > freeCount)
            {
                throw new SoundIOException("Ring buffer overflow");
            }

            int writeFrames = Math.Min(freeCount, frameCountMax);
            int framesLeft  = writeFrames;

            while (true)
            {
                int frameCount = framesLeft;

                err = instream.BeginRead(out areas, ref frameCount);
                if (err != SoundIoError.None)
                {
                    throw new SoundIOException(string.Format("Begin read error: {0}.", err.GetErrorMessage()));
                }

                if (frameCount == 0)
                {
                    break;
                }

                if (areas == null)
                {
                    // Due to an overflow there is a hole. Fill the ring buffer with
                    // silence for the size of the hole.
                    int count = frameCount * instream.BytesPerFrame;
                    for (int i = 0; i < count; i++)
                    {
                        Marshal.WriteByte(writePtr + i, 0);
                    }
                }
                else
                {
                    int channelCount   = instream.Layout.ChannelCount;
                    int bytesPerSample = instream.BytesPerSample;
                    for (int frame = 0; frame < frameCount; frame++)
                    {
                        for (int ch = 0; ch < channelCount; ch++)
                        {
                            unsafe
                            {
                                Buffer.MemoryCopy((void *)areas[ch].Pointer, (void *)writePtr, bytesPerSample, bytesPerSample);
                            }
                            areas[ch].AdvancePointer();
                            writePtr += bytesPerSample;
                        }
                    }
                }

                err = instream.EndRead();
                if (err != SoundIoError.None)
                {
                    throw new SoundIOException(string.Format("End read error: {0}.", err.GetErrorMessage()));
                }

                framesLeft -= frameCount;
                if (framesLeft <= 0)
                {
                    break;
                }
            }

            int advanceBytes = writeFrames * instream.BytesPerFrame;

            ringBuffer.AdvanceWritePointer(advanceBytes);
        }
コード例 #2
0
        private unsafe void ReadCallback(int frameCountMin, int frameCountMax)
        {
            int         writeFrames = frameCountMax;
            int         framesLeft  = writeFrames;
            UnionBuffer unionBuffer = new UnionBuffer();

            for (; ;)
            {
                int frameCount = framesLeft;

                var areas = _instream.BeginRead(ref frameCount);

                if (frameCount == 0)
                {
                    break;
                }

                if (areas.IsEmpty)
                {
                    // Due to an overflow there is a hole. Fill the ring buffer with
                    // silence for the size of the hole.
                    Console.Error.WriteLine("Dropped {0} frames due to internal overflow", frameCount);
                }
                else
                {
                    for (int frame = 0; frame < frameCount; frame += 1)
                    {
                        int chCount  = _instream.Layout.ChannelCount;
                        int copySize = _instream.BytesPerSample;
                        unionBuffer.Bytes = new byte[copySize];

                        fixed(byte *buffer = unionBuffer.Bytes)
                        {
                            for (int ch = 0; ch < chCount; ch += 1)
                            {
                                var area = areas.GetArea(ch);
                                Buffer.MemoryCopy((void *)area.Pointer, buffer, copySize, copySize);
                                _ringBuffer.Enqueue(unionBuffer.Bytes, 0, copySize);
                                area.Pointer += area.Step;
                            }
                        }
                    }
                }

                _instream.EndRead();

                framesLeft -= frameCount;
                if (framesLeft <= 0)
                {
                    break;
                }
            }

            int length = (int)_ringBuffer.GetLength();

            if (length >= FlushCount)
            {
                if (_flushBuffer == null || _flushBuffer.Length != length)
                {
                    _flushBuffer = new byte[length];
                }

                _ringBuffer.Dequeue(_flushBuffer);
                Filled?.Invoke(this, new FillEventArgs(_flushBuffer, 0, length));
            }
        }
コード例 #3
0
ファイル: Program.cs プロジェクト: tlecomte/libsoundio-sharp
        static void read_callback(SoundIOInStream instream, int frame_count_min, int frame_count_max)
        {
            var write_ptr  = ring_buffer.WritePointer;
            int free_bytes = ring_buffer.FreeCount;
            int free_count = free_bytes / instream.BytesPerFrame;

            if (frame_count_min > free_count)
            {
                throw new InvalidOperationException("ring buffer overflow");                  // panic()
            }
            int write_frames = Math.Min(free_count, frame_count_max);
            int frames_left  = write_frames;

            for (; ;)
            {
                int frame_count = frames_left;

                var areas = instream.BeginRead(ref frame_count);

                if (frame_count == 0)
                {
                    break;
                }

                if (areas.IsEmpty)
                {
                    // Due to an overflow there is a hole. Fill the ring buffer with
                    // silence for the size of the hole.
                    for (int i = 0; i < frame_count * instream.BytesPerFrame; i++)
                    {
                        Marshal.WriteByte(write_ptr + i, 0);
                    }
                    Console.Error.WriteLine("Dropped {0} frames due to internal overflow", frame_count);
                }
                else
                {
                    for (int frame = 0; frame < frame_count; frame += 1)
                    {
                        int chCount  = instream.Layout.ChannelCount;
                        int copySize = instream.BytesPerSample;
                        unsafe {
                            for (int ch = 0; ch < chCount; ch += 1)
                            {
                                var area = areas.GetArea(ch);
                                Buffer.MemoryCopy((void *)area.Pointer, (void *)write_ptr, copySize, copySize);
                                area.Pointer += area.Step;
                                write_ptr    += copySize;
                            }
                        }
                    }
                }

                instream.EndRead();

                frames_left -= frame_count;
                if (frames_left <= 0)
                {
                    break;
                }
            }

            int advance_bytes = write_frames * instream.BytesPerFrame;

            ring_buffer.AdvanceWritePointer(advance_bytes);
        }