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:
@@ -9,6 +9,7 @@
|
|||||||
#include "MixerOutput.h"
|
#include "MixerOutput.h"
|
||||||
#include "MixerUtils.h"
|
#include "MixerUtils.h"
|
||||||
#include "AudioMixer.h"
|
#include "AudioMixer.h"
|
||||||
|
#include "Resampler.h"
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
|
|
||||||
#define DOUBLE_RATE_MIXING 1
|
#define DOUBLE_RATE_MIXING 1
|
||||||
@@ -34,6 +35,7 @@ MixerCore::MixerCore(AudioMixer *node)
|
|||||||
fOutput(0),
|
fOutput(0),
|
||||||
fNextInputID(1),
|
fNextInputID(1),
|
||||||
fRunning(false),
|
fRunning(false),
|
||||||
|
fResampler(0),
|
||||||
fMixBuffer(0),
|
fMixBuffer(0),
|
||||||
fMixBufferFrameRate(0),
|
fMixBufferFrameRate(0),
|
||||||
fMixBufferFrameCount(0),
|
fMixBufferFrameCount(0),
|
||||||
@@ -63,6 +65,13 @@ MixerCore::~MixerCore()
|
|||||||
if (fTimeSource)
|
if (fTimeSource)
|
||||||
fTimeSource->Release();
|
fTimeSource->Release();
|
||||||
|
|
||||||
|
// delete resamplers
|
||||||
|
if (fResampler) {
|
||||||
|
for (int i = 0; i < fMixBufferChannelCount; i++)
|
||||||
|
delete fResampler[i];
|
||||||
|
delete [] fResampler;
|
||||||
|
}
|
||||||
|
|
||||||
delete fMixBufferChannelTypes;
|
delete fMixBufferChannelTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +167,7 @@ void
|
|||||||
MixerCore::OutputFormatChanged(const media_multi_audio_format &format)
|
MixerCore::OutputFormatChanged(const media_multi_audio_format &format)
|
||||||
{
|
{
|
||||||
ASSERT_LOCKED();
|
ASSERT_LOCKED();
|
||||||
|
|
||||||
if (fMixBuffer)
|
if (fMixBuffer)
|
||||||
rtm_free(fMixBuffer);
|
rtm_free(fMixBuffer);
|
||||||
|
|
||||||
@@ -177,6 +186,18 @@ MixerCore::OutputFormatChanged(const media_multi_audio_format &format)
|
|||||||
fMixBufferChannelTypes[i] = ChannelMaskToChannelType(GetChannelMask(i, format.channel_mask));
|
fMixBufferChannelTypes[i] = ChannelMaskToChannelType(GetChannelMask(i, format.channel_mask));
|
||||||
|
|
||||||
fMixBuffer = (float *)rtm_alloc(NULL, sizeof(float) * fMixBufferFrameCount * fMixBufferChannelCount);
|
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("MixerCore::OutputFormatChanged:\n");
|
||||||
printf(" fMixBufferFrameRate %ld\n", fMixBufferFrameRate);
|
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);
|
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
|
// 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, 10000);
|
||||||
if (buf) {
|
if (buf) {
|
||||||
|
|
||||||
// copy data from mix buffer into output buffer
|
// 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
|
// fill in the buffer header
|
||||||
media_header* hdr = buf->Header();
|
media_header* hdr = buf->Header();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
class AudioMixer;
|
class AudioMixer;
|
||||||
class MixerInput;
|
class MixerInput;
|
||||||
class MixerOutput;
|
class MixerOutput;
|
||||||
|
class Resampler;
|
||||||
|
|
||||||
class MixerCore
|
class MixerCore
|
||||||
{
|
{
|
||||||
@@ -54,7 +55,9 @@ private:
|
|||||||
MixerOutput *fOutput;
|
MixerOutput *fOutput;
|
||||||
int32 fNextInputID;
|
int32 fNextInputID;
|
||||||
bool fRunning;
|
bool fRunning;
|
||||||
|
|
||||||
|
Resampler **fResampler; // array
|
||||||
|
|
||||||
float *fMixBuffer;
|
float *fMixBuffer;
|
||||||
int32 fMixBufferFrameRate;
|
int32 fMixBufferFrameRate;
|
||||||
int32 fMixBufferFrameCount;
|
int32 fMixBufferFrameCount;
|
||||||
|
|||||||
@@ -121,16 +121,16 @@ MixerInput::BufferReceived(BBuffer *buffer)
|
|||||||
in_frames, out_frames, in_frames1, out_frames1, in_frames2, out_frames2);
|
in_frames, out_frames, in_frames1, out_frames1, in_frames2, out_frames2);
|
||||||
|
|
||||||
for (int i = 0; i < fInputChannelCount; i++) {
|
for (int i = 0; i < fInputChannelCount; i++) {
|
||||||
fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_frame(fInput.format.u.raw_audio),
|
fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_sample(fInput.format.u.raw_audio),
|
||||||
fInputChannelCount * bytes_per_frame(fInput.format.u.raw_audio),
|
bytes_per_frame(fInput.format.u.raw_audio),
|
||||||
in_frames1,
|
in_frames1,
|
||||||
reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base) + (offset * sizeof(float) * fInputChannelCount),
|
reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base) + (offset * sizeof(float) * fInputChannelCount),
|
||||||
fInputChannelCount * sizeof(float),
|
fInputChannelCount * sizeof(float),
|
||||||
out_frames1,
|
out_frames1,
|
||||||
fInputChannelInfo[i].gain);
|
fInputChannelInfo[i].gain);
|
||||||
|
|
||||||
fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_frame(fInput.format.u.raw_audio),
|
fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_sample(fInput.format.u.raw_audio),
|
||||||
fInputChannelCount * bytes_per_frame(fInput.format.u.raw_audio),
|
bytes_per_frame(fInput.format.u.raw_audio),
|
||||||
in_frames2,
|
in_frames2,
|
||||||
reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base),
|
reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base),
|
||||||
fInputChannelCount * sizeof(float),
|
fInputChannelCount * sizeof(float),
|
||||||
@@ -142,8 +142,8 @@ MixerInput::BufferReceived(BBuffer *buffer)
|
|||||||
printf(" in_frames %5d, out_frames %5d\n", in_frames, out_frames);
|
printf(" in_frames %5d, out_frames %5d\n", in_frames, out_frames);
|
||||||
|
|
||||||
for (int i = 0; i < fInputChannelCount; i++) {
|
for (int i = 0; i < fInputChannelCount; i++) {
|
||||||
fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_frame(fInput.format.u.raw_audio),
|
fResampler[i]->Resample(reinterpret_cast<char *>(data) + i * bytes_per_sample(fInput.format.u.raw_audio),
|
||||||
fInputChannelCount * bytes_per_frame(fInput.format.u.raw_audio),
|
bytes_per_frame(fInput.format.u.raw_audio),
|
||||||
in_frames,
|
in_frames,
|
||||||
reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base) + (offset * sizeof(float) * fInputChannelCount),
|
reinterpret_cast<char *>(fInputChannelInfo[i].buffer_base) + (offset * sizeof(float) * fInputChannelCount),
|
||||||
fInputChannelCount * sizeof(float),
|
fInputChannelCount * sizeof(float),
|
||||||
|
|||||||
@@ -173,6 +173,12 @@ duration_for_frames(double framerate, int64 frames)
|
|||||||
return (bigtime_t)((1000000.0 * frames) / framerate);
|
return (bigtime_t)((1000000.0 * frames) / framerate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bytes_per_sample(const media_multi_audio_format & format)
|
||||||
|
{
|
||||||
|
return format.format & 0xf;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
bytes_per_frame(const media_multi_audio_format & format)
|
bytes_per_frame(const media_multi_audio_format & format)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ void CopySamples(float *_dst, int32 _dst_sample_offset,
|
|||||||
const float *_src, int32 _src_sample_offset,
|
const float *_src, int32 _src_sample_offset,
|
||||||
int32 _sample_count);
|
int32 _sample_count);
|
||||||
|
|
||||||
|
int bytes_per_sample(const media_multi_audio_format & format);
|
||||||
|
|
||||||
int bytes_per_frame(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);
|
int frames_per_buffer(const media_multi_audio_format & format);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user