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 3bedda4ed7..bcd22162e8 100644 --- a/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp +++ b/src/add-ons/media/media-add-ons/mixer/AudioMixer.cpp @@ -16,6 +16,7 @@ #include "MixerCore.h" #include "MixerInput.h" #include "MixerOutput.h" +#include "MixerUtils.h" #include "debug.h" #define USE_MEDIA_FORMAT_WORKAROUND 1 @@ -334,6 +335,8 @@ AudioMixer::FormatChanged(const media_source &producer, const media_destination { // at some point in the future (indicated by change_tag and RequestCompleted()), // we will receive buffers in a different format + + printf("AudioMixer::FormatChanged\n"); if (consumer.port != ControlPort() || consumer.id == 0) return B_MEDIA_BAD_DESTINATION; @@ -400,7 +403,12 @@ AudioMixer::FormatChangeRequested(const media_source &source, const media_destin // another format, we need to check if the format is acceptable and // remove any wildcards before returning OK. + return B_ERROR; + fCore->Lock(); + + printf("AudioMixer::FormatChangeRequested\n"); + MixerOutput *output = fCore->Output(); if (!output) { ERROR("AudioMixer::FormatChangeRequested: no output\n"); @@ -411,8 +419,15 @@ AudioMixer::FormatChangeRequested(const media_source &source, const media_destin goto err; } if (destination != output->MediaOutput().destination) { - ERROR("AudioMixer::FormatChangeRequested: wrong output destination\n"); - goto err; + ERROR("AudioMixer::FormatChangeRequested: wrong output destination (port %ld, id %ld), our is (port %ld, id %ld)\n", destination.port, destination.id, output->MediaOutput().destination.port, output->MediaOutput().destination.id); + if (destination.port == output->MediaOutput().destination.port && destination.id == output->MediaOutput().destination.id + 1) { + ERROR("AudioMixer::FormatChangeRequested: this might be the broken R5 multi audio add-on\n"); + goto err; +// fCore->Unlock(); +// return B_OK; + } else { + goto err; + } } if (io_format->type != B_MEDIA_RAW_AUDIO && io_format->type != B_MEDIA_UNKNOWN_TYPE) { ERROR("AudioMixer::FormatChangeRequested: wrong format type\n"); @@ -426,11 +441,34 @@ AudioMixer::FormatChangeRequested(const media_source &source, const media_destin io_format->SpecializeTo(&fDefaultFormat); #endif - // apply format change - fCore->Lock(); - fCore->OutputFormatChanged(io_format->u.raw_audio); - fCore->Unlock(); + media_node_id id; + FindLatencyFor(destination, &fDownstreamLatency, &id); + printf("AudioMixer: Downstream Latency is %Ld usecs\n", fDownstreamLatency); + + // SetDuration of one buffer + SetBufferDuration(buffer_duration(io_format->u.raw_audio)); + printf("AudioMixer: buffer duration is %Ld usecs\n", BufferDuration()); + + // Our internal latency is at least the length of a full output buffer + fInternalLatency = bigtime_t(1.2 * BufferDuration()); + printf("AudioMixer: Internal latency is %Ld usecs\n", fInternalLatency); + SetEventLatency(fDownstreamLatency + fInternalLatency); + + //printf("AudioMixer: SendLatencyChange %Ld\n", EventLatency()); + //SendLatencyChange(source, destination, EventLatency()); + + delete fBufferGroup; + fBufferGroup = CreateBufferGroup(); + fCore->SetOutputBufferGroup(fBufferGroup); + + // apply latency change + fCore->SetTimingInfo(TimeSource(), fDownstreamLatency); + + // apply format change + fCore->OutputFormatChanged(io_format->u.raw_audio); + + fCore->Unlock(); return B_OK; err: @@ -473,6 +511,7 @@ AudioMixer::DisposeOutputCookie(int32 cookie) status_t AudioMixer::SetBufferGroup(const media_source &for_source, BBufferGroup *newGroup) { + printf("#############################AudioMixer::SetBufferGroup\n"); // the downstream consumer (soundcard) node asks us to use another // BBufferGroup (might be NULL). We only have one output (id 0) if (for_source.port != ControlPort() || for_source.id != 0) @@ -590,19 +629,18 @@ AudioMixer::Connect(status_t error, const media_source &source, const media_dest printf("AudioMixer: Downstream Latency is %Ld usecs\n", fDownstreamLatency); // SetDuration of one buffer - SetBufferDuration((1000000 * (format.u.raw_audio.buffer_size / ((format.u.raw_audio.format & media_raw_audio_format::B_AUDIO_SIZE_MASK) * format.u.raw_audio.channel_count))) / format.u.raw_audio.frame_rate); + SetBufferDuration(buffer_duration(format.u.raw_audio)); printf("AudioMixer: buffer duration is %Ld usecs\n", BufferDuration()); // Our internal latency is at least the length of a full output buffer - // XXX we use two for now - fInternalLatency = 2 * BufferDuration(); + fInternalLatency = bigtime_t(1.2 * BufferDuration()); printf("AudioMixer: Internal latency is %Ld usecs\n", fInternalLatency); SetEventLatency(fDownstreamLatency + fInternalLatency); - printf("AudioMixer: SendLatencyChange %Ld\n", EventLatency()); - SendLatencyChange(source, dest, EventLatency()); + //printf("AudioMixer: SendLatencyChange %Ld\n", EventLatency()); + //SendLatencyChange(source, dest, EventLatency()); // Set up the buffer group for our connection, as long as nobody handed us a // buffer group (via SetBufferGroup()) prior to this. That can happen, for example, @@ -625,7 +663,7 @@ AudioMixer::Connect(status_t error, const media_source &source, const media_dest fCore->Output()->MediaOutput().destination = dest; fCore->EnableOutput(true); - fCore->SetTimeSource(TimeSource()); + fCore->SetTimingInfo(TimeSource(), fDownstreamLatency); fCore->SetOutputBufferGroup(fBufferGroup); fCore->Unlock(); } @@ -709,8 +747,8 @@ void AudioMixer::NodeRegistered() { Run(); - SetPriority(8); // SetPriority(120); + SetPriority(12); } void @@ -718,7 +756,7 @@ AudioMixer::SetTimeSource(BTimeSource * time_source) { printf("AudioMixer::SetTimeSource: timesource is now %ld\n", time_source->ID()); fCore->Lock(); - fCore->SetTimeSource(time_source); + fCore->SetTimingInfo(time_source, fDownstreamLatency); fCore->Unlock(); } @@ -780,7 +818,7 @@ AudioMixer::CreateBufferGroup() int32 count = int32(fDownstreamLatency / BufferDuration()) + 2; fCore->Lock(); - uint32 size = fCore->OutputBufferSize(); + uint32 size = fCore->Output()->MediaOutput().format.u.raw_audio.buffer_size; fCore->Unlock(); printf("AudioMixer: allocating %ld buffers of %ld bytes each\n", count, size); 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 f7769b0a7e..a052b43013 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.cpp @@ -13,7 +13,7 @@ #include "Resampler.h" #include "Debug.h" -#define DOUBLE_RATE_MIXING 0 +#define DOUBLE_RATE_MIXING 1 #define ASSERT_LOCKED() if (fLocker->IsLocked()) {} else debugger("core not locked, meltdown occurred") @@ -43,7 +43,7 @@ MixerCore::MixerCore(AudioMixer *node) fMixBufferChannelTypes(0), fMixBufferChannelCount(0), fDoubleRateMixing(DOUBLE_RATE_MIXING), - fMixStartTime(0), + fDownstreamLatency(1), fNode(node), fBufferGroup(0), fTimeSource(0), @@ -80,7 +80,7 @@ bool MixerCore::AddInput(const media_input &input) { ASSERT_LOCKED(); - fInputs->AddItem(new MixerInput(this, input, fMixBufferFrameRate, fMixBufferFrameCount, fMixStartTime)); + fInputs->AddItem(new MixerInput(this, input, fMixBufferFrameRate, fMixBufferFrameCount)); return true; } @@ -92,7 +92,7 @@ MixerCore::AddOutput(const media_output &output) return false; fOutput = new MixerOutput(this, output); // the output format might have been adjusted inside MixerOutput - OutputFormatChanged(fOutput->MediaOutput().format.u.raw_audio); + ApplyOutputFormat(); } bool @@ -169,6 +169,25 @@ MixerCore::OutputFormatChanged(const media_multi_audio_format &format) { ASSERT_LOCKED(); + bool wasrunning = fRunning; + + if (wasrunning) + Stop(); + + fOutput->ChangeFormat(format); + ApplyOutputFormat(); + + if (wasrunning) + Start(0); +} + +void +MixerCore::ApplyOutputFormat() +{ + ASSERT_LOCKED(); + + media_multi_audio_format format = fOutput->MediaOutput().format.u.raw_audio; + if (fMixBuffer) rtm_free(fMixBuffer); @@ -209,7 +228,7 @@ MixerCore::OutputFormatChanged(const media_multi_audio_format &format) MixerInput *input; for (int i = 0; (input = Input(i)); i++) - input->SetMixBufferFormat(fMixBufferFrameRate, fMixBufferFrameCount, fMixStartTime); + input->SetMixBufferFormat(fMixBufferFrameRate, fMixBufferFrameCount); } void @@ -221,7 +240,7 @@ MixerCore::SetOutputBufferGroup(BBufferGroup *group) } void -MixerCore::SetTimeSource(BTimeSource *ts) +MixerCore::SetTimingInfo(BTimeSource *ts, bigtime_t downstream_latency) { ASSERT_LOCKED(); @@ -229,13 +248,9 @@ MixerCore::SetTimeSource(BTimeSource *ts) fTimeSource->Release(); fTimeSource = dynamic_cast(ts->Acquire()); -// fMixStartTime = fTimeSource->Now(); + fDownstreamLatency = downstream_latency; - printf("MixerCore::SetTimeSource, now = %Ld\n", fTimeSource->Now()); - -// MixerInput *input; -// for (int i = 0; (input = Input(i)); i++) -// input->SetMixBufferFormat(fMixBufferFrameRate, fMixBufferFrameCount, fMixStartTime); + printf("MixerCore::SetTimingInfo, now = %Ld, downstream latency %Ld\n", fTimeSource->Now(), fDownstreamLatency); } void @@ -279,15 +294,6 @@ MixerCore::Stop() fRunning = false; } -uint32 -MixerCore::OutputBufferSize() -{ - ASSERT_LOCKED(); - - uint32 size = sizeof(float) * fMixBufferFrameCount * fMixBufferChannelCount; - return fDoubleRateMixing ? (size / 2) : size; -} - bool MixerCore::IsStarted() { @@ -308,83 +314,96 @@ MixerCore::MixThread() bigtime_t event_time; bigtime_t time_base; bigtime_t latency; + bigtime_t start; int64 frame_base; int64 frame_pos; - latency = 30000; - - while (fTimeSource->Now() <= 0) { - printf("delay MixThread start, now %Ld\n", (int64)fTimeSource->Now()); + // The broken BeOS R5 multiaudio node starts with time 0, + // then publishes negative times for about 50ms, publishes 0 + // again until it finally reaches time values > 0 + start = fTimeSource->Now(); + while (start <= 0) { + printf("MixerCore: delaying MixThread start, timesource is at %Ld\n", start); snooze(1000); + start = fTimeSource->Now(); } + + latency = bigtime_t(0.2 * buffer_duration(fOutput->MediaOutput().format.u.raw_audio)); - printf("starting MixThread, now %Ld\n", (int64)fTimeSource->Now()); + printf("MixerCore: starting MixThread at %Ld with latency %Ld and downstream latency %Ld\n", start, latency, fDownstreamLatency); /* 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); + int64 temp = frames_for_duration(fMixBufferFrameRate, start ); frame_base = ((temp / fMixBufferFrameCount) + 1) * fMixBufferFrameCount; - time_base = duration_for_frames(fMixBufferFrameRate, frame_base) + fMixStartTime; + time_base = duration_for_frames(fMixBufferFrameRate, frame_base); - printf("starting MixThread, now %Ld, time_base %Ld, fMixStartTime %Ld, frame_base %Ld\n", fTimeSource->Now(), time_base, fMixStartTime, frame_base); + printf("starting MixThread, start %Ld, time_base %Ld, frame_base %Ld\n", start, time_base, 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)); + rv = acquire_sem_etc(fMixThreadWaitSem, 1, B_ABSOLUTE_TIMEOUT, fTimeSource->RealTimeFor(event_time, latency + fDownstreamLatency)); if (rv == B_INTERRUPTED) continue; if (rv != B_TIMED_OUT && rv < B_OK) return; + if (!LockWithTimeout(10000)) + continue; + // 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); -/* - for (int i = 0; i < fMixBufferChannelCount; i++) { - for (int j = 0; j < fMixBufferFrameCount; j++) { - fMixBuffer[(i * fMixBufferChannelCount)+j] = (i*j) / (float)(fMixBufferChannelCount * fMixBufferFrameCount); - } - } -*/ - // XXX this is a test, copy the the left channel from input 1 or 0 - Lock(); + + // XXX this is a test, copy the the left and right channel from input 1 or 0 + + if (fMixBufferChannelCount > 2) + memset(fMixBuffer, 0, fMixBufferChannelCount * fMixBufferFrameCount * sizeof(float)); MixerInput *input = Input(1); if (!input) input = Input(0); - if (input) { - const float *buffer; - uint32 src_sample_offset; - int type; - float gain; - - printf("data reading for %15Ld to %15Ld, ", event_time, event_time + duration_for_frames(fMixBufferFrameRate, fMixBufferFrameCount)); - - int64 cur_framepos = frame_base + frame_pos; - input->GetMixerChannelInfo(0, cur_framepos, &buffer, &src_sample_offset, &type, &gain); - + if (fMixBufferChannelCount > 2 || !input) memset(fMixBuffer, 0, fMixBufferChannelCount * fMixBufferFrameCount * sizeof(float)); - uint32 dst_sample_offset; + if (input) { + + printf("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; - char *src = (char *)buffer; - char *dst = (char *)fMixBuffer; - dst_sample_offset = fMixBufferChannelCount * sizeof(float); + for (int chan = 0; chan < 2; chan++) { + + const float *buffer; + uint32 src_sample_offset; + uint32 dst_sample_offset; + int type; + float gain; - for (int i = 0; i < fMixBufferFrameCount; i++) { - *(float *)dst = *(float *)src; - dst += dst_sample_offset; - src += src_sample_offset; + input->GetMixerChannelInfo(chan, cur_framepos, &buffer, &src_sample_offset, &type, &gain); + dst_sample_offset = fMixBufferChannelCount * sizeof(float); + + char *src = (char *)buffer; + char *dst = (char *)fMixBuffer; + + src += chan * sizeof(float); + dst += chan * sizeof(float); + + for (int i = 0; i < fMixBufferFrameCount; i++) { + *(float *)dst = *(float *)src; + dst += dst_sample_offset; + src += src_sample_offset; + } } } - Unlock(); - + // request a buffer - BBuffer* buf = fBufferGroup->RequestBuffer(fOutput->MediaOutput().format.u.raw_audio.buffer_size, 10000); + BBuffer* buf = fBufferGroup->RequestBuffer(fOutput->MediaOutput().format.u.raw_audio.buffer_size, 5000); + if (buf) { // copy data from mix buffer into output buffer @@ -397,6 +416,7 @@ MixerCore::MixThread() frames_per_buffer(fOutput->MediaOutput().format.u.raw_audio), 1.0); } +// printf("send buffer, inframes %ld, outframes %ld\n",fMixBufferFrameCount, frames_per_buffer(fOutput->MediaOutput().format.u.raw_audio)); // fill in the buffer header media_header* hdr = buf->Header(); @@ -407,13 +427,16 @@ MixerCore::MixThread() // send the buffer if (B_OK != fNode->SendBuffer(buf, fOutput->MediaOutput().destination)) { - printf("SendBuffer failed\n"); + printf("MixerCore: #### SendBuffer failed\n"); buf->Recycle(); } + } else { + printf("MixerCore: #### RequestBuffer failed\n"); } // schedule next event frame_pos += fMixBufferFrameCount; event_time = time_base + bigtime_t((1000000LL * frame_pos) / fMixBufferFrameRate); + Unlock(); } } 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 fa44aaa6b6..5f38ff4de5 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerCore.h +++ b/src/add-ons/media/media-add-ons/mixer/MixerCore.h @@ -26,6 +26,7 @@ public: MixerOutput *Output(); void Lock(); + bool LockWithTimeout(bigtime_t timeout); void Unlock(); void BufferReceived(BBuffer *buffer, bigtime_t lateness); @@ -34,17 +35,17 @@ public: void OutputFormatChanged(const media_multi_audio_format &format); void SetOutputBufferGroup(BBufferGroup *group); - void SetTimeSource(BTimeSource *ts); + void SetTimingInfo(BTimeSource *ts, bigtime_t downstream_latency); void EnableOutput(bool enabled); void Start(bigtime_t time); void Stop(); - uint32 OutputBufferSize(); bool IsStarted(); uint32 OutputChannelCount(); private: + void ApplyOutputFormat(); static int32 _mix_thread_(void *arg); void MixThread(); @@ -56,7 +57,7 @@ private: int32 fNextInputID; bool fRunning; - Resampler **fResampler; // array + Resampler **fResampler; // array float *fMixBuffer; int32 fMixBufferFrameRate; @@ -64,7 +65,9 @@ private: int32 fMixBufferChannelCount; int32 *fMixBufferChannelTypes; //array bool fDoubleRateMixing; - bigtime_t fMixStartTime; + bigtime_t fDownstreamLatency; + + friend class MixerInput; // XXX debug only AudioMixer *fNode; BBufferGroup *fBufferGroup; @@ -79,6 +82,11 @@ inline void MixerCore::Lock() fLocker->Lock(); } +inline bool MixerCore::LockWithTimeout(bigtime_t timeout) +{ + return B_OK == fLocker->LockWithTimeout(timeout); +} + inline void MixerCore::Unlock() { fLocker->Unlock(); 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 6892f1ed27..6a50513852 100644 --- a/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp +++ b/src/add-ons/media/media-add-ons/mixer/MixerInput.cpp @@ -2,6 +2,7 @@ #include #include #include +#include // XXX debug only #include "MixerInput.h" #include "MixerCore.h" #include "MixerUtils.h" @@ -11,7 +12,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 mixFrameRate, int32 mixFrameCount, bigtime_t mixStartTime) +MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrameRate, int32 mixFrameCount) : fCore(core), fInput(input), fInputByteSwap(0), @@ -23,7 +24,6 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrame fMixBuffer(0), fMixBufferFrameRate(0), fMixBufferFrameCount(0), - fMixBufferStartTime(0), fResampler(0), fUserOverridesChannelDesignations(false) { @@ -60,17 +60,19 @@ MixerInput::MixerInput(MixerCore *core, const media_input &input, float mixFrame // fMixerChannelInfo and fMixerChannelCount will be initialized by UpdateMixerChannels() - SetMixBufferFormat(mixFrameRate, mixFrameCount, mixStartTime); + SetMixBufferFormat(mixFrameRate, mixFrameCount); UpdateChannelDesignations(); UpdateMixerChannels(); // XXX a test: +/* SetMixerChannelGain(0, 0.222); SetMixerChannelGain(1, 0.444); AddInputChannelDesignation(0, B_CHANNEL_REARRIGHT); SetMixerChannelGain(2, 0.666); AddInputChannelDesignation(1, B_CHANNEL_REARLEFT); +*/ } MixerInput::~MixerInput() @@ -98,19 +100,29 @@ MixerInput::BufferReceived(BBuffer *buffer) data = buffer->Data(); size = buffer->SizeUsed(); start = buffer->Header()->start_time; + if (start < 0) { + printf("MixerInput::BufferReceived: buffer with negative start time of %Ld dropped\n", start); + return; + } // swap the byte order of this buffer, if necessary if (fInputByteSwap) fInputByteSwap->Swap(data, size); - int32 offset = frames_for_duration(fMixBufferFrameRate, start - fMixBufferStartTime) % fMixBufferFrameCount; + int32 offset = frames_for_duration(fMixBufferFrameRate, start) % fMixBufferFrameCount; + + // XXX test code! This will place the data earlier into the buffer then the supposed + // arrival time + // offset -= debugMixBufferFrames; + // if (offset < 0) + // offset += fMixBufferFrameCount; // printf("MixerInput::BufferReceived: mix buffer start %14Ld, buffer start %14Ld, offset %6d\n", fMixBufferStartTime, start, offset); - int in_frames = frames_per_buffer(fInput.format.u.raw_audio); // XXX use size + int in_frames = buffer->SizeUsed() / bytes_per_frame(fInput.format.u.raw_audio); int out_frames = (int)((in_frames * fMixBufferFrameRate) / fInput.format.u.raw_audio.frame_rate); // XXX losing fractions - //printf("data arrived for %15Ld to %15Ld, storing at frames %ld to %ld\n", start, start + duration_for_frames(fInput.format.u.raw_audio.frame_rate, frames_per_buffer(fInput.format.u.raw_audio)), offset, offset + out_frames); + //printf("data arrived for %10Ld to %10Ld, storing at frames %ld to %ld\n", start, start + duration_for_frames(fInput.format.u.raw_audio.frame_rate, frames_per_buffer(fInput.format.u.raw_audio)), offset, offset + out_frames); if (offset + out_frames > fMixBufferFrameCount) { @@ -119,16 +131,20 @@ MixerInput::BufferReceived(BBuffer *buffer) int in_frames1 = (out_frames1 * in_frames) / out_frames; int in_frames2 = in_frames - in_frames1; - printf("data arrived for %15Ld to %15Ld, storing at frames %ld to %ld and %ld to %ld\n", start, start + duration_for_frames(fInput.format.u.raw_audio.frame_rate, frames_per_buffer(fInput.format.u.raw_audio)), offset, offset + out_frames1, 0, out_frames2); + printf("at %10Ld, data arrived for %10Ld to %10Ld, storing at frames %ld to %ld and %ld to %ld\n", fCore->fTimeSource->Now(), start, start + duration_for_frames(fInput.format.u.raw_audio.frame_rate, frames_per_buffer(fInput.format.u.raw_audio)), offset, offset + out_frames1, 0, out_frames2); + + //printf(" in_frames %5d, out_frames %5d, in_frames1 %5d, out_frames1 %5d, in_frames2 %5d, out_frames2 %5d\n", + // in_frames, out_frames, in_frames1, out_frames1, in_frames2, out_frames2); + + offset *= sizeof(float) * fInputChannelCount; // convert offset from frames into bytes -// printf(" in_frames %5d, out_frames %5d, in_frames1 %5d, out_frames1 %5d, in_frames2 %5d, out_frames2 %5d\n", -// in_frames, out_frames, in_frames1, out_frames1, in_frames2, out_frames2); - for (int i = 0; i < fInputChannelCount; i++) { + + fResampler[i]->Resample(reinterpret_cast(data) + i * bytes_per_sample(fInput.format.u.raw_audio), bytes_per_frame(fInput.format.u.raw_audio), in_frames1, - reinterpret_cast(fInputChannelInfo[i].buffer_base) + (offset * sizeof(float) * fInputChannelCount), + reinterpret_cast(fInputChannelInfo[i].buffer_base) + offset, fInputChannelCount * sizeof(float), out_frames1, fInputChannelInfo[i].gain); @@ -143,14 +159,16 @@ MixerInput::BufferReceived(BBuffer *buffer) } } else { -// printf(" in_frames %5d, out_frames %5d\n", in_frames, out_frames); - printf("data arrived for %15Ld to %15Ld, storing at frames %ld to %ld\n", start, start + duration_for_frames(fInput.format.u.raw_audio.frame_rate, frames_per_buffer(fInput.format.u.raw_audio)), offset, offset + out_frames); + printf("at %10Ld, data arrived for %10Ld to %10Ld, storing at frames %ld to %ld\n", fCore->fTimeSource->Now(), start, start + duration_for_frames(fInput.format.u.raw_audio.frame_rate, frames_per_buffer(fInput.format.u.raw_audio)), offset, offset + out_frames); + //printf(" in_frames %5d, out_frames %5d\n", in_frames, out_frames); + + offset *= sizeof(float) * fInputChannelCount; // convert offset from frames into bytes for (int i = 0; i < fInputChannelCount; i++) { fResampler[i]->Resample(reinterpret_cast(data) + i * bytes_per_sample(fInput.format.u.raw_audio), bytes_per_frame(fInput.format.u.raw_audio), in_frames, - reinterpret_cast(fInputChannelInfo[i].buffer_base) + (offset * sizeof(float) * fInputChannelCount), + reinterpret_cast(fInputChannelInfo[i].buffer_base) + offset, fInputChannelCount * sizeof(float), out_frames, fInputChannelInfo[i].gain); @@ -374,7 +392,7 @@ MixerInput::GetMixerChannelInfo(int channel, int64 framepos, const float **buffe ASSERT(fMixBuffer); ASSERT(channel >= 0 && channel < fMixerChannelCount); int32 offset = framepos % fMixBufferFrameCount; - printf("GetMixerChannelInfo: frames %ld to %ld\n", offset, offset + debugMixBufferFrames); + if (channel == 0) printf("GetMixerChannelInfo: frames %ld to %ld\n", offset, offset + debugMixBufferFrames); *buffer = reinterpret_cast(reinterpret_cast(fMixerChannelInfo[channel].buffer_base) + (offset * sizeof(float) * fInputChannelCount)); *sample_offset = sizeof(float) * fInputChannelCount; *type = fMixerChannelInfo[channel].type; @@ -400,13 +418,12 @@ MixerInput::GetMixerChannelGain(int channel) } void -MixerInput::SetMixBufferFormat(int32 framerate, int32 frames, bigtime_t starttime) +MixerInput::SetMixBufferFormat(int32 framerate, int32 frames) { fMixBufferFrameRate = framerate; - fMixBufferStartTime = starttime; debugMixBufferFrames = frames; - printf("MixerInput::SetMixBufferFormat: framerate %ld, frames %ld, starttime %Ld\n", framerate, frames, starttime); + printf("MixerInput::SetMixBufferFormat: framerate %ld, frames %ld\n", framerate, frames); // make fMixBufferFrameCount an integral multiple of frames, // but at least 3 times duration of our input buffer @@ -422,6 +439,8 @@ MixerInput::SetMixBufferFormat(int32 framerate, int32 frames, bigtime_t starttim printf(" mixerBufferLength %10Ld\n", mixerBufferLength); printf(" fMixBufferFrameCount %10ld\n", fMixBufferFrameCount); + ASSERT((fMixBufferFrameCount % frames) == 0); + if (fMixBuffer) rtm_free(fMixBuffer); int size = sizeof(float) * fInputChannelCount * fMixBufferFrameCount; 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 66fe7502f1..bcc5302d3c 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 mixFrameRate, int32 mixFrameCount, bigtime_t mixStartTime); + MixerInput(MixerCore *core, const media_input &input, float mixFrameRate, int32 mixFrameCount); ~MixerInput(); int32 ID(); @@ -31,7 +31,7 @@ public: protected: friend class MixerCore; - void SetMixBufferFormat(int32 framerate, int32 frames, bigtime_t starttime); + void SetMixBufferFormat(int32 framerate, int32 frames); private: void UpdateChannelDesignations(); @@ -65,7 +65,6 @@ private: float fMixBufferFrameRate; uint32 fMixBufferFrameCount; - bigtime_t fMixBufferStartTime; Resampler **fResampler; // array