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