Example #1
0
        /// <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;
                }
            }
        }
Example #2
0
        /// <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);
                }
            }
        }