[haiku-commits] haiku: hrev43804 - src/add-ons/media/media-add-ons/multi_audio

  • From: korli@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 29 Feb 2012 00:36:18 +0100 (CET)

hrev43804 adds 1 changeset to branch 'master'
old head: e766693eb0fe789eae0b729c7c5d5400018aa328
new head: ea81d6eaf00849fcf8bb46d5e2c2f59142dfc19b

----------------------------------------------------------------------------

ea81d6e: multi_audio: Add multiple Audio In Feature, implement listed TODO
  
  Signed-off-by: Jérôme Duval <jerome.duval@xxxxxxxxx>

                               [ Jerome Leveque <leveque.jerome@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev43804
Commit:      ea81d6eaf00849fcf8bb46d5e2c2f59142dfc19b
URL:         http://cgit.haiku-os.org/haiku/commit/?id=ea81d6e
Author:      Jerome Leveque <leveque.jerome@xxxxxxxxx>
Date:        Tue Jan 24 10:58:59 2012 UTC
Committer:   Jérôme Duval <jerome.duval@xxxxxxxxx>
Commit-Date: Tue Feb 28 23:36:05 2012 UTC

----------------------------------------------------------------------------

5 files changed, 900 insertions(+), 220 deletions(-)
.../media/media-add-ons/multi_audio/Jamfile        |    1 +
.../media-add-ons/multi_audio/MultiAudioNode.cpp   |  320 +++------
.../media-add-ons/multi_audio/MultiAudioNode.h     |    9 +-
.../media/media-add-ons/multi_audio/Resampler.cpp  |  645 ++++++++++++++++
.../media/media-add-ons/multi_audio/Resampler.h    |  145 ++++

----------------------------------------------------------------------------

diff --git a/src/add-ons/media/media-add-ons/multi_audio/Jamfile 
b/src/add-ons/media/media-add-ons/multi_audio/Jamfile
index 84b8641..7f116b7 100644
--- a/src/add-ons/media/media-add-ons/multi_audio/Jamfile
+++ b/src/add-ons/media/media-add-ons/multi_audio/Jamfile
@@ -13,6 +13,7 @@ Addon hmulti_audio.media_addon :
        MultiAudioDevice.cpp
        MultiAudioNode.cpp
        MultiAudioUtility.cpp
+       Resampler.cpp
        TimeComputer.cpp
        : be media $(TARGET_LIBSUPC++)
 ;
diff --git a/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.cpp 
b/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.cpp
index 44b9b5a..d417a88 100644
--- a/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.cpp
+++ b/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.cpp
@@ -24,12 +24,14 @@
 #      define PRINTING
 #endif
 #include "debug.h"
+#include "Resampler.h"
 
 
 #define PARAMETER_ID_INPUT_FREQUENCY   1
 #define PARAMETER_ID_OUTPUT_FREQUENCY  2
 
 
+//This represent an hardware output
 class node_input {
 public:
        node_input(media_input& input, media_format format);
@@ -39,12 +41,14 @@ public:
        media_input                     fInput;
        media_format            fPreferredFormat;
        media_format            fFormat;
-       uint32                          fBufferCycle;
+       volatile uint32         fBufferCycle;
        multi_buffer_info       fOldBufferInfo;
        BBuffer*                        fBuffer;
+       Resampler                       *fResampler;
 };
 
 
+//This represent an hardware input
 class node_output {
 public:
        node_output(media_output& output, media_format format);
@@ -60,6 +64,7 @@ public:
        uint64                          fSamplesSent;
        volatile uint32         fBufferCycle;
        multi_buffer_info       fOldBufferInfo;
+       Resampler                       *fResampler;
 };
 
 
@@ -115,6 +120,7 @@ node_input::node_input(media_input& input, media_format 
format)
        fPreferredFormat = format;
        fBufferCycle = 1;
        fBuffer = NULL;
+       fResampler = NULL;
 }
 
 
@@ -136,6 +142,7 @@ node_output::node_output(media_output& output, media_format 
format)
        fOutput = output;
        fPreferredFormat = format;
        fBufferCycle = 1;
+       fResampler = NULL;
 }
 
 
@@ -351,6 +358,10 @@ MultiAudioNode::NodeRegistered()
                        currentInput = new node_input(*input, 
fOutputPreferredFormat);
                        
currentInput->fPreferredFormat.u.raw_audio.channel_count = 1;
                        currentInput->fInput.format = 
currentInput->fPreferredFormat;
+                       delete currentInput->fResampler;
+                       currentInput->fResampler = new
+                               
Resampler(currentInput->fPreferredFormat.AudioFormat(),
+                                       fOutputPreferredFormat.AudioFormat());
 
                        currentInput->fChannelId = 
fDevice->Description().channels[i].channel_id;
                        fInputs.AddItem(currentInput);
@@ -397,6 +408,11 @@ MultiAudioNode::NodeRegistered()
                        currentOutput = new node_output(*output, 
fInputPreferredFormat);
                        
currentOutput->fPreferredFormat.u.raw_audio.channel_count = 1;
                        currentOutput->fOutput.format = 
currentOutput->fPreferredFormat;
+                       delete currentOutput->fResampler;
+                       currentOutput->fResampler = new
+                               Resampler(fInputPreferredFormat.AudioFormat(),
+                                       
currentOutput->fPreferredFormat.AudioFormat());
+
                        currentOutput->fChannelId = 
fDevice->Description().channels[i].channel_id;
                        fOutputs.AddItem(currentOutput);
 
@@ -1725,8 +1741,6 @@ MultiAudioNode::_OutputThread()
        CALLED();
        multi_buffer_info bufferInfo;
        bufferInfo.info_size = sizeof(multi_buffer_info);
-       bufferInfo._reserved_0 = 0;
-       bufferInfo._reserved_1 = 2;
        bufferInfo.playback_buffer_cycle = 0;
        bufferInfo.record_buffer_cycle = 0;
 
@@ -1758,8 +1772,7 @@ MultiAudioNode::_OutputThread()
                for (int32 i = 0; i < fInputs.CountItems(); i++) {
                        node_input* input = (node_input*)fInputs.ItemAt(i);
 
-                       if (bufferInfo._reserved_0 == input->fChannelId
-                               && bufferInfo.playback_buffer_cycle >= 0
+                       if (bufferInfo.playback_buffer_cycle >= 0
                                && bufferInfo.playback_buffer_cycle
                                                < 
fDevice->BufferList().return_playback_buffers
                                && (input->fOldBufferInfo.playback_buffer_cycle
@@ -1814,8 +1827,7 @@ MultiAudioNode::_OutputThread()
                        // buffer
                        if (RunState() == BMediaEventLooper::B_STARTED
                                && output->fOutput.destination != 
media_destination::null) {
-                               if (bufferInfo._reserved_1 == output->fChannelId
-                                       && bufferInfo.record_buffer_cycle >= 0
+                               if (bufferInfo.record_buffer_cycle >= 0
                                        && bufferInfo.record_buffer_cycle
                                                        < 
fDevice->BufferList().return_record_buffers
                                        && 
(output->fOldBufferInfo.record_buffer_cycle
@@ -1823,6 +1835,8 @@ MultiAudioNode::_OutputThread()
                                                || 
fDevice->BufferList().return_record_buffers == 1)) {
                                        //PRINT(("record_buffer_cycle ok\n"));
 
+                                       output->fBufferCycle = 
bufferInfo.record_buffer_cycle;
+
                                        // Get the next buffer of data
                                        BBuffer* buffer = 
_FillNextBuffer(bufferInfo, *output);
                                        if (buffer != NULL) {
@@ -1889,6 +1903,17 @@ MultiAudioNode::_WriteZeros(node_input& input, uint32 
bufferCycle)
                        }
                        break;
 
+               case media_raw_audio_format::B_AUDIO_DOUBLE:
+                       for (uint32 channel = 0; channel < channelCount; 
channel++) {
+                               char* dest = _PlaybackBuffer(bufferCycle,
+                                       input.fChannelId + channel);
+                               for (uint32 i = bufferSize; i > 0; i--) {
+                                       *(double*)dest = 0;
+                                       dest += stride;
+                               }
+                       }
+                       break;
+
                case media_raw_audio_format::B_AUDIO_INT:
                        for (uint32 channel = 0; channel < channelCount; 
channel++) {
                                char* dest = _PlaybackBuffer(bufferCycle,
@@ -1911,6 +1936,28 @@ MultiAudioNode::_WriteZeros(node_input& input, uint32 
bufferCycle)
                        }
                        break;
 
+               case media_raw_audio_format::B_AUDIO_UCHAR:
+                       for (uint32 channel = 0; channel < channelCount; 
channel++) {
+                               char* dest = _PlaybackBuffer(bufferCycle,
+                                       input.fChannelId + channel);
+                               for (uint32 i = bufferSize; i > 0; i--) {
+                                       *(uint8*)dest = 128;
+                                       dest += stride;
+                               }
+                       }
+                       break;
+
+               case media_raw_audio_format::B_AUDIO_CHAR:
+                       for (uint32 channel = 0; channel < channelCount; 
channel++) {
+                               char* dest = _PlaybackBuffer(bufferCycle,
+                                       input.fChannelId + channel);
+                               for (uint32 i = bufferSize; i > 0; i--) {
+                                       *(int8*)dest = 0;
+                                       dest += stride;
+                               }
+                       }
+                       break;
+
                default:
                        fprintf(stderr, "ERROR in WriteZeros format not 
handled\n");
        }
@@ -1929,218 +1976,35 @@ MultiAudioNode::_FillWithZeros(node_input& input)
 void
 MultiAudioNode::_FillNextBuffer(node_input& input, BBuffer* buffer)
 {
-       // TODO: simplify this, or put it into a static function to remove
-       // the need for checking all over again
+       uint32 channelCount = input.fInput.format.u.raw_audio.channel_count;
+       size_t inputSampleSize = input.fInput.format.u.raw_audio.format
+                       & media_raw_audio_format::B_AUDIO_SIZE_MASK;
 
        uint32 bufferSize = fDevice->BufferList().return_playback_buffer_size;
 
-       if (buffer->SizeUsed()
-               / (input.fInput.format.u.raw_audio.format
-                       & media_raw_audio_format::B_AUDIO_SIZE_MASK)
-               / input.fInput.format.u.raw_audio.channel_count != bufferSize) {
+       if (buffer->SizeUsed() / inputSampleSize / channelCount != bufferSize) {
                _WriteZeros(input, input.fBufferCycle);
                return;
        }
 
-       switch (input.fInput.format.u.raw_audio.format) {
-               case media_raw_audio_format::B_AUDIO_FLOAT:
-                       switch (input.fFormat.u.raw_audio.format) {
-                               case media_raw_audio_format::B_AUDIO_FLOAT:
-                               {
-                                       size_t frameSize = 
input.fInput.format.u.raw_audio
-                                               .channel_count * sizeof(float);
-                                       size_t stride = 
_PlaybackStride(input.fBufferCycle,
-                                               input.fChannelId);
-                                       //PRINT(("stride : %i, frame_size : %i, 
return_playback_buffer_size : %i\n", stride, frame_size, 
fDevice->BufferList().return_playback_buffer_size));
-                                       for (uint32 channel = 0; channel
-                                                       < 
input.fInput.format.u.raw_audio.channel_count;
-                                                       channel++) {
-                                               char* dest = 
_PlaybackBuffer(input.fBufferCycle,
-                                                       input.fChannelId + 
channel);
-                                               char* src = 
(char*)buffer->Data()
-                                                       + channel * 
sizeof(float);
-
-                                               for (uint32 i = bufferSize; i > 
0; i--) {
-                                                       *(float *)dest = 
*(float *)src;
-                                                       dest += stride;
-                                                       src += frameSize;
-                                               }
-                                       }
-                                       break;
-                               }
-
-                               case media_raw_audio_format::B_AUDIO_SHORT:
-                                       if 
(input.fInput.format.u.raw_audio.channel_count == 2) {
-                                               int16* dest1 = 
(int16*)_PlaybackBuffer(
-                                                       input.fBufferCycle, 
input.fChannelId);
-                                               int16* dest2 = 
(int16*)_PlaybackBuffer(
-                                                       input.fBufferCycle, 
input.fChannelId + 1);
-                                               float* src = 
(float*)buffer->Data();
-                                               if 
(_PlaybackStride(input.fBufferCycle,
-                                                                       
input.fChannelId) == sizeof(int16)
-                                                       && 
_PlaybackStride(input.fBufferCycle,
-                                                                       
input.fChannelId + 1) == sizeof(int16)) {
-                                                       
//PRINT(("FillNextBuffer : 2 channels strides 2\n"));
-                                                       for (uint32 i = 
bufferSize; i > 0; i--) {
-                                                               *dest1++ = 
int16(32767 * *src++);
-                                                               *dest2++ = 
int16(32767 * *src++);
-                                                       }
-                                               } else if 
(_PlaybackStride(input.fBufferCycle,
-                                                                       
input.fChannelId) == 2 * sizeof(int16)
-                                                       && 
_PlaybackStride(input.fBufferCycle,
-                                                                       
input.fChannelId + 1) == 2 * sizeof(int16)
-                                                       && dest1 + 1 == dest2) {
-                                                       
//PRINT(("FillNextBuffer : 2 channels strides 4\n"));
-                                                       for (uint32 i = 2 * 
bufferSize; i > 0; i--)
-                                                               *dest1++ = 
int16(32767 * *src++);
-                                               } else {
-                                                       
//PRINT(("FillNextBuffer : 2 channels strides != 2\n"));
-                                                       size_t stride1 = 
_PlaybackStride(input.fBufferCycle,
-                                                               
input.fChannelId) / sizeof(int16);
-                                                       size_t stride2 = 
_PlaybackStride(input.fBufferCycle,
-                                                               
input.fChannelId + 1) / sizeof(int16);
-                                                       for (uint32 i = 
bufferSize; i > 0; i--) {
-                                                               *dest1 = 
int16(32767 * *src++);
-                                                               *dest2 = 
int16(32767 * *src++);
-                                                               dest1 += 
stride1;
-                                                               dest2 += 
stride2;
-                                                       }
-                                               }
-                                       } else {
-                                               size_t frameSize = 
input.fInput.format.u
-                                                       
.raw_audio.channel_count * sizeof(int16);
-                                               size_t stride = 
_PlaybackStride(input.fBufferCycle,
-                                                       input.fChannelId);
-                                               //PRINT(("stride : %i, 
frame_size : %i, return_playback_buffer_size : %i\n", stride, frame_size, 
fDevice->BufferList().return_playback_buffer_size));
-                                               for (uint32 channel = 0; 
channel <
-                                                               
input.fInput.format.u.raw_audio.channel_count;
-                                                               channel++) {
-                                                       char* dest = 
_PlaybackBuffer(input.fBufferCycle,
-                                                               
input.fChannelId + channel);
-                                                       char* src = 
(char*)buffer->Data()
-                                                               + channel * 
sizeof(int16);
-
-                                                       for (uint32 i = 
bufferSize; i > 0; i--) {
-                                                               *(int16*)dest = 
int16(32767 * *(float*)src);
-                                                               dest += stride;
-                                                               src += 
frameSize;
-                                                       }
-                                               }
-                                       }
-                                       break;
+       if (channelCount != input.fFormat.u.raw_audio.channel_count) {
+               PRINT(("Channel count is different"));
+               return;
+       }
 
-                               case media_raw_audio_format::B_AUDIO_INT:
-                               default:
-                                       break;
-                       }
-                       break;
+       if (input.fResampler != NULL) {
+               size_t srcStride = channelCount * inputSampleSize;
 
-               case media_raw_audio_format::B_AUDIO_INT:
-                       switch (input.fFormat.u.raw_audio.format) {
-                               case media_raw_audio_format::B_AUDIO_INT:
-                               {
-                                       size_t frameSize = 
input.fInput.format.u.raw_audio
-                                               .channel_count * sizeof(int32);
-                                       size_t stride = 
_PlaybackStride(input.fBufferCycle,
-                                               input.fChannelId);
-                                       //PRINT(("stride : %i, frame_size : %i, 
return_playback_buffer_size : %i\n", stride, frame_size, 
fDevice->BufferList().return_playback_buffer_size));
-                                       for (uint32 channel = 0; channel
-                                                       < 
input.fInput.format.u.raw_audio.channel_count;
-                                                       channel++) {
-                                               char* dest = 
_PlaybackBuffer(input.fBufferCycle,
+               for (uint32 channel = 0; channel < channelCount; channel++) {
+                       char* src = (char*)buffer->Data() + channel * 
inputSampleSize;
+                       char* dst = _PlaybackBuffer(input.fBufferCycle,
+                                                       input.fChannelId + 
channel);
+                       size_t dstStride = _PlaybackStride(input.fBufferCycle,
                                                        input.fChannelId + 
channel);
-                                               char* src = 
(char*)buffer->Data()
-                                                       + channel * 
sizeof(int32);
-
-                                               for (uint32 i = bufferSize; i > 
0; i--) {
-                                                       *(int32 *)dest = 
*(int32 *)src;
-                                                       dest += stride;
-                                                       src += frameSize;
-                                               }
-                                       }
-                                       break;
-                               }
-                               case media_raw_audio_format::B_AUDIO_SHORT:
-                               case media_raw_audio_format::B_AUDIO_FLOAT:
-                               default:
-                                       break;
-                       }
-                       break;
-
-               case media_raw_audio_format::B_AUDIO_SHORT:
-                       switch (input.fFormat.u.raw_audio.format) {
-                               case media_raw_audio_format::B_AUDIO_SHORT:
-                                       if 
(input.fInput.format.u.raw_audio.channel_count == 2) {
-                                               int16* dest1 = 
(int16*)_PlaybackBuffer(
-                                                       input.fBufferCycle, 
input.fChannelId);
-                                               int16* dest2 = 
(int16*)_PlaybackBuffer(
-                                                       input.fBufferCycle, 
input.fChannelId + 1);
-                                               int16* src = 
(int16*)buffer->Data();
-                                               if 
(_PlaybackStride(input.fBufferCycle,
-                                                               
input.fChannelId) == sizeof(int16)
-                                                       && 
_PlaybackStride(input.fBufferCycle,
-                                                               
input.fChannelId + 1) == sizeof(int16)) {
-                                                       
//PRINT(("FillNextBuffer : 2 channels strides 2\n"));
-                                                       for (uint32 i = 
bufferSize; i > 0; i--) {
-                                                               *dest1++ = 
*src++;
-                                                               *dest2++ = 
*src++;
-                                                       }
-                                               } else if 
(_PlaybackStride(input.fBufferCycle,
-                                                               
input.fChannelId) == 2 * sizeof(int16)
-                                                       && 
_PlaybackStride(input.fBufferCycle,
-                                                               
input.fChannelId + 1) == 2 * sizeof(int16)
-                                                       && dest1 + 1 == dest2) {
-                                                               
//PRINT(("FillNextBuffer : 2 channels strides 4\n"));
-                                                               memcpy(dest1, 
src,
-                                                                       
bufferSize * 2 * sizeof(int16));
-                                                       } else {
-                                                               
//PRINT(("FillNextBuffer : 2 channels strides != 2\n"));
-                                                               size_t stride1 
= _PlaybackStride(
-                                                                       
input.fBufferCycle, input.fChannelId) / 2;
-                                                               size_t stride2 
= _PlaybackStride(
-                                                                       
input.fBufferCycle, input.fChannelId + 1)
-                                                                       / 2;
-
-                                                               for (uint32 i = 
bufferSize; i > 0; i--) {
-                                                                       *dest1 
= *src++;
-                                                                       *dest2 
= *src++;
-                                                                       dest1 
+= stride1;
-                                                                       dest2 
+= stride2;
-                                                               }
-                                                       }
-                                       } else {
-                                               size_t frameSize = 
input.fInput.format.u
-                                                       
.raw_audio.channel_count * sizeof(int16);
-                                               size_t stride = 
_PlaybackStride(input.fBufferCycle,
-                                                       input.fChannelId);
-                                               //PRINT(("stride : %i, 
frame_size : %i, return_playback_buffer_size : %i\n", stride, frame_size, 
fDevice->BufferList().return_playback_buffer_size));
-                                               for (uint32 channel = 0; channel
-                                                               < 
input.fInput.format.u.raw_audio.channel_count;
-                                                               channel++) {
-                                                       char* dest = 
_PlaybackBuffer(input.fBufferCycle,
-                                                               
input.fChannelId + channel);
-                                                       char* src = 
(char*)buffer->Data()
-                                                               + channel * 
sizeof(int16);
-
-                                                       for (uint32 i = 
bufferSize; i > 0; i--) {
-                                                               *(int16*)dest = 
*(int16*)src;
-                                                               dest += stride;
-                                                               src += 
frameSize;
-                                                       }
-                                               }
-                                       }
-                                       break;
-
-                               case media_raw_audio_format::B_AUDIO_FLOAT:
-                               case media_raw_audio_format::B_AUDIO_INT:
-                               default:
-                                       break;
-                       }
-                       break;
 
-               case media_raw_audio_format::B_AUDIO_UCHAR:
-               default:
-                       break;
+                       input.fResampler->Resample(src, srcStride,
+                               dst, dstStride, bufferSize);
+               }
        }
 }
 
@@ -2219,7 +2083,7 @@ MultiAudioNode::_UpdateTimeSource(multi_buffer_info& info,
 
 
 BBuffer*
-MultiAudioNode::_FillNextBuffer(multi_buffer_info &info, node_output &channel)
+MultiAudioNode::_FillNextBuffer(multi_buffer_info &info, node_output &output)
 {
        //CALLED();
        // get a buffer from our buffer group
@@ -2227,15 +2091,16 @@ MultiAudioNode::_FillNextBuffer(multi_buffer_info 
&info, node_output &channel)
        //PRINT(("MBI.record_buffer_cycle : %i\n", MBI.record_buffer_cycle));
        //PRINT(("MBI.recorded_real_time : %i\n", MBI.recorded_real_time));
        //PRINT(("MBI.recorded_frames_count : %i\n", 
MBI.recorded_frames_count));
-       if (!channel.fBufferGroup)
+       if (!output.fBufferGroup)
                return NULL;
 
-       BBuffer* buffer = channel.fBufferGroup->RequestBuffer(
-               channel.fOutput.format.u.raw_audio.buffer_size, 
BufferDuration());
+       BBuffer* buffer = output.fBufferGroup->RequestBuffer(
+               output.fOutput.format.u.raw_audio.buffer_size, 
BufferDuration());
        if (buffer == NULL) {
                // If we fail to get a buffer (for example, if the request 
times out),
                // we skip this buffer and go on to the next, to avoid locking 
up the
                // control thread.
+               fprintf(stderr, "Buffer is null");
                return NULL;
        }
 
@@ -2246,17 +2111,34 @@ MultiAudioNode::_FillNextBuffer(multi_buffer_info 
&info, node_output &channel)
        if (TimeSource() == NULL)
                fprintf(stderr, "TimeSource() NULL\n");
 
-       // now fill it with data, continuing where the last buffer left off
-       memcpy(buffer->Data(),
-               fDevice->BufferList().record_buffers[info.record_buffer_cycle]
-                       [channel.fChannelId
-                               - 
fDevice->Description().output_channel_count].base,
-               channel.fOutput.format.u.raw_audio.buffer_size);
+       uint32 channelCount = output.fOutput.format.u.raw_audio.channel_count;
+       size_t outputSampleSize = output.fOutput.format.u.raw_audio.format
+               & media_raw_audio_format::B_AUDIO_SIZE_MASK;
+
+       uint32 bufferSize = fDevice->BufferList().return_record_buffer_size;
+
+       if (output.fResampler != NULL) {
+               size_t dstStride = channelCount * outputSampleSize;
+
+               uint32 channelId = output.fChannelId
+                       - fDevice->Description().output_channel_count;
+
+               for (uint32 channel = 0; channel < channelCount; channel++) {
+                       char* src = _RecordBuffer(output.fBufferCycle,
+                                                                       
channelId + channel);
+                       size_t srcStride = _RecordStride(output.fBufferCycle,
+                                                                       
channelId + channel);
+                       char* dst = (char*)buffer->Data() + channel * 
outputSampleSize;
+
+                       output.fResampler->Resample(src, srcStride, dst, 
dstStride,
+                               bufferSize);
+               }
+       }
 
        // fill in the buffer header
        media_header* header = buffer->Header();
        header->type = B_MEDIA_RAW_AUDIO;
-       header->size_used = channel.fOutput.format.u.raw_audio.buffer_size;
+       header->size_used = output.fOutput.format.u.raw_audio.buffer_size;
        header->time_source = TimeSource()->ID();
        header->start_time = PerformanceTimeFor(info.recorded_real_time);
 
diff --git a/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.h 
b/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.h
index 34e9e1b..473c77b 100644
--- a/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.h
+++ b/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.h
@@ -166,6 +166,13 @@ private:
                                                                { return 
fDevice->BufferList().playback_buffers
                                                                        
[cycle][channel].stride; }
 
+                       char*                   _RecordBuffer(int32 cycle, 
int32 channel)
+                                                               { return 
fDevice->BufferList().record_buffers
+                                                                       
[cycle][channel].base; }
+                       uint32                  _RecordStride(int32 cycle, 
int32 channel)
+                                                               { return 
fDevice->BufferList().record_buffers
+                                                                       
[cycle][channel].stride; }
+
                        void                    _WriteZeros(node_input& input, 
uint32 bufferCycle);
                        void                    _FillWithZeros(node_input& 
input);
                        void                    _FillNextBuffer(node_input& 
channel,
@@ -178,7 +185,7 @@ private:
 
                        void                    _AllocateBuffers(node_output& 
channel);
                        BBuffer*                
_FillNextBuffer(multi_buffer_info& info,
-                                                               node_output& 
channel);
+                                                               node_output& 
output);
                        void                    
_UpdateTimeSource(multi_buffer_info& info,
                                                                
multi_buffer_info& oldInfo, node_input& input);
 
diff --git a/src/add-ons/media/media-add-ons/multi_audio/Resampler.cpp 
b/src/add-ons/media/media-add-ons/multi_audio/Resampler.cpp
new file mode 100644
index 0000000..780ec8d
--- /dev/null
+++ b/src/add-ons/media/media-add-ons/multi_audio/Resampler.cpp
@@ -0,0 +1,645 @@
+/*
+ * Copyright 2012 Jérôme Leveque
+ * Copyright 2012 Jérôme Duval
+ * Copyright 2003 Marcus Overhagen
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "Resampler.h"
+#include "MultiAudioUtility.h"
+#include "debug.h"
+
+
+/*!    A simple resampling class for the multi_audio add-ons.
+       You pick the conversion function on object creation,
+       and then call the Resample() function, specifying data pointer,
+       offset (in bytes) to the next sample, and count of samples.
+*/
+
+
+Resampler::Resampler(uint32 sourceFormat, uint32 destFormat)
+       :
+       fFunc(NULL)
+{
+       PRINT(("Resampler() in 0x%x, out 0x%x\n", (unsigned int)sourceFormat,
+               (unsigned int)destFormat));
+
+       switch (sourceFormat) {
+               case media_raw_audio_format::B_AUDIO_FLOAT:
+                       switch (destFormat) {
+                               case media_raw_audio_format::B_AUDIO_FLOAT:
+                                       fFunc = 
&Resampler::_CopyType2Type<float>;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_DOUBLE:
+                                       fFunc = &Resampler::_CopyFloat2Double;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_INT:
+                                       fFunc = &Resampler::_CopyFloat2Int;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_SHORT:
+                                       fFunc = &Resampler::_CopyFloat2Short;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_UCHAR:
+                                       fFunc = &Resampler::_CopyFloat2UChar;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_CHAR:
+                                       fFunc = &Resampler::_CopyFloat2Char;
+                                       break;
+                       }
+                       break;
+
+               case media_raw_audio_format::B_AUDIO_DOUBLE:
+                       switch (destFormat) {
+                               case media_raw_audio_format::B_AUDIO_FLOAT:
+                                       fFunc = &Resampler::_CopyDouble2Float;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_DOUBLE:
+                                       fFunc = 
&Resampler::_CopyType2Type<double>;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_INT:
+                                       fFunc = &Resampler::_CopyDouble2Int;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_SHORT:
+                                       fFunc = &Resampler::_CopyDouble2Short;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_UCHAR:
+                                       fFunc = &Resampler::_CopyDouble2UChar;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_CHAR:
+                                       fFunc = &Resampler::_CopyDouble2Char;
+                                       break;
+                       }
+                       break;
+
+               case media_raw_audio_format::B_AUDIO_INT:
+                       switch (destFormat) {
+                               case media_raw_audio_format::B_AUDIO_FLOAT:
+                                       fFunc = &Resampler::_CopyInt2Float;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_DOUBLE:
+                                       fFunc = &Resampler::_CopyInt2Double;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_INT:
+                                       fFunc = 
&Resampler::_CopyType2Type<int32>;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_SHORT:
+                                       fFunc = &Resampler::_CopyInt2Short;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_UCHAR:
+                                       fFunc = &Resampler::_CopyInt2UChar;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_CHAR:
+                                       fFunc = &Resampler::_CopyInt2Char;
+                                       break;
+                       }
+                       break;
+
+               case media_raw_audio_format::B_AUDIO_SHORT:
+                       switch (destFormat) {
+                               case media_raw_audio_format::B_AUDIO_FLOAT:
+                                       fFunc = &Resampler::_CopyShort2Float;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_DOUBLE:
+                                       fFunc = &Resampler::_CopyShort2Double;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_INT:
+                                       fFunc = &Resampler::_CopyShort2Int;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_SHORT:
+                                       fFunc = 
&Resampler::_CopyType2Type<int16>;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_UCHAR:
+                                       fFunc = &Resampler::_CopyShort2UChar;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_CHAR:
+                                       fFunc = &Resampler::_CopyShort2Char;
+                                       break;
+                       }
+                       break;
+
+               case media_raw_audio_format::B_AUDIO_UCHAR:
+                       switch (destFormat) {
+                               case media_raw_audio_format::B_AUDIO_FLOAT:
+                                       fFunc = &Resampler::_CopyUChar2Float;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_DOUBLE:
+                                       fFunc = &Resampler::_CopyUChar2Double;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_INT:
+                                       fFunc = &Resampler::_CopyUChar2Int;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_SHORT:
+                                       fFunc = &Resampler::_CopyUChar2Short;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_UCHAR:
+                                       fFunc = 
&Resampler::_CopyType2Type<uint8>;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_CHAR:
+                                       fFunc = &Resampler::_CopyUChar2Char;
+                                       break;
+                       }
+                       break;
+
+               case media_raw_audio_format::B_AUDIO_CHAR:
+                       switch (destFormat) {
+                               case media_raw_audio_format::B_AUDIO_FLOAT:
+                                       fFunc = &Resampler::_CopyChar2Float;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_DOUBLE:
+                                       fFunc = &Resampler::_CopyChar2Double;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_INT:
+                                       fFunc = &Resampler::_CopyChar2Int;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_SHORT:
+                                       fFunc = &Resampler::_CopyChar2Short;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_UCHAR:
+                                       fFunc = &Resampler::_CopyChar2UChar;
+                                       break;
+                               case media_raw_audio_format::B_AUDIO_CHAR:
+                                       fFunc = 
&Resampler::_CopyType2Type<int8>;
+                                       break;
+                       }
+                       break;
+       }
+}
+
+
+Resampler::~Resampler()
+{
+}
+
+
+status_t
+Resampler::InitCheck() const
+{
+       return fFunc != NULL ? B_OK : B_ERROR;
+}
+
+
+template<typename T>
+void
+Resampler::_CopyType2Type(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(T*)outputData = *(const T*)inputData;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyFloat2Double(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(double*)outputData = *(const float*)inputData;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyFloat2Int(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int32*)outputData = (int32)(*(const float*)inputData * 
2147483647.0f);
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+void
+Resampler::_CopyFloat2Short(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int16*)outputData = (int16)(*(const float*)inputData * 
32767.0f);
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyFloat2UChar(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(uint8*)outputData = (uint8)(128.0f + *(const float*)inputData 
* 127.0f);
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyFloat2Char(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int8*)outputData = (int8)(*(const float*)inputData * 127.0f);
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyDouble2Float(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(float*)outputData = *(const double*)inputData;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyDouble2Int(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int32*)outputData = (int32)(*(const double*)inputData * 
2147483647.0f);
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyDouble2Short(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int16*)outputData = (int16)(*(const double*)inputData * 
32767.0f);
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyDouble2UChar(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(uint8*)outputData = (uint8)(128.0f + *(const 
double*)inputData * 127.0f);
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyDouble2Char(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int8*)outputData = (int8)(*(const double*)inputData * 127.0f);
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyShort2Float(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(float*)outputData = *(const int16*)inputData / 32767.0f;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyShort2Double(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(double*)outputData = *(const int16*)inputData / 32767.0;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyShort2Int(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int32*)outputData = (int32)*(const int16*)inputData << 16;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyShort2UChar(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(uint8*)outputData = 128 + (*(const int16*)inputData >> 8);
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyShort2Char(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int8*)outputData = *(const int16*)inputData >> 8;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyInt2Float(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(float*)outputData = *(const int32*)inputData / 2147483647.0f;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyInt2Double(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(double*)outputData = *(const int32*)inputData / 2147483647.0;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyInt2Short(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int16*)outputData = *(const int32*)inputData >> 16;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyInt2UChar(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(uint8*)outputData = 128 + (*(const int32*)inputData >> 24);
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyInt2Char(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(uint8*)outputData = *(const int32*)inputData >> 24;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyUChar2Float(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(float*)outputData = (*(const uint8*)inputData - 128) / 127.0f;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyUChar2Double(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(double*)outputData = (*(const uint8*)inputData - 128) / 127.0;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyUChar2Short(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int16*)outputData = (int16)(*(const uint8*)inputData - 128) 
<< 8;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyUChar2Int(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int32*)outputData = (int32)(*(const uint8*)inputData - 128) 
<< 24;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyUChar2Char(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int8*)outputData = *(const uint8*)inputData - 128;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyChar2Float(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(float*)outputData = *(const int8*)inputData / 127.0f;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyChar2Double(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(double*)outputData = *(const int8*)inputData / 127.0;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyChar2Short(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int16*)outputData = ((int16)*(const int8*)inputData) << 8;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyChar2Int(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(int32*)outputData = ((int16)*(const int8*)inputData) << 24;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
+
+void
+Resampler::_CopyChar2UChar(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       while (sampleCount > 0) {
+               *(uint8*)outputData = *(const int8*)inputData + 128;
+
+               outputData = (void*)((uint8*)outputData + outputStride);
+               inputData = (void*)((uint8*)inputData + inputStride);
+
+               sampleCount--;
+       }
+}
+
diff --git a/src/add-ons/media/media-add-ons/multi_audio/Resampler.h 
b/src/add-ons/media/media-add-ons/multi_audio/Resampler.h
new file mode 100644
index 0000000..d392bd8
--- /dev/null
+++ b/src/add-ons/media/media-add-ons/multi_audio/Resampler.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2012 Jérôme Leveque
+ * Copyright 2003 Marcus Overhagen
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _MULTI_AUDIO_RESAMPLER_H
+#define _MULTI_AUDIO_RESAMPLER_H
+
+
+#include <MediaDefs.h>
+
+
+class Resampler {
+public:
+                                                               
Resampler(uint32 sourceFormat,
+                                                                       uint32 
destFormat);
+
+       virtual                                         ~Resampler();
+
+                       status_t                        InitCheck() const;
+
+                       void                            Resample(const void 
*inputData,
+                                                                       uint32 
inputStride, void *outputData,
+                                                                       uint32 
outputStride, uint32 sampleCount);
+
+protected:
+       //static functions for converting datas
+       template<typename T> void _CopyType2Type(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyFloat2Double(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyFloat2Short(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyFloat2Int(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyFloat2UChar(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyFloat2Char(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+
+       virtual  void                   _CopyDouble2Float(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyDouble2Short(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyDouble2Int(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyDouble2UChar(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyDouble2Char(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+
+       virtual  void                   _CopyInt2Float(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyInt2Double(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyInt2Short(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyInt2UChar(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyInt2Char(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+
+       virtual  void                   _CopyShort2Float(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyShort2Double(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyShort2Int(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyShort2UChar(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyShort2Char(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+
+       virtual  void                   _CopyUChar2Float(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyUChar2Double(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyUChar2Short(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyUChar2Int(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyUChar2Char(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+
+       virtual  void                   _CopyChar2Float(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyChar2Double(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyChar2Short(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyChar2Int(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+       virtual  void                   _CopyChar2UChar(const void *inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+
+private:
+                       void                    (Resampler::*fFunc)(const void 
*inputData,
+                                                               uint32 
inputStride, void *outputData,
+                                                               uint32 
outputStride, uint32 sampleCount);
+};
+
+
+inline void
+Resampler::Resample(const void *inputData, uint32 inputStride,
+       void *outputData, uint32 outputStride, uint32 sampleCount)
+{
+       if (this->InitCheck() != B_OK)
+               return;
+       (this->*fFunc)(inputData, inputStride, outputData, outputStride,
+               sampleCount);
+}
+
+
+#endif // _MULTI_AUDIO_RESAMPLER_H


Other related posts:

  • » [haiku-commits] haiku: hrev43804 - src/add-ons/media/media-add-ons/multi_audio - korli