finally it does mixing, but we should get rid of the CPU eating List template
at this place, as it internally calls malloc, free, new and delete quite often git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3748 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
806cf56077
commit
60e2e68ce4
@ -763,8 +763,11 @@ void
|
||||
AudioMixer::NodeRegistered()
|
||||
{
|
||||
Run();
|
||||
// SetPriority(120);
|
||||
#if DEBUG > 1
|
||||
SetPriority(12);
|
||||
#else
|
||||
SetPriority(120);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "AudioMixer.h"
|
||||
#include "Resampler.h"
|
||||
#include "debug.h"
|
||||
#include "TList.h"
|
||||
|
||||
#define DOUBLE_RATE_MIXING 1
|
||||
|
||||
@ -327,7 +328,11 @@ MixerCore::StartMixThread()
|
||||
ASSERT(fOutput);
|
||||
fRunning = true;
|
||||
fMixThreadWaitSem = create_sem(0, "mix thread wait");
|
||||
#if DEBUG > 1
|
||||
fMixThread = spawn_thread(_mix_thread_, "Yeah baby, very shagadelic", 12, this);
|
||||
#else
|
||||
fMixThread = spawn_thread(_mix_thread_, "Yeah baby, very shagadelic", 120, this);
|
||||
#endif
|
||||
resume_thread(fMixThread);
|
||||
}
|
||||
|
||||
@ -354,6 +359,12 @@ MixerCore::_mix_thread_(void *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct chan_info {
|
||||
const char *base;
|
||||
uint32 sample_offset;
|
||||
float gain;
|
||||
};
|
||||
|
||||
void
|
||||
MixerCore::MixThread()
|
||||
{
|
||||
@ -419,32 +430,64 @@ MixerCore::MixThread()
|
||||
PRINT(4, "create new buffer event at %Ld, reading input frames at %Ld\n", event_time, frame_base + frame_pos);
|
||||
|
||||
// XXX this is a test, copy the the left and right channel from input 1 or 0
|
||||
|
||||
#define MAX_TYPES 18
|
||||
|
||||
int64 cur_framepos = frame_base + frame_pos;
|
||||
|
||||
List<chan_info> InputChanInfos[MAX_TYPES];
|
||||
List<chan_info> MixChanInfos[fOutput->GetOutputChannelCount()];
|
||||
|
||||
MixerInput *input = Input(1);
|
||||
if (!input)
|
||||
input = Input(0);
|
||||
|
||||
if (fMixBufferChannelCount > 2 || !input)
|
||||
memset(fMixBuffer, 0, fMixBufferChannelCount * fMixBufferFrameCount * sizeof(float));
|
||||
|
||||
if (input) {
|
||||
|
||||
PRINT(3, "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;
|
||||
|
||||
for (int chan = 0; chan < 2; chan++) {
|
||||
|
||||
const float *buffer;
|
||||
uint32 src_sample_offset;
|
||||
uint32 dst_sample_offset;
|
||||
MixerInput *input;
|
||||
for (int i = 0; (input = Input(i)) != 0; i++) {
|
||||
int count = input->GetMixerChannelCount();
|
||||
for (int chan = 0; chan < count; chan++) {
|
||||
chan_info info;
|
||||
int type;
|
||||
input->GetMixerChannelInfo(chan, cur_framepos, (const float **)&info.base, &info.sample_offset, &type, &info.gain);
|
||||
if (type < 0 || type >= MAX_TYPES)
|
||||
continue;
|
||||
InputChanInfos[type].Insert(info);
|
||||
}
|
||||
}
|
||||
|
||||
int count = fOutput->GetOutputChannelCount();
|
||||
for (int chan = 0; chan < count; chan++) {
|
||||
int count2 = fOutput->GetOutputChannelSourceCount(chan);
|
||||
for (int i = 0; i < count2; i++) {
|
||||
int type;
|
||||
float gain;
|
||||
|
||||
input->GetMixerChannelInfo(chan, cur_framepos, &buffer, &src_sample_offset, &type, &gain);
|
||||
dst_sample_offset = fMixBufferChannelCount * sizeof(float);
|
||||
|
||||
CopySamples(&fMixBuffer[chan], dst_sample_offset, buffer, src_sample_offset, fMixBufferFrameCount);
|
||||
fOutput->GetMixerChannelInfo(chan, i, &type, &gain);
|
||||
if (type < 0 || type >= MAX_TYPES)
|
||||
continue;
|
||||
int count3 = InputChanInfos[type].CountItems();
|
||||
for (int j = 0; j < count3; j++) {
|
||||
chan_info *info;
|
||||
InputChanInfos[type].Get(j, &info);
|
||||
chan_info newinfo = *info;
|
||||
newinfo.gain *= gain;
|
||||
MixChanInfos[chan].Insert(newinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 dst_sample_offset = fMixBufferChannelCount * sizeof(float);
|
||||
|
||||
count = fOutput->GetOutputChannelCount();
|
||||
for (int chan = 0; chan < count; chan++) {
|
||||
PRINT(5, "MixThread: chan %d has %d sources\n", chan, MixChanInfos[chan].CountItems());
|
||||
ZeroFill(&fMixBuffer[chan], dst_sample_offset, fMixBufferFrameCount);
|
||||
int count2 = MixChanInfos[chan].CountItems();
|
||||
for (int i = 0; i < count2; i++) {
|
||||
chan_info *info;
|
||||
MixChanInfos[chan].Get(i, &info);
|
||||
char *dst = (char *)&fMixBuffer[chan];
|
||||
for (int j = 0; j < fMixBufferFrameCount; j++) {
|
||||
*(float *)dst += *(const float *)info->base * info->gain;
|
||||
dst += dst_sample_offset;
|
||||
info->base += info->sample_offset;
|
||||
}
|
||||
PRINT(5, "MixThread: base %p, sample-offset %2d, gain %.3f\n", info->base, info->sample_offset, info->gain);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,18 @@ CopySamples(float *_dst, int32 _dst_sample_offset,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ZeroFill(float *_dst, int32 _dst_sample_offset, int32 _sample_count)
|
||||
{
|
||||
register char * dst = (char *) _dst;
|
||||
register int32 sample_count = _sample_count;
|
||||
register int32 dst_sample_offset = _dst_sample_offset;
|
||||
while (sample_count--) {
|
||||
*(float *)dst = 0.0f;
|
||||
dst += dst_sample_offset;
|
||||
}
|
||||
}
|
||||
|
||||
int64
|
||||
frames_for_duration(double framerate, bigtime_t duration)
|
||||
{
|
||||
|
@ -12,6 +12,8 @@ void CopySamples(float *_dst, int32 _dst_sample_offset,
|
||||
const float *_src, int32 _src_sample_offset,
|
||||
int32 _sample_count);
|
||||
|
||||
void ZeroFill(float *_dst, int32 _dst_sample_offset, int32 _sample_count);
|
||||
|
||||
bigtime_t buffer_duration(const media_multi_audio_format & format);
|
||||
|
||||
int bytes_per_sample(const media_multi_audio_format & format);
|
||||
|
Loading…
Reference in New Issue
Block a user