From 60e2e68ce4ee2cd63621a47d1f174c9c5158dcd1 Mon Sep 17 00:00:00 2001 From: beveloper Date: Sun, 29 Jun 2003 23:08:00 +0000 Subject: [PATCH] finally it does mixing, but we should get rid of the CPU eating List template at this place, as it internally calls malloc, free, new and delete quite often git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3748 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media/media-add-ons/mixer/AudioMixer.cpp | 5 +- .../media/media-add-ons/mixer/MixerCore.cpp | 89 ++++++++++++++----- .../media/media-add-ons/mixer/MixerUtils.cpp | 12 +++ .../media/media-add-ons/mixer/MixerUtils.h | 2 + 4 files changed, 84 insertions(+), 24 deletions(-) diff --git a/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp b/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp index cb8b8b7031..3028d9eada 100644 --- a/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp +++ b/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp @@ -763,8 +763,11 @@ void AudioMixer::NodeRegistered() { Run(); -// SetPriority(120); +#if DEBUG > 1 SetPriority(12); +#else + SetPriority(120); +#endif } void diff --git a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp index 4cc565a5d0..e794a14370 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp @@ -12,6 +12,7 @@ #include "AudioMixer.h" #include "Resampler.h" #include "debug.h" +#include "TList.h" #define DOUBLE_RATE_MIXING 1 @@ -327,7 +328,11 @@ MixerCore::StartMixThread() ASSERT(fOutput); fRunning = true; fMixThreadWaitSem = create_sem(0, "mix thread wait"); +#if DEBUG > 1 fMixThread = spawn_thread(_mix_thread_, "Yeah baby, very shagadelic", 12, this); +#else + fMixThread = spawn_thread(_mix_thread_, "Yeah baby, very shagadelic", 120, this); +#endif resume_thread(fMixThread); } @@ -354,6 +359,12 @@ MixerCore::_mix_thread_(void *arg) return 0; } +struct chan_info { + const char *base; + uint32 sample_offset; + float gain; +}; + void MixerCore::MixThread() { @@ -419,32 +430,64 @@ MixerCore::MixThread() PRINT(4, "create new buffer event at %Ld, reading input frames at %Ld\n", event_time, frame_base + frame_pos); // XXX this is a test, copy the the left and right channel from input 1 or 0 + + #define MAX_TYPES 18 + + int64 cur_framepos = frame_base + frame_pos; + + List InputChanInfos[MAX_TYPES]; + List MixChanInfos[fOutput->GetOutputChannelCount()]; - MixerInput *input = Input(1); - if (!input) - input = Input(0); - - if (fMixBufferChannelCount > 2 || !input) - memset(fMixBuffer, 0, fMixBufferChannelCount * fMixBufferFrameCount * sizeof(float)); - - if (input) { - - PRINT(3, "at %10Ld, data reading for %10Ld to %10Ld, ", fTimeSource->Now(), event_time, event_time + duration_for_frames(fMixBufferFrameRate, fMixBufferFrameCount)); - - int64 cur_framepos = frame_base + frame_pos; - - for (int chan = 0; chan < 2; chan++) { - - const float *buffer; - uint32 src_sample_offset; - uint32 dst_sample_offset; + MixerInput *input; + for (int i = 0; (input = Input(i)) != 0; i++) { + int count = input->GetMixerChannelCount(); + for (int chan = 0; chan < count; chan++) { + chan_info info; + int type; + input->GetMixerChannelInfo(chan, cur_framepos, (const float **)&info.base, &info.sample_offset, &type, &info.gain); + if (type < 0 || type >= MAX_TYPES) + continue; + InputChanInfos[type].Insert(info); + } + } + + int count = fOutput->GetOutputChannelCount(); + for (int chan = 0; chan < count; chan++) { + int count2 = fOutput->GetOutputChannelSourceCount(chan); + for (int i = 0; i < count2; i++) { int type; float gain; - - input->GetMixerChannelInfo(chan, cur_framepos, &buffer, &src_sample_offset, &type, &gain); - dst_sample_offset = fMixBufferChannelCount * sizeof(float); - - CopySamples(&fMixBuffer[chan], dst_sample_offset, buffer, src_sample_offset, fMixBufferFrameCount); + fOutput->GetMixerChannelInfo(chan, i, &type, &gain); + if (type < 0 || type >= MAX_TYPES) + continue; + int count3 = InputChanInfos[type].CountItems(); + for (int j = 0; j < count3; j++) { + chan_info *info; + InputChanInfos[type].Get(j, &info); + chan_info newinfo = *info; + newinfo.gain *= gain; + MixChanInfos[chan].Insert(newinfo); + } + } + } + + uint32 dst_sample_offset = fMixBufferChannelCount * sizeof(float); + + count = fOutput->GetOutputChannelCount(); + for (int chan = 0; chan < count; chan++) { + PRINT(5, "MixThread: chan %d has %d sources\n", chan, MixChanInfos[chan].CountItems()); + ZeroFill(&fMixBuffer[chan], dst_sample_offset, fMixBufferFrameCount); + int count2 = MixChanInfos[chan].CountItems(); + for (int i = 0; i < count2; i++) { + chan_info *info; + MixChanInfos[chan].Get(i, &info); + char *dst = (char *)&fMixBuffer[chan]; + for (int j = 0; j < fMixBufferFrameCount; j++) { + *(float *)dst += *(const float *)info->base * info->gain; + dst += dst_sample_offset; + info->base += info->sample_offset; + } + PRINT(5, "MixThread: base %p, sample-offset %2d, gain %.3f\n", info->base, info->sample_offset, info->gain); } } diff --git a/src/add-ons/media/media-add-ons/mixer/MixerUtils.cpp b/src/add-ons/media/media-add-ons/mixer/MixerUtils.cpp index 07b8edf418..5841405321 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerUtils.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerUtils.cpp @@ -171,6 +171,18 @@ CopySamples(float *_dst, int32 _dst_sample_offset, } } +void +ZeroFill(float *_dst, int32 _dst_sample_offset, int32 _sample_count) +{ + register char * dst = (char *) _dst; + register int32 sample_count = _sample_count; + register int32 dst_sample_offset = _dst_sample_offset; + while (sample_count--) { + *(float *)dst = 0.0f; + dst += dst_sample_offset; + } +} + int64 frames_for_duration(double framerate, bigtime_t duration) { diff --git a/src/add-ons/media/media-add-ons/mixer/MixerUtils.h b/src/add-ons/media/media-add-ons/mixer/MixerUtils.h index 792f2437cf..bd5011adde 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerUtils.h +++ b/src/add-ons/media/media-add-ons/mixer/MixerUtils.h @@ -12,6 +12,8 @@ void CopySamples(float *_dst, int32 _dst_sample_offset, const float *_src, int32 _src_sample_offset, int32 _sample_count); +void ZeroFill(float *_dst, int32 _dst_sample_offset, int32 _sample_count); + bigtime_t buffer_duration(const media_multi_audio_format & format); int bytes_per_sample(const media_multi_audio_format & format);