From 16cecbde360eb5fc03598dc7d05fb2d9be9b6931 Mon Sep 17 00:00:00 2001 From: beveloper Date: Wed, 25 Jun 2003 16:21:41 +0000 Subject: [PATCH] some workarounds, fMixStartTime is now always 0, delay mix thread if timesource has negative time, calculate correct time and frame base for mix thread git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3663 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media/media-add-ons/mixer/AudioMixer.cpp | 14 +++- .../media/media-add-ons/mixer/AudioMixer.h | 2 + .../media/media-add-ons/mixer/MixerCore.cpp | 80 +++++++++++++------ .../media/media-add-ons/mixer/MixerCore.h | 6 +- .../media/media-add-ons/mixer/MixerInput.cpp | 4 +- .../media/media-add-ons/mixer/MixerInput.h | 2 +- 6 files changed, 78 insertions(+), 30 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 faccd5c30a..3bedda4ed7 100644 --- a/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp +++ b/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp @@ -31,7 +31,7 @@ AudioMixer::AudioMixer(BMediaAddOn *addOn) BControllable(), BMediaEventLooper(), fAddOn(addOn), - fCore(new MixerCore), + fCore(new MixerCore(this)), fWeb(0), fBufferGroup(0), fDownstreamLatency(1), @@ -57,6 +57,14 @@ AudioMixer::~AudioMixer() BMediaEventLooper::Quit(); SetParameterWeb(NULL); + // stop the mixer + fCore->Lock(); + fCore->Stop(); + fCore->Unlock(); + + // disconnect all nodes from the mixer + // XXX todo + delete fCore; delete fBufferGroup; @@ -715,7 +723,7 @@ AudioMixer::SetTimeSource(BTimeSource * time_source) } void -AudioMixer::HandleEvent( const media_timed_event *event, bigtime_t lateness, bool realTimeEvent) +AudioMixer::HandleEvent(const media_timed_event *event, bigtime_t lateness, bool realTimeEvent) { switch (event->type) { @@ -729,6 +737,7 @@ AudioMixer::HandleEvent( const media_timed_event *event, bigtime_t lateness, boo case BTimedEventQueue::B_START: { + printf("AudioMixer::HandleEvent: B_START\n"); if (RunState() != B_STARTED) { fCore->Lock(); fCore->Start(event->event_time); @@ -739,6 +748,7 @@ AudioMixer::HandleEvent( const media_timed_event *event, bigtime_t lateness, boo case BTimedEventQueue::B_STOP: { + printf("AudioMixer::HandleEvent: B_STOP\n"); // stopped - don't process any more buffers, flush all buffers from eventqueue EventQueue()->FlushEvents(0, BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HANDLE_BUFFER); fCore->Lock(); diff --git a/src/add-ons/media/media-add-ons/mixer/AudioMixer.h b/src/add-ons/media/media-add-ons/mixer/AudioMixer.h index c6609c5b3f..60fa5f9cb2 100644 --- a/src/add-ons/media/media-add-ons/mixer/AudioMixer.h +++ b/src/add-ons/media/media-add-ons/mixer/AudioMixer.h @@ -59,6 +59,8 @@ class AudioMixer : void NodeRegistered(); void Stop(bigtime_t performance_time, bool immediate); void SetTimeSource(BTimeSource * time_source); + + using BBufferProducer::SendBuffer; protected: 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 271a70992c..c4557f7b64 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -7,6 +8,7 @@ #include "MixerInput.h" #include "MixerOutput.h" #include "MixerUtils.h" +#include "AudioMixer.h" #include "Debug.h" #define DOUBLE_RATE_MIXING 1 @@ -26,7 +28,7 @@ */ -MixerCore::MixerCore() +MixerCore::MixerCore(AudioMixer *node) : fLocker(new BLocker), fInputs(new BList), fOutput(0), @@ -38,7 +40,8 @@ MixerCore::MixerCore() fMixBufferChannelTypes(0), fMixBufferChannelCount(0), fDoubleRateMixing(DOUBLE_RATE_MIXING), - fLastMixStartTime(0), + fMixStartTime(0), + fNode(node), fBufferGroup(0), fTimeSource(0), fMixThread(-1), @@ -67,7 +70,7 @@ bool MixerCore::AddInput(const media_input &input) { ASSERT_LOCKED(); - fInputs->AddItem(new MixerInput(this, input, fMixBufferFrameRate, fMixBufferFrameCount, fLastMixStartTime)); + fInputs->AddItem(new MixerInput(this, input, fMixBufferFrameRate, fMixBufferFrameCount, fMixStartTime)); return true; } @@ -184,7 +187,7 @@ MixerCore::OutputFormatChanged(const media_multi_audio_format &format) MixerInput *input; for (int i = 0; (input = Input(i)); i++) - input->SetMixBufferFormat(fMixBufferFrameRate, fMixBufferFrameCount, fLastMixStartTime); + input->SetMixBufferFormat(fMixBufferFrameRate, fMixBufferFrameCount, fMixStartTime); } void @@ -204,11 +207,13 @@ MixerCore::SetTimeSource(BTimeSource *ts) fTimeSource->Release(); fTimeSource = dynamic_cast(ts->Acquire()); - fLastMixStartTime = fTimeSource->Now(); +// fMixStartTime = fTimeSource->Now(); - MixerInput *input; - for (int i = 0; (input = Input(i)); i++) - input->SetMixBufferFormat(fMixBufferFrameRate, fMixBufferFrameCount, fLastMixStartTime); + printf("MixerCore::SetTimeSource, now = %Ld\n", fTimeSource->Now()); + +// MixerInput *input; +// for (int i = 0; (input = Input(i)); i++) +// input->SetMixBufferFormat(fMixBufferFrameRate, fMixBufferFrameCount, fMixStartTime); } void @@ -222,6 +227,7 @@ void MixerCore::Start(bigtime_t time) { ASSERT_LOCKED(); + printf("MixerCore::Start\n"); if (fRunning) return; @@ -235,6 +241,7 @@ void MixerCore::Stop() { ASSERT_LOCKED(); + printf("MixerCore::Stop\n"); if (!fRunning) return; @@ -277,39 +284,66 @@ void MixerCore::MixThread() { bigtime_t event_time; - bigtime_t base; + bigtime_t time_base; bigtime_t latency; - int64 pos; + int64 frame_base; + int64 frame_pos; - pos = 0; latency = 30000; - base = event_time = fTimeSource->Now(); + + while (fTimeSource->Now() <= 0) { + printf("delay MixThread start, now %Ld\n", (int64)fTimeSource->Now()); + snooze(1000); + } + + printf("starting MixThread, now %Ld\n", (int64)fTimeSource->Now()); + + /* We must read from the input buffer at a position (pos) that is always a multiple of fMixBufferFrameCount. + */ + int64 temp = frames_for_duration(fMixBufferFrameRate, fTimeSource->Now() - fMixStartTime); + frame_base = ((temp / fMixBufferFrameCount) + 1) * fMixBufferFrameCount; + time_base = duration_for_frames(fMixBufferFrameRate, frame_base) + fMixStartTime; + + printf("starting MixThread, now %Ld, time_base %Ld, fMixStartTime %Ld, frame_base %Ld\n", fTimeSource->Now(), time_base, fMixStartTime, frame_base); + + event_time = time_base; + frame_pos = 0; 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) + if (rv != B_TIMED_OUT && rv < B_OK) return; // mix all data from all inputs into the mix buffer + ASSERT((frame_base + frame_pos) % fMixBufferFrameCount == 0); + + printf("create new buffer event at %Ld, reading input frames at %Ld\n", event_time, frame_base + frame_pos); + // request a buffer BBuffer* buf = fBufferGroup->RequestBuffer(fOutput->MediaOutput().format.u.raw_audio.buffer_size, 10000); + if (buf) { - // copy data from mix buffer into output buffer + // 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; + // 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 + // send the buffer + if (B_OK != fNode->SendBuffer(buf, fOutput->MediaOutput().destination)) { + printf("SendBuffer failed\n"); + buf->Recycle(); + } + } // shedule next event - pos += fMixBufferFrameCount; - event_time = base + bigtime_t((1000000LL * pos) / fMixBufferFrameRate); + frame_pos += fMixBufferFrameCount; + event_time = time_base + bigtime_t((1000000LL * frame_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 8d9a3629eb..54aea1b483 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerCore.h +++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.h @@ -3,13 +3,14 @@ #include +class AudioMixer; class MixerInput; class MixerOutput; class MixerCore { public: - MixerCore(); + MixerCore(AudioMixer *node); ~MixerCore(); bool AddInput(const media_input &input); @@ -60,8 +61,9 @@ private: int32 fMixBufferChannelCount; int32 *fMixBufferChannelTypes; //array bool fDoubleRateMixing; - bigtime_t fLastMixStartTime; + bigtime_t fMixStartTime; + AudioMixer *fNode; BBufferGroup *fBufferGroup; BTimeSource *fTimeSource; thread_id fMixThread; diff --git a/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp b/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp index d80b8c5e14..7288cc0ed1 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp @@ -11,7 +11,7 @@ template const t & max(const t &t1, const t &t2) { return (t1 > t2) ? t1 : t2; } -MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixSampleRate, int32 mixFramesCount, bigtime_t mixStartTime) +MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrameRate, int32 mixFrameCount, bigtime_t mixStartTime) : fCore(core), fInput(input), fInputByteSwap(0), @@ -60,7 +60,7 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixSampl // fMixerChannelInfo and fMixerChannelCount will be initialized by UpdateMixerChannels() - SetMixBufferFormat(mixSampleRate, mixFramesCount, mixStartTime); + SetMixBufferFormat(mixFrameRate, mixFrameCount, mixStartTime); UpdateChannelDesignations(); UpdateMixerChannels(); diff --git a/src/add-ons/media/media-add-ons/mixer/MixerInput.h b/src/add-ons/media/media-add-ons/mixer/MixerInput.h index 2f61580603..d6965881e1 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerInput.h +++ b/src/add-ons/media/media-add-ons/mixer/MixerInput.h @@ -8,7 +8,7 @@ class Resampler; class MixerInput { public: - MixerInput(MixerCore *core, const media_input &input, float mixSampleRate, int32 mixFramesCount, bigtime_t mixStartTime); + MixerInput(MixerCore *core, const media_input &input, float mixFrameRate, int32 mixFrameCount, bigtime_t mixStartTime); ~MixerInput(); int32 ID();