use sample size when calculating channel offsets, no more buffer overruns

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3664 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper 2003-06-25 18:04:34 +00:00
parent 16cecbde36
commit 78563dcaec
5 changed files with 54 additions and 8 deletions

View File

@ -9,6 +9,7 @@
#include "MixerOutput.h"
#include "MixerUtils.h"
#include "AudioMixer.h"
#include "Resampler.h"
#include "Debug.h"
#define DOUBLE_RATE_MIXING 1
@ -34,6 +35,7 @@ MixerCore::MixerCore(AudioMixer *node)
fOutput(0),
fNextInputID(1),
fRunning(false),
fResampler(0),
fMixBuffer(0),
fMixBufferFrameRate(0),
fMixBufferFrameCount(0),
@ -63,6 +65,13 @@ MixerCore::~MixerCore()
if (fTimeSource)
fTimeSource->Release();
// delete resamplers
if (fResampler) {
for (int i = 0; i < fMixBufferChannelCount; i++)
delete fResampler[i];
delete [] fResampler;
}
delete fMixBufferChannelTypes;
}
@ -158,7 +167,7 @@ void
MixerCore::OutputFormatChanged(const media_multi_audio_format &format)
{
ASSERT_LOCKED();
if (fMixBuffer)
rtm_free(fMixBuffer);
@ -177,6 +186,18 @@ MixerCore::OutputFormatChanged(const media_multi_audio_format &format)
fMixBufferChannelTypes[i] = ChannelMaskToChannelType(GetChannelMask(i, format.channel_mask));
fMixBuffer = (float *)rtm_alloc(NULL, sizeof(float) * fMixBufferFrameCount * fMixBufferChannelCount);
ASSERT(fMixBuffer);
// delete resamplers
if (fResampler) {
for (int i = 0; i < fMixBufferChannelCount; i++)
delete fResampler[i];
delete [] fResampler;
}
// create new resamplers
fResampler = new Resampler * [fMixBufferChannelCount];
for (int i = 0; i < fMixBufferChannelCount; i++)
fResampler[i] = new Resampler(media_raw_audio_format::B_AUDIO_FLOAT, format.format);
printf("MixerCore::OutputFormatChanged:\n");
printf(" fMixBufferFrameRate %ld\n", fMixBufferFrameRate);
@ -321,12 +342,26 @@ MixerCore::MixThread()
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);
}
}
// 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
for (int i = 0; i < fMixBufferChannelCount; i++) {
fResampler[i]->Resample(reinterpret_cast<char *>(fMixBuffer) + i * sizeof(float),
fMixBufferChannelCount * sizeof(float),
fMixBufferFrameCount,
reinterpret_cast<char *>(buf->Data()) + (i * bytes_per_sample(fOutput->MediaOutput().format.u.raw_audio)),
bytes_per_frame(fOutput->MediaOutput().format.u.raw_audio),
frames_per_buffer(fOutput->MediaOutput().format.u.raw_audio),
1.0);
}
// fill in the buffer header
media_header* hdr = buf->Header();

View File

@ -6,6 +6,7 @@
class AudioMixer;
class MixerInput;
class MixerOutput;
class Resampler;
class MixerCore
{
@ -54,7 +55,9 @@ private:
MixerOutput *fOutput;
int32 fNextInputID;
bool fRunning;
Resampler **fResampler; // array
float *fMixBuffer;
int32 fMixBufferFrameRate;
int32 fMixBufferFrameCount;

View File

@ -121,16 +121,16 @@ MixerInput::BufferReceived(BBuffer *buffer)
in_frames, out_frames, in_frames1, out_frames1, in_frames2, out_frames2);
for (int i = 0; i < fInputChannelCount; i++) {
fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_frame(fInput.format.u.raw_audio),
fInputChannelCount * bytes_per_frame(fInput.format.u.raw_audio),
fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_sample(fInput.format.u.raw_audio),
bytes_per_frame(fInput.format.u.raw_audio),
in_frames1,
reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base) + (offset * sizeof(float) * fInputChannelCount),
fInputChannelCount * sizeof(float),
out_frames1,
fInputChannelInfo[i].gain);
fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_frame(fInput.format.u.raw_audio),
fInputChannelCount * bytes_per_frame(fInput.format.u.raw_audio),
fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_sample(fInput.format.u.raw_audio),
bytes_per_frame(fInput.format.u.raw_audio),
in_frames2,
reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base),
fInputChannelCount * sizeof(float),
@ -142,8 +142,8 @@ MixerInput::BufferReceived(BBuffer *buffer)
printf(" in_frames %5d, out_frames %5d\n", in_frames, out_frames);
for (int i = 0; i < fInputChannelCount; i++) {
fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_frame(fInput.format.u.raw_audio),
fInputChannelCount * bytes_per_frame(fInput.format.u.raw_audio),
fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_sample(fInput.format.u.raw_audio),
bytes_per_frame(fInput.format.u.raw_audio),
in_frames,
reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base) + (offset * sizeof(float) * fInputChannelCount),
fInputChannelCount * sizeof(float),

View File

@ -173,6 +173,12 @@ duration_for_frames(double framerate, int64 frames)
return (bigtime_t)((1000000.0 * frames) / framerate);
}
int
bytes_per_sample(const media_multi_audio_format & format)
{
return format.format & 0xf;
}
int
bytes_per_frame(const media_multi_audio_format & format)
{

View File

@ -12,6 +12,8 @@ void CopySamples(float *_dst, int32 _dst_sample_offset,
const float *_src, int32 _src_sample_offset,
int32 _sample_count);
int bytes_per_sample(const media_multi_audio_format & format);
int bytes_per_frame(const media_multi_audio_format & format);
int frames_per_buffer(const media_multi_audio_format & format);