Exemplo n.º 1
0
        public static void LoadData <T>(
            this INativeAudioBuffer buffer,
            int sampleRate,
            T[] data,
            int dataLength,
            AudioDataLayout dataLayout,
            AudioDataElementType dataElementType) where T : struct
        {
            if (dataLength < 0)
            {
                throw new ArgumentOutOfRangeException("dataLength", "Data length cannot be negative");
            }
            if (dataLength > data.Length)
            {
                throw new ArgumentOutOfRangeException("dataLength", "Data length cannot exceed the specified arrays length.");
            }

            int itemSize = Marshal.SizeOf(typeof(T));

            using (PinnedArrayHandle pinned = new PinnedArrayHandle(data))
            {
                buffer.LoadData(
                    sampleRate,
                    pinned.Address,
                    itemSize * dataLength,
                    dataLayout,
                    dataElementType);
            }
        }
Exemplo n.º 2
0
        void INativeAudioBuffer.LoadData(int sampleRate, IntPtr data, int size, AudioDataLayout dataLayout, AudioDataElementType dataElementType)
        {
            ALFormat format = ALFormat.Mono16;

            if (dataLayout == AudioDataLayout.Mono)
            {
                if (dataElementType == AudioDataElementType.Byte)
                {
                    format = ALFormat.Mono8;
                }
                else if (dataElementType == AudioDataElementType.Short)
                {
                    format = ALFormat.Mono16;
                }
            }
            else if (dataLayout == AudioDataLayout.LeftRight)
            {
                if (dataElementType == AudioDataElementType.Byte)
                {
                    format = ALFormat.Stereo8;
                }
                else if (dataElementType == AudioDataElementType.Short)
                {
                    format = ALFormat.Stereo16;
                }
            }

            AL.BufferData(
                this.handle,
                format,
                data,
                (int)size,
                sampleRate);
        }
Exemplo n.º 3
0
        void INativeAudioBuffer.LoadData <T>(int sampleRate, T[] data, int dataLength, AudioDataLayout dataLayout, AudioDataElementType dataElementType)
        {
            ALFormat format = ALFormat.Mono16;

            if (dataLayout == AudioDataLayout.Mono)
            {
                if (dataElementType == AudioDataElementType.Byte)
                {
                    format = ALFormat.Mono8;
                }
                else if (dataElementType == AudioDataElementType.Short)
                {
                    format = ALFormat.Mono16;
                }
            }
            else if (dataLayout == AudioDataLayout.LeftRight)
            {
                if (dataElementType == AudioDataElementType.Byte)
                {
                    format = ALFormat.Stereo8;
                }
                else if (dataElementType == AudioDataElementType.Short)
                {
                    format = ALFormat.Stereo16;
                }
            }

            int sizeOfElement = System.Runtime.InteropServices.Marshal.SizeOf(typeof(T));

            AL.BufferData(
                this.handle,
                format,
                data,
                dataLength * sizeOfElement,
                sampleRate);
        }
Exemplo n.º 4
0
 void INativeAudioBuffer.LoadData(int sampleRate, IntPtr data, int size, AudioDataLayout dataLayout, AudioDataElementType dataElementType)
 {
 }
Exemplo n.º 5
0
        unsafe void INativeAudioBuffer.LoadData <T>(int sampleRate, T[] data, int dataLength, AudioDataLayout dataLayout, AudioDataElementType dataElementType)
        {
            float pitch = (float)sampleRate / targetSampleRate;
            int   targetLengthPerChannel = (int)Math.Ceiling(dataLength / pitch);

            // ToDo: Resampler skips samples with too high input sample rate (and too low output sample rate),
            // but that almost never happens on Android anyway

            GCHandle gcHandle = GCHandle.Alloc(data, GCHandleType.Pinned);

            try {
                if (dataLayout == AudioDataLayout.Mono)
                {
                    // Duplicate mono input to stereo output
                    ResizeBuffer(targetLengthPerChannel * 2);

                    if (dataElementType == AudioDataElementType.Byte)
                    {
                        // Duplicate channel, resample and convert 8-bit samples to 16-bit samples
                        byte *ptr = (byte *)gcHandle.AddrOfPinnedObject();
                        for (int destIndex = 0; destIndex < targetLengthPerChannel; destIndex++)
                        {
                            float srcIndex = (float)destIndex / targetLengthPerChannel * dataLength;

                            short sample1 = (short)((ptr[(int)srcIndex] - 0x80) << 8);
                            short sample2 = (short)((ptr[Math.Min((int)srcIndex + 1, dataLength - 1)] - 0x80) << 8);
                            short sample  = (short)(sample1 + (sample2 - sample1) * (srcIndex % 1f));
                            InternalBuffer[Length++] = sample;
                            InternalBuffer[Length++] = sample;
                        }
                    }
                    else if (dataElementType == AudioDataElementType.Short)
                    {
                        // Duplicate channel and resample
                        short *ptr = (short *)gcHandle.AddrOfPinnedObject();
                        for (int destIndex = 0; destIndex < targetLengthPerChannel; destIndex++)
                        {
                            float srcIndex = (float)destIndex / targetLengthPerChannel * dataLength;

                            short sample1 = ptr[(int)srcIndex];
                            short sample2 = ptr[Math.Min((int)srcIndex + 1, dataLength - 1)];
                            short sample  = (short)(sample1 + (sample2 - sample1) * (srcIndex % 1f));
                            InternalBuffer[Length++] = sample;
                            InternalBuffer[Length++] = sample;
                        }
                    }
                }
                else if (dataLayout == AudioDataLayout.LeftRight)
                {
                    // Channels are already interleaved, "targetLengthPerChannel" will
                    // be divided by channel count later, it's target length right here
                    ResizeBuffer(targetLengthPerChannel);

                    if (dataElementType == AudioDataElementType.Byte)
                    {
                        byte *ptr = (byte *)gcHandle.AddrOfPinnedObject();
                        if (targetSampleRate == sampleRate)
                        {
                            // Resampling is not needed, convert 8-bit samples to 16-bit samples
                            for (int srcIndex = 0; srcIndex < dataLength; srcIndex++)
                            {
                                short sample = (short)((ptr[srcIndex] - 0x80) << 8);
                                InternalBuffer[Length++] = sample;
                            }
                        }
                        else
                        {
                            // Resample and convert samples to 16-bit samples
                            targetLengthPerChannel /= 2;
                            int dataLengthPerChannel = dataLength / 2;

                            for (int destIndex = 0; destIndex < targetLengthPerChannel; destIndex++)
                            {
                                float srcIndex = (float)destIndex / targetLengthPerChannel * dataLengthPerChannel;

                                short sample1 = (short)((ptr[(int)srcIndex] - 0x80) << 8);
                                short sample2 = (short)((ptr[Math.Min((int)srcIndex + 2, dataLength - 2)] - 0x80) << 8);
                                short sample  = (short)(sample1 + (sample2 - sample1) * (srcIndex % 1f));
                                InternalBuffer[Length++] = sample;

                                sample1 = (short)((ptr[(int)srcIndex + 1] - 0x80) << 8);
                                sample2 = (short)((ptr[Math.Min((int)srcIndex + 3, dataLength - 1)] - 0x80) << 8);
                                sample  = (short)(sample1 + (sample2 - sample1) * (srcIndex % 1f));
                                InternalBuffer[Length++] = sample;
                            }
                        }
                    }
                    else if (dataElementType == AudioDataElementType.Short)
                    {
                        short *ptr = (short *)gcHandle.AddrOfPinnedObject();
                        if (targetSampleRate == sampleRate)
                        {
                            // Resampling is not needed
                            for (int srcIndex = 0; srcIndex < dataLength; srcIndex++)
                            {
                                InternalBuffer[Length++] = ptr[srcIndex];
                            }
                        }
                        else
                        {
                            // Resample buffer to target sample rate
                            targetLengthPerChannel /= 2;
                            int dataLengthPerChannel = dataLength / 2;

                            for (int destIndex = 0; destIndex < targetLengthPerChannel; destIndex++)
                            {
                                float srcIndex = (float)destIndex / targetLengthPerChannel * dataLengthPerChannel;

                                short sample1 = ptr[(int)srcIndex];
                                short sample2 = ptr[Math.Min((int)srcIndex + 2, dataLength - 2)];
                                short sample  = (short)(sample1 + (sample2 - sample1) * (srcIndex % 1f));
                                InternalBuffer[Length++] = sample;

                                sample1 = ptr[(int)srcIndex + 1];
                                sample2 = ptr[Math.Min((int)srcIndex + 3, dataLength - 1)];
                                sample  = (short)(sample1 + (sample2 - sample1) * (srcIndex % 1f));
                                InternalBuffer[Length++] = sample;
                            }
                        }
                    }
                }
            } finally {
                gcHandle.Free();
            }
        }
Exemplo n.º 6
0
 void INativeAudioBuffer.LoadData <T>(int sampleRate, T[] data, int dataLength, AudioDataLayout dataLayout, AudioDataElementType dataElementType)
 {
 }
Exemplo n.º 7
0
        //private byte[] buffer;
        //private int sampleRate;
        //private AudioDataLayout layout;
        //private AudioDataElementType type;

        public static void Parse(byte[] audioData, out byte[] buffer, out int sampleRate, out AudioDataLayout layout, out AudioDataElementType type)
        {
            MemoryStream s = new MemoryStream(audioData, true);

            using (BinaryReader r = new BinaryReader(s, Encoding.ASCII, true)) {
                uint riff = r.ReadUInt32();
                if (riff != 0x46464952)
                {
                    throw new NotSupportedException();
                }
                uint riffChunkSize = r.ReadUInt32();

                uint wave = r.ReadUInt32();
                if (wave != 0x45564157)
                {
                    throw new NotSupportedException();
                }

                uint fmt = r.ReadUInt32();
                if (fmt != 0x20746d66)
                {
                    throw new NotSupportedException();
                }
                uint fmtChunkSize = r.ReadUInt32();

                ushort format = r.ReadUInt16();
                if (format != 0x1 /*CODEC_PCM*/)
                {
                    throw new NotSupportedException();
                }
                ushort channels = r.ReadUInt16();
                sampleRate = r.ReadInt32();
                uint byteRate = r.ReadUInt32();

                ushort blockAlign = r.ReadUInt16();
                ushort bits       = r.ReadUInt16();

                if (channels == 2)
                {
                    layout = AudioDataLayout.LeftRight;;
                }
                else if (channels == 1)
                {
                    layout = AudioDataLayout.Mono;
                }
                else
                {
                    throw new NotSupportedException("Unsupported channels " + channels);
                }

                if (bits == 8)
                {
                    type = AudioDataElementType.Byte;
                }
                else if (bits == 16)
                {
                    type = AudioDataElementType.Short;
                }
                else
                {
                    throw new NotSupportedException("Unsupported bits " + bits);
                }

                uint data = r.ReadUInt32();
                if (data != 0x61746164)
                {
                    throw new NotSupportedException();
                }
                int dataChunkSize = r.ReadInt32();

                buffer = r.ReadBytes(dataChunkSize);
            }
        }