I fixed a timing bug. The mixer was accidentally sending itself

a notification about downstream latency change, when it really
should have send that to the connected inputs. This is now done
by the PublishEventLatencyChange() function.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4567 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2003-09-08 19:39:35 +00:00
parent d33e7c4428
commit dfbe8043fa
3 changed files with 60 additions and 29 deletions
@@ -22,7 +22,7 @@
#include "MixerUtils.h"
#include "debug.h"
#define VERSION_STRING "0.1 alpha 2"
#define VERSION_STRING "0.1 alpha 3"
#define BUILD_STRING __DATE__ " " __TIME__
// the range of the gain sliders (in dB)
@@ -313,7 +313,7 @@ AudioMixer::GetLatencyFor(const media_destination &for_whom,
*out_latency = EventLatency();
*out_timesource = TimeSource()->ID();
//printf("AudioMixer::GetLatencyFor %Ld, timesource is %ld\n", *out_latency, *out_timesource);
printf("AudioMixer::GetLatencyFor %Ld, timesource is %ld\n", *out_latency, *out_timesource);
return B_OK;
@@ -509,13 +509,15 @@ AudioMixer::FormatChangeRequested(const media_source &source, const media_destin
TRACE("AudioMixer: buffer duration is %Ld usecs\n", BufferDuration());
// Our internal latency is at least the length of a full output buffer
fInternalLatency = BufferDuration() + min(4500LL, bigtime_t(0.5 * BufferDuration()));
fInternalLatency = BufferDuration() + max(4500LL, bigtime_t(0.5 * BufferDuration()));
TRACE("AudioMixer: Internal latency is %Ld usecs\n", fInternalLatency);
SetEventLatency(fDownstreamLatency + fInternalLatency);
TRACE("AudioMixer: SendLatencyChange %Ld\n", EventLatency());
SendLatencyChange(source, destination, EventLatency());
// we need to inform all connected *inputs* about *our* change in latency
PublishEventLatencyChange();
// XXX we might need to create more buffers, to span a larger downstream latency
// apply latency change
fCore->SetTimingInfo(TimeSource(), fDownstreamLatency);
@@ -605,23 +607,31 @@ void
AudioMixer::LatencyChanged(const media_source & source, const media_destination & destination,
bigtime_t new_latency, uint32 flags)
{
TRACE("AudioMixer::LatencyChanged: downstream latency changed from %Ld to %Ld\n", fDownstreamLatency, new_latency);
if (source.port != ControlPort() || source.id != 0) {
ERROR("AudioMixer::LatencyChanged: received but has wrong source %ld/%ld\n", source.port, source.id);
return;
}
TRACE("AudioMixer::LatencyChanged: downstream latency from %ld/%ld to %ld/%ld changed from %Ld to %Ld\n",
source.port, source.id, destination.port, destination.id, fDownstreamLatency, new_latency);
#if DEBUG
{
media_node_id id;
bigtime_t l;
FindLatencyFor(destination, &l, &id);
TRACE("AudioMixer: Reported downstream Latency is %Ld usecs\n", l);
}
#endif
fDownstreamLatency = new_latency;
SetEventLatency(fDownstreamLatency + fInternalLatency);
// XXX we might need to create more buffers, to span a larger downstream latency
fCore->Lock();
fCore->SetTimingInfo(TimeSource(), fDownstreamLatency);
MixerInput *input;
for (int i = 0; (input = fCore->Input(i)) != 0; i++) {
TRACE("AudioMixer: SendLatencyChange from %ld/%ld to %ld/%ld event latency is now %Ld\n",
input->MediaInput().source.port, input->MediaInput().source.id,
input->MediaInput().destination.port, input->MediaInput().destination.id,
EventLatency());
SendLatencyChange(input->MediaInput().source, input->MediaInput().destination, EventLatency());
}
PublishEventLatencyChange();
fCore->Unlock();
}
@@ -772,13 +782,13 @@ AudioMixer::Connect(status_t error, const media_source &source, const media_dest
TRACE("AudioMixer: buffer duration is %Ld usecs\n", BufferDuration());
// Our internal latency is at least the length of a full output buffer
fInternalLatency = BufferDuration() + min(4500LL, bigtime_t(0.5 * BufferDuration()));
fInternalLatency = BufferDuration() + max(4500LL, bigtime_t(0.5 * BufferDuration()));
TRACE("AudioMixer: Internal latency is %Ld usecs\n", fInternalLatency);
SetEventLatency(fDownstreamLatency + fInternalLatency);
TRACE("AudioMixer: SendLatencyChange %Ld\n", EventLatency());
SendLatencyChange(source, dest, EventLatency());
// we need to inform all connected *inputs* about *our* change in latency
PublishEventLatencyChange();
// 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,
@@ -868,9 +878,8 @@ AudioMixer::LateNoticeReceived(const media_source &what, bigtime_t how_much, big
printf("AudioMixer: increasing internal latency to %Ld usec\n", fInternalLatency);
SetEventLatency(fDownstreamLatency + fInternalLatency);
// printf("AudioMixer: SendLatencyChange %Ld (2)\n", EventLatency());
// SendLatencyChange(source, dest, EventLatency());
PublishEventLatencyChange();
}
}
*/
@@ -962,6 +971,28 @@ AudioMixer::HandleEvent(const media_timed_event *event, bigtime_t lateness, bool
// AudioMixer methods
//
void
AudioMixer::PublishEventLatencyChange()
{
// our event (processing + downstream) latency has changed,
// and we need tell all inputs about this
TRACE("AudioMixer::PublishEventLatencyChange\n");
fCore->Lock();
MixerInput *input;
for (int i = 0; (input = fCore->Input(i)) != 0; i++) {
TRACE("AudioMixer::PublishEventLatencyChange: SendLatencyChange, connection %ld/%ld to %ld/%ld event latency is now %Ld\n",
input->MediaInput().source.port, input->MediaInput().source.id,
input->MediaInput().destination.port, input->MediaInput().destination.id,
EventLatency());
SendLatencyChange(input->MediaInput().source, input->MediaInput().destination, EventLatency());
}
fCore->Unlock();
}
BBufferGroup *
AudioMixer::CreateBufferGroup()
{
@@ -44,7 +44,7 @@ class AudioMixer :
void ApplySettings();
void PublishEventLatencyChange();
void UpdateParameterWeb();
void HandleInputBuffer(BBuffer *buffer, bigtime_t lateness);
@@ -418,12 +418,10 @@ MixerCore::MixThread()
if (!LockFromMixThread())
return;
latency = min(3600LL, bigtime_t(0.4 * buffer_duration(fOutput->MediaOutput().format.u.raw_audio)));
// XXX we might need to add scheduling latency
// latency += 0.4 * buffer_duration(fOutput->MediaOutput().format.u.raw_audio);
latency = max(3600LL, bigtime_t(0.4 * buffer_duration(fOutput->MediaOutput().format.u.raw_audio)));
// XXX when the format changes while running, everything is wrong!
buffer_request_timeout = (3 * buffer_duration(fOutput->MediaOutput().format.u.raw_audio)) / 4;
buffer_request_timeout = buffer_duration(fOutput->MediaOutput().format.u.raw_audio) / 2;
TRACE("MixerCore: starting MixThread at %Ld with latency %Ld and downstream latency %Ld, buffer_request_timeout %Ld\n", start, latency, fDownstreamLatency, buffer_request_timeout);
@@ -459,9 +457,11 @@ MixerCore::MixThread()
continue;
if (rv != B_TIMED_OUT && rv < B_OK)
return;
if (!LockWithTimeout(10000))
if (!LockWithTimeout(10000)) {
ERROR("MixerCore: LockWithTimeout failed\n");
continue;
}
// no inputs or output muted, skip further processing and just send an empty buffer
if (fInputs->IsEmpty() || fOutput->IsMuted()) {