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
This commit is contained in:
beveloper
2003-06-25 00:19:49 +00:00
parent 320b131c05
commit b9bc85776c
2 changed files with 63 additions and 42 deletions
@@ -40,7 +40,9 @@ MixerCore::MixerCore()
fDoubleRateMixing(DOUBLE_RATE_MIXING), fDoubleRateMixing(DOUBLE_RATE_MIXING),
fLastMixStartTime(0), fLastMixStartTime(0),
fBufferGroup(0), fBufferGroup(0),
fTimeSource(0) fTimeSource(0),
fMixThread(-1),
fMixThreadWaitSem(-1)
{ {
} }
@@ -49,6 +51,9 @@ MixerCore::~MixerCore()
delete fLocker; delete fLocker;
delete fInputs; delete fInputs;
ASSERT(fMixThreadWaitSem == -1);
ASSERT(fMixThread == -1);
if (fMixBuffer) if (fMixBuffer)
rtm_free(fMixBuffer); rtm_free(fMixBuffer);
@@ -221,6 +226,9 @@ MixerCore::Start(bigtime_t time)
return; return;
fRunning = true; fRunning = true;
fMixThreadWaitSem = create_sem(0, "mix thread wait");
fMixThread = spawn_thread(_mix_thread_, "Yeah baby, very shagadelic", 12, this);
resume_thread(fMixThread);
} }
void void
@@ -230,6 +238,15 @@ MixerCore::Stop()
if (!fRunning) if (!fRunning)
return; return;
ASSERT(fMixThread > 0);
ASSERT(fMixThreadWaitSem > 0);
status_t unused;
delete_sem(fMixThreadWaitSem);
wait_for_thread(fMixThread, &unused);
fMixThread = -1;
fMixThreadWaitSem = -1;
fRunning = false; fRunning = false;
} }
@@ -249,44 +266,50 @@ MixerCore::IsStarted()
return fRunning; 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 int32
AudioMixer::_mix_thread_(void *data) MixerCore::_mix_thread_(void *arg)
{ {
return ((AudioMixer *)data)->MixThread(); static_cast<MixerCore *>(arg)->MixThread();
return 0;
} }
int32 void
AudioMixer::MixThread() MixerCore::MixThread()
{ {
while (1) bigtime_t event_time;
{ bigtime_t base;
snooze(500000); 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);
} }
} }
*/
@@ -43,15 +43,11 @@ public:
uint32 OutputChannelCount(); uint32 OutputChannelCount();
private: private:
// handle mixing in separate thread static int32 _mix_thread_(void *arg);
// not implemented (yet) void MixThread();
static int32 _mix_thread_(void *data);
int32 MixThread();
private: private:
BLocker *fLocker; BLocker *fLocker;
BList *fInputs; BList *fInputs;
MixerOutput *fOutput; MixerOutput *fOutput;
@@ -68,6 +64,8 @@ private:
BBufferGroup *fBufferGroup; BBufferGroup *fBufferGroup;
BTimeSource *fTimeSource; BTimeSource *fTimeSource;
thread_id fMixThread;
sem_id fMixThreadWaitSem;
}; };