/// <summary> /// Appends an audio buffer to the specified track /// </summary> /// <typeparam name="T">The sample type of the buffer</typeparam> /// <param name="trackId">The track to append the buffer to</param> /// <param name="bufferTag">The internal tag of the buffer</param> /// <param name="buffer">The buffer to append to the track</param> public void AppendBuffer <T>(int trackId, long bufferTag, T[] buffer) where T : struct { if (_tracks.TryGetValue(trackId, out OpenALAudioTrack track)) { lock (track) { int bufferId = track.AppendBuffer(bufferTag); // Do we need to downmix? if (track.HardwareChannels != track.VirtualChannels) { short[] downmixedBuffer; ReadOnlySpan <short> bufferPCM16 = MemoryMarshal.Cast <T, short>(buffer); if (track.VirtualChannels == 6) { downmixedBuffer = Downmixing.DownMixSurroundToStereo(bufferPCM16); if (track.HardwareChannels == 1) { downmixedBuffer = Downmixing.DownMixStereoToMono(downmixedBuffer); } } else if (track.VirtualChannels == 2) { downmixedBuffer = Downmixing.DownMixStereoToMono(bufferPCM16); } else { throw new NotImplementedException($"Downmixing from {track.VirtualChannels} to {track.HardwareChannels} not implemented!"); } AL.BufferData(bufferId, track.Format, downmixedBuffer, downmixedBuffer.Length * sizeof(ushort), track.SampleRate); } else { AL.BufferData(bufferId, track.Format, buffer, buffer.Length * sizeof(ushort), track.SampleRate); } AL.SourceQueueBuffer(track.SourceId, bufferId); StartPlaybackIfNeeded(track); track.PlayedSampleCount += (ulong)buffer.Length; } } }
/// <summary> /// Appends an audio buffer to the specified track /// </summary> /// <param name="trackId">The track to append the buffer to</param> /// <param name="bufferTag">The internal tag of the buffer</param> /// <param name="buffer">The buffer to append to the track</param> public void AppendBuffer(int trackId, long bufferTag, ReadOnlySpan <short> buffer) { if (_tracks.TryGetValue(trackId, out OpenALAudioTrack track)) { lock (track) { int bufferId = track.AppendBuffer(bufferTag); // Do we need to downmix? if (track.HardwareChannels != track.VirtualChannels) { short[] downmixedBuffer; if (track.VirtualChannels == 6) { downmixedBuffer = Downmixing.DownMixSurroundToStereo(buffer); if (track.HardwareChannels == 1) { downmixedBuffer = Downmixing.DownMixStereoToMono(downmixedBuffer); } } else if (track.VirtualChannels == 2) { downmixedBuffer = Downmixing.DownMixStereoToMono(buffer); } else { throw new NotImplementedException($"Downmixing from {track.VirtualChannels} to {track.HardwareChannels} not implemented!"); } AL.BufferData(bufferId, track.Format, downmixedBuffer, downmixedBuffer.Length * Marshal.SizeOf <ushort>(), track.SampleRate); } else { AL.BufferData(bufferId, track.Format, buffer.ToArray(), buffer.Length * Marshal.SizeOf <ushort>(), track.SampleRate); } AL.SourceQueueBuffer(track.SourceId, bufferId); StartPlaybackIfNeeded(track); } } }