Пример #1
0
        internal void SetData(IntPtr data, AudioFormat fmt, uint hz, uint size)
        {
            AL10.alBufferData(_handle, (int)fmt, data, (int)size, (int)hz);
            ALUtils.CheckALError("unable to set audio buffer data");

            AL10.alGetBufferi(_handle, AL10.AL_BITS, out int bits);
            AL10.alGetBufferi(_handle, AL10.AL_CHANNELS, out int channels);
            AL10.alGetBufferi(_handle, AL10.AL_SIZE, out int unpackedSize);

            Format   = fmt;
            DataSize = (uint)unpackedSize;
            Duration = TimeSpan.FromSeconds((double)(unpackedSize / ((bits / 8) * channels)) / hz);
        }
Пример #2
0
        public TimeSpan GetDuration()
        {
            int sizeInBytes;
            int channels;
            int bits;
            int lengthInSamples;

            AL10.alGetBufferi(_handle, AL10.AL_SIZE, out sizeInBytes);
            AL10.alGetBufferi(_handle, AL10.AL_CHANNELS, out channels);
            AL10.alGetBufferi(_handle, AL10.AL_BITS, out bits);

            lengthInSamples = sizeInBytes * 8 / (channels * bits);

            int frequency;

            AL10.alGetBufferi(_handle, AL10.AL_FREQUENCY, out frequency);
            return(TimeSpan.FromSeconds(lengthInSamples / (float)frequency));
        }
Пример #3
0
        public void GetBufferData(
            IALSource source,
            IALBuffer[] buffer,
            IntPtr samples,
            int samplesLen,
            AudioChannels channels
            )
        {
            int copySize1 = samplesLen / (int)channels;
            int copySize2 = 0;

            // Where are we now?
            int offset;

            AL10.alGetSourcei(
                (source as OpenALSource).Handle,
                AL11.AL_SAMPLE_OFFSET,
                out offset
                );

            // Is that longer than what the active buffer has left...?
            uint buf = (buffer[0] as OpenALBuffer).Handle;
            int  len;

            AL10.alGetBufferi(
                buf,
                AL10.AL_SIZE,
                out len
                );
            len /= 2;             // FIXME: Assuming 16-bit!
            len /= (int)channels;
            if (offset > len)
            {
                copySize2 = copySize1;
                copySize1 = 0;
                offset   -= len;
            }
            else if (offset + copySize1 > len)
            {
                copySize2 = copySize1 - (len - offset);
                copySize1 = (len - offset);
            }

            // Copy!
            if (copySize1 > 0)
            {
                ALEXT.alGetBufferSamplesSOFT(
                    buf,
                    offset,
                    copySize1,
                    channels == AudioChannels.Stereo ?
                    ALEXT.AL_STEREO_SOFT :
                    ALEXT.AL_MONO_SOFT,
                    ALEXT.AL_FLOAT_SOFT,
                    samples
                    );
                offset = 0;
            }
            if (buffer.Length > 1 && copySize2 > 0)
            {
                ALEXT.alGetBufferSamplesSOFT(
                    (buffer[1] as OpenALBuffer).Handle,
                    0,
                    copySize2,
                    channels == AudioChannels.Stereo ?
                    ALEXT.AL_STEREO_SOFT :
                    ALEXT.AL_MONO_SOFT,
                    ALEXT.AL_FLOAT_SOFT,
                    samples + (copySize1 * (int)channels)
                    );
            }
        }
Пример #4
0
        public IALBuffer ConvertStereoToMono(IALBuffer buffer)
        {
            OpenALBuffer buf = buffer as OpenALBuffer;
            int          bufLen, bits;

            AL10.alGetBufferi(
                buf.Handle,
                AL10.AL_SIZE,
                out bufLen
                );
            AL10.alGetBufferi(
                buf.Handle,
                AL10.AL_BITS,
                out bits
                );
            bits /= 8;
#if VERBOSE_AL_DEBUGGING
            CheckALError();
#endif

            byte[]   data       = new byte[bufLen];
            GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
            IntPtr   dataPtr    = dataHandle.AddrOfPinnedObject();
            ALEXT.alGetBufferSamplesSOFT(
                buf.Handle,
                0,
                bufLen / bits / 2,
                ALEXT.AL_STEREO_SOFT,
                bits == 2 ? ALEXT.AL_SHORT_SOFT : ALEXT.AL_BYTE_SOFT,
                dataPtr
                );
#if VERBOSE_AL_DEBUGGING
            CheckALError();
#endif

            byte[]   monoData   = new byte[bufLen / 2];
            GCHandle monoHandle = GCHandle.Alloc(monoData, GCHandleType.Pinned);
            IntPtr   monoPtr    = monoHandle.AddrOfPinnedObject();
            unsafe
            {
                if (bits == 2)
                {
                    short *src = (short *)dataPtr;
                    short *dst = (short *)monoPtr;
                    for (int i = 0; i < monoData.Length / 2; i += 1)
                    {
                        dst[i] = (short)(((int)src[0] + (int)src[1]) / 2);
                        src   += 2;
                    }
                }
                else
                {
                    sbyte *src = (sbyte *)dataPtr;
                    sbyte *dst = (sbyte *)monoPtr;
                    for (int i = 0; i < monoData.Length; i += 1)
                    {
                        dst[i] = (sbyte)(((short)src[0] + (short)src[1]) / 2);
                        src   += 2;
                    }
                }
            }
            monoHandle.Free();
            dataHandle.Free();
            data = null;

            return(GenBuffer(
                       monoData,
                       (uint)buf.SampleRate,
                       1,
                       0,
                       0,
                       false,
                       (uint)bits - 1
                       ));
        }
Пример #5
0
        public IALBuffer GenBuffer(
            byte[] data,
            uint sampleRate,
            uint channels,
            uint loopStart,
            uint loopEnd,
            bool isADPCM,
            uint formatParameter
            )
        {
            uint result;

            // Generate the buffer now, in case we need to perform alBuffer ops.
            AL10.alGenBuffers(1, out result);
#if VERBOSE_AL_DEBUGGING
            CheckALError();
#endif

            int format;
            int length = data.Length;
            if (isADPCM)
            {
                format = (channels == 2) ?
                         ALEXT.AL_FORMAT_STEREO_MSADPCM_SOFT :
                         ALEXT.AL_FORMAT_MONO_MSADPCM_SOFT;
                AL10.alBufferi(
                    result,
                    ALEXT.AL_UNPACK_BLOCK_ALIGNMENT_SOFT,
                    (int)formatParameter
                    );
            }
            else
            {
                if (formatParameter == 1)
                {
                    format = (channels == 2) ?
                             AL10.AL_FORMAT_STEREO16:
                             AL10.AL_FORMAT_MONO16;

                    /* We have to perform extra data validation on
                     * PCM16 data, as the MS SoundEffect builder will
                     * leave extra bytes at the end which will confuse
                     * alBufferData and throw an AL_INVALID_VALUE.
                     * -flibit
                     */
                    length &= 0x7FFFFFFE;
                }
                else
                {
                    format = (channels == 2) ?
                             AL10.AL_FORMAT_STEREO8:
                             AL10.AL_FORMAT_MONO8;
                }
            }

            // Load it!
            AL10.alBufferData(
                result,
                format,
                data,
                length,
                (int)sampleRate
                );
#if VERBOSE_AL_DEBUGGING
            CheckALError();
#endif

            // Calculate the duration now, after we've unpacked the buffer
            int bufLen, bits;
            AL10.alGetBufferi(
                result,
                AL10.AL_SIZE,
                out bufLen
                );
            AL10.alGetBufferi(
                result,
                AL10.AL_BITS,
                out bits
                );
            if (bufLen == 0 || bits == 0)
            {
                throw new InvalidOperationException(
                          "OpenAL buffer allocation failed!"
                          );
            }
            TimeSpan resultDur = TimeSpan.FromSeconds(
                bufLen /
                (bits / 8) /
                channels /
                ((double)sampleRate)
                );

            // Set the loop points, if applicable
            if (loopStart > 0 || loopEnd > 0)
            {
                AL10.alBufferiv(
                    result,
                    ALEXT.AL_LOOP_POINTS_SOFT,
                    new int[]
                {
                    (int)loopStart,
                    (int)loopEnd
                }
                    );
            }
#if VERBOSE_AL_DEBUGGING
            CheckALError();
#endif

            // Finally.
            return(new OpenALBuffer(result, resultDur, (int)channels, (int)sampleRate));
        }
Пример #6
0
        private void INTERNAL_bufferData(
            byte[] data,
            uint sampleRate,
            uint channels,
            uint loopStart,
            uint loopEnd,
            bool isADPCM,
            uint formatParameter
            )
        {
            if (OpenALDevice.Instance == null)
            {
                throw new NoAudioHardwareException();
            }

            // Generate the buffer now, in case we need to perform alBuffer ops.
            AL10.alGenBuffers((IntPtr)1, out INTERNAL_buffer);

            int format;

            if (isADPCM)
            {
                format = (channels == 2) ?
                         ALEXT.AL_FORMAT_STEREO_MSADPCM_SOFT :
                         ALEXT.AL_FORMAT_MONO_MSADPCM_SOFT;
                AL10.alBufferi(
                    INTERNAL_buffer,
                    ALEXT.AL_UNPACK_BLOCK_ALIGNMENT_SOFT,
                    (int)formatParameter
                    );
            }
            else
            {
                if (formatParameter == 1)
                {
                    format = (channels == 2) ?
                             AL10.AL_FORMAT_STEREO16:
                             AL10.AL_FORMAT_MONO16;
                }
                else
                {
                    format = (channels == 2) ?
                             AL10.AL_FORMAT_STEREO8:
                             AL10.AL_FORMAT_MONO8;
                }
            }

            // Load it!
            AL10.alBufferData(
                INTERNAL_buffer,
                format,
                data,
                (IntPtr)data.Length,
                (IntPtr)sampleRate
                );

            // Calculate the duration now, after we've unpacked the buffer
            int bufLen, bits;

            AL10.alGetBufferi(
                INTERNAL_buffer,
                AL10.AL_SIZE,
                out bufLen
                );
            AL10.alGetBufferi(
                INTERNAL_buffer,
                AL10.AL_BITS,
                out bits
                );
            Duration = TimeSpan.FromSeconds(
                bufLen /
                (bits / 8) /
                channels /
                ((double)sampleRate)
                );

            // Set the loop points, if applicable
            if (loopStart > 0 || loopEnd > 0)
            {
                AL10.alBufferiv(
                    INTERNAL_buffer,
                    ALEXT.AL_LOOP_POINTS_SOFT,
                    new int[]
                {
                    (int)loopStart,
                    (int)loopEnd
                }
                    );
            }
        }
        public unsafe IALBuffer ConvertStereoToMono(IALBuffer buffer)
        {
            OpenALBuffer buf = buffer as OpenALBuffer;
            int          bufLen, bits;

            AL10.alGetBufferi(
                buf.Handle,
                AL10.AL_SIZE,
                out bufLen
                );
            AL10.alGetBufferi(
                buf.Handle,
                AL10.AL_BITS,
                out bits
                );
            bits /= 8;
#if VERBOSE_AL_DEBUGGING
            CheckALError();
#endif

            byte[] data     = new byte[bufLen];
            byte[] monoData = new byte[bufLen / 2];
            fixed(byte *dataPtr = &data[0])
            fixed(byte *monoPtr = &monoData[0])
            {
                ALEXT.alGetBufferSamplesSOFT(
                    buf.Handle,
                    0,
                    bufLen / bits / 2,
                    ALEXT.AL_STEREO_SOFT,
                    bits == 2 ? ALEXT.AL_SHORT_SOFT : ALEXT.AL_BYTE_SOFT,
                    (IntPtr)dataPtr
                    );
#if VERBOSE_AL_DEBUGGING
                CheckALError();
#endif

                if (bits == 2)
                {
                    short *src = (short *)dataPtr;
                    short *dst = (short *)monoPtr;
                    for (int i = 0; i < monoData.Length / 2; i += 1)
                    {
                        dst[i] = (short)(((int)src[0] + (int)src[1]) / 2);
                        src   += 2;
                    }
                }
                else
                {
                    sbyte *src = (sbyte *)dataPtr;
                    sbyte *dst = (sbyte *)monoPtr;
                    for (int i = 0; i < monoData.Length; i += 1)
                    {
                        dst[i] = (sbyte)(((short)src[0] + (short)src[1]) / 2);
                        src   += 2;
                    }
                }
            }

            return(GenBuffer(
                       monoData,
                       (uint)buf.SampleRate,
                       1,
                       0,
                       0,
                       false,
                       (uint)bits - 1
                       ));
        }
Пример #8
0
        public IALBuffer GenBuffer(
            byte[] data,
            uint sampleRate,
            uint channels,
            uint loopStart,
            uint loopEnd,
            bool isADPCM,
            uint formatParameter
            )
        {
            uint result;

            // Generate the buffer now, in case we need to perform alBuffer ops.
            AL10.alGenBuffers((IntPtr)1, out result);

            int format;

            if (isADPCM)
            {
                format = (channels == 2) ?
                         ALEXT.AL_FORMAT_STEREO_MSADPCM_SOFT :
                         ALEXT.AL_FORMAT_MONO_MSADPCM_SOFT;
                AL10.alBufferi(
                    result,
                    ALEXT.AL_UNPACK_BLOCK_ALIGNMENT_SOFT,
                    (int)formatParameter
                    );
            }
            else
            {
                if (formatParameter == 1)
                {
                    format = (channels == 2) ?
                             AL10.AL_FORMAT_STEREO16:
                             AL10.AL_FORMAT_MONO16;
                }
                else
                {
                    format = (channels == 2) ?
                             AL10.AL_FORMAT_STEREO8:
                             AL10.AL_FORMAT_MONO8;
                }
            }

            // Load it!
            AL10.alBufferData(
                result,
                format,
                data,
                (IntPtr)data.Length,
                (IntPtr)sampleRate
                );

            // Calculate the duration now, after we've unpacked the buffer
            int bufLen, bits;

            AL10.alGetBufferi(
                result,
                AL10.AL_SIZE,
                out bufLen
                );
            AL10.alGetBufferi(
                result,
                AL10.AL_BITS,
                out bits
                );
            TimeSpan resultDur = TimeSpan.FromSeconds(
                bufLen /
                (bits / 8) /
                channels /
                ((double)sampleRate)
                );

            // Set the loop points, if applicable
            if (loopStart > 0 || loopEnd > 0)
            {
                AL10.alBufferiv(
                    result,
                    ALEXT.AL_LOOP_POINTS_SOFT,
                    new int[]
                {
                    (int)loopStart,
                    (int)loopEnd
                }
                    );
            }

            // Finally.
            return(new OpenALBuffer(result, resultDur));
        }
Пример #9
0
        private void INTERNAL_bufferData(
            byte[] data,
            uint sampleRate,
            uint channels,
            uint loopStart,
            uint loopEnd,
            bool isADPCM,
            uint formatParameter
            )
        {
            if (OpenALDevice.Instance == null)
            {
                throw new NoAudioHardwareException();
            }

            // Generate the buffer now, in case we need to perform alBuffer ops.
            AL10.alGenBuffers((IntPtr)1, out INTERNAL_buffer);

            int format;

            if (isADPCM)
            {
                Platform.AssertSupported("ADPCM");

                format = (channels == 2) ?
                         ALEXT.AL_FORMAT_STEREO_MSADPCM_SOFT :
                         ALEXT.AL_FORMAT_MONO_MSADPCM_SOFT;
                AL10.alBufferi(
                    INTERNAL_buffer,
                    ALEXT.AL_UNPACK_BLOCK_ALIGNMENT_SOFT,
                    (int)formatParameter
                    );
            }
            else
            {
                if (formatParameter == 1)
                {
                    format = (channels == 2) ?
                             AL10.AL_FORMAT_STEREO16:
                             AL10.AL_FORMAT_MONO16;
                }
                else
                {
                    format = (channels == 2) ?
                             AL10.AL_FORMAT_STEREO8:
                             AL10.AL_FORMAT_MONO8;
                }
            }

            // Load it!
            AL10.alBufferData(
                INTERNAL_buffer,
                format,
                data,
                (IntPtr)data.Length,
                (IntPtr)sampleRate
                );

            // Calculate the duration now, after we've unpacked the buffer
            int bufLen, bits;

            AL10.alGetBufferi(
                INTERNAL_buffer,
                AL10.AL_SIZE,
                out bufLen
                );
            AL10.alGetBufferi(
                INTERNAL_buffer,
                AL10.AL_BITS,
                out bits
                );
            Duration = TimeSpan.FromSeconds(
                bufLen /
                (bits / 8) /
                channels /
                ((double)sampleRate)
                );

            // Compute the default loop end point (end of the buffer), because
            //  some content builders automatically set a loop endpoint here instead of at 0
            int defaultEndPoint = (bufLen / (bits / 8)) / (int)channels;

            var hasCustomStartPoint = (loopStart > 0);
            var hasCustomEndPoint   = (
                (loopEnd > loopStart) &&
                (loopEnd < defaultEndPoint)
                );

            if (hasCustomStartPoint || hasCustomEndPoint)
            {
                // Set the loop points, if applicable
                Platform.AssertSupported("CustomLoopPoints");

                AL10.alBufferiv(
                    INTERNAL_buffer,
                    ALEXT.AL_LOOP_POINTS_SOFT,
                    new int[]
                {
                    (int)loopStart,
                    (int)loopEnd
                }
                    );
            }
        }