From b9bc85776c298ca9cfc114225ab0cf7c8cf5dfba Mon Sep 17 00:00:00 2001 From: beveloper Date: Wed, 25 Jun 2003 00:19:49 +0000 Subject: [PATCH] added mixing thread, as well as start and stop git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3660 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media/media-add-ons/mixer/MixerCore.cpp | 93 ++++++++++++------- .../media/media-add-ons/mixer/MixerCore.h | 12 +-- 2 files changed, 63 insertions(+), 42 deletions(-) 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 3d218dc4e0..271a70992c 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp @@ -40,7 +40,9 @@ MixerCore::MixerCore() fDoubleRateMixing(DOUBLE_RATE_MIXING), fLastMixStartTime(0), fBufferGroup(0), - fTimeSource(0) + fTimeSource(0), + fMixThread(-1), + fMixThreadWaitSem(-1) { } @@ -49,6 +51,9 @@ MixerCore::~MixerCore() delete fLocker; delete fInputs; + ASSERT(fMixThreadWaitSem == -1); + ASSERT(fMixThread == -1); + if (fMixBuffer) rtm_free(fMixBuffer); @@ -221,6 +226,9 @@ MixerCore::Start(bigtime_t time) return; fRunning = true; + fMixThreadWaitSem = create_sem(0, "mix thread wait"); + fMixThread = spawn_thread(_mix_thread_, "Yeah baby, very shagadelic", 12, this); + resume_thread(fMixThread); } void @@ -229,7 +237,16 @@ MixerCore::Stop() ASSERT_LOCKED(); if (!fRunning) return; + + ASSERT(fMixThread > 0); + ASSERT(fMixThreadWaitSem > 0); + + status_t unused; + delete_sem(fMixThreadWaitSem); + wait_for_thread(fMixThread, &unused); + fMixThread = -1; + fMixThreadWaitSem = -1; fRunning = false; } @@ -249,44 +266,50 @@ MixerCore::IsStarted() return fRunning; } - -/* - void BufferReceived(BBuffer *buffer, bigtime_t lateness); - - - if (buffer->SizeUsed() > (channel->fDataSize - total_offset)) - { - memcpy(channel->fData + total_offset, indata, channel->fDataSize - total_offset); - memcpy(channel->fData, indata + (channel->fDataSize - total_offset), buffer->SizeUsed() - (channel->fDataSize - total_offset)); - } - else - memcpy(channel->fData + total_offset, indata, buffer->SizeUsed()); - - if ((B_OFFLINE == RunMode()) && (B_DATA_AVAILABLE == channel->fProducerDataStatus)) - { - RequestAdditionalBuffer(channel->fInput.source, buffer); - } - - break; - } - - -// use this later for separate threads - int32 -AudioMixer::_mix_thread_(void *data) +MixerCore::_mix_thread_(void *arg) { - return ((AudioMixer *)data)->MixThread(); + static_cast(arg)->MixThread(); + return 0; } -int32 -AudioMixer::MixThread() +void +MixerCore::MixThread() { - while (1) - { - snooze(500000); - } + bigtime_t event_time; + bigtime_t base; + bigtime_t latency; + int64 pos; -} + pos = 0; + latency = 30000; + base = event_time = fTimeSource->Now(); + for (;;) { + status_t rv; + rv = acquire_sem_etc(fMixThreadWaitSem, 1, B_ABSOLUTE_TIMEOUT, fTimeSource->RealTimeFor(event_time, latency)); + if (rv == B_INTERRUPTED) + continue; + if (rv < B_OK) + return; + + // mix all data from all inputs into the mix buffer + + // request a buffer + BBuffer* buf = fBufferGroup->RequestBuffer(fOutput->MediaOutput().format.u.raw_audio.buffer_size, 10000); + + // copy data from mix buffer into output buffer -*/ + // fill in the buffer header + media_header* hdr = buf->Header(); + hdr->type = B_MEDIA_RAW_AUDIO; + hdr->size_used = fOutput->MediaOutput().format.u.raw_audio.buffer_size; + hdr->time_source = fTimeSource->ID(); + hdr->start_time = event_time; + + // send the buffer + + // shedule next event + pos += fMixBufferFrameCount; + event_time = base + bigtime_t((1000000LL * pos) / fMixBufferFrameRate); + } +} diff --git a/src/add-ons/media/media-add-ons/mixer/MixerCore.h b/src/add-ons/media/media-add-ons/mixer/MixerCore.h index 5f7fe57261..8d9a3629eb 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerCore.h +++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.h @@ -43,15 +43,11 @@ public: uint32 OutputChannelCount(); private: - // handle mixing in separate thread - // not implemented (yet) - - static int32 _mix_thread_(void *data); - int32 MixThread(); - + static int32 _mix_thread_(void *arg); + void MixThread(); private: - BLocker *fLocker; + BLocker *fLocker; BList *fInputs; MixerOutput *fOutput; @@ -68,6 +64,8 @@ private: BBufferGroup *fBufferGroup; BTimeSource *fTimeSource; + thread_id fMixThread; + sem_id fMixThreadWaitSem; };