parent
58bb5d5d12
commit
bcc0ad0c59
@ -1,41 +0,0 @@ |
|||||||
#ifndef _HX_MEMCPY_H |
|
||||||
#define _HX_MEMCPY_H |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief combine two separate buffers into interleaved one |
|
||||||
* @param sz - samples per output buffer (divisible by 2) |
|
||||||
* @param dst - pointer to source buffer |
|
||||||
* @param srcA - pointer to A source buffer (even samples) |
|
||||||
* @param srcB - pointer to B source buffer (odd samples) |
|
||||||
* @retval none |
|
||||||
*/ |
|
||||||
inline void memcpyInterleave_f32(float32_t *srcA, float32_t *srcB, float32_t *dst, int16_t sz) |
|
||||||
{ |
|
||||||
while(sz) |
|
||||||
{ |
|
||||||
*dst++ = *srcA++; |
|
||||||
*dst++ = *srcB++; |
|
||||||
sz--; |
|
||||||
*dst++ = *srcA++; |
|
||||||
*dst++ = *srcB++; |
|
||||||
sz--;
|
|
||||||
} |
|
||||||
} |
|
||||||
inline void memcpyInterleave_f32(float32_t *srcA, float32_t *srcB, float32_t *dst, int16_t sz); |
|
||||||
|
|
||||||
inline void memcpyDeinterleave_f32(float32_t *src, float32_t *dstA, float32_t *dstB, int16_t sz) |
|
||||||
{ |
|
||||||
while(sz) |
|
||||||
{ |
|
||||||
*dstA++ = *src++; |
|
||||||
*dstB++ = *src++; |
|
||||||
sz--; |
|
||||||
*dstA++ = *src++; |
|
||||||
*dstB++ = *src++; |
|
||||||
sz--;
|
|
||||||
} |
|
||||||
} |
|
||||||
inline void memcpyDeinterleave_f32(float32_t *src, float32_t *dstA, float32_t *dstB, int16_t sz); |
|
||||||
|
|
||||||
|
|
||||||
#endif // _HX_MEMCPY_H
|
|
@ -0,0 +1,70 @@ |
|||||||
|
#include "basic_bypassStereo_F32.h" |
||||||
|
|
||||||
|
bool bypass_process(audio_block_f32_t** p_blockL, audio_block_f32_t** p_blockR, bypass_mode_t mode, bool state) |
||||||
|
{ |
||||||
|
bool result = false; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief bypass mode PASS can be used to validate the incoming audio blocks, create silence blocks if the input ones
|
||||||
|
* are not available (NULL).
|
||||||
|
*/ |
||||||
|
if (!state) mode = BYPASS_MODE_PASS; |
||||||
|
|
||||||
|
switch(mode) |
||||||
|
{ |
||||||
|
/**
|
||||||
|
* @brief TRAILS mode is the same as OFF with the different the component "update" function does not return |
||||||
|
* and processes the incoming data, which is silence. Used in reverb/delays to let them naturally
|
||||||
|
* fade out |
||||||
|
*/ |
||||||
|
case BYPASS_MODE_TRAILS: |
||||||
|
/**
|
||||||
|
* @brief bypass mode OFF sends silence on both outputs. Used with components placed in an effect loop with separate |
||||||
|
* dry path. Classic example is a parallel effect loop used for delays and reverbs:
|
||||||
|
* input ------------> |0 |---> output |
||||||
|
* |--->reverb --> |1 mixer| |
||||||
|
*/ |
||||||
|
case BYPASS_MODE_OFF: |
||||||
|
if (*p_blockL) AudioStream_F32::release(*p_blockL); // discard both input blocks
|
||||||
|
if (*p_blockR) AudioStream_F32::release(*p_blockR); |
||||||
|
*p_blockL = NULL; |
||||||
|
*p_blockR = NULL; |
||||||
|
// no break - let it run through the next switch case, with input blocks as NULL it will emit silence on both channels
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PASS mode connects the input signal directly to the output |
||||||
|
* in case one of the blocks is not available, it tries to allocate a new block and make it silent |
||||||
|
* returns false if allocation is not possbile due to not enoufg audio memory (increase AudioMemory_F32(xx);) |
||||||
|
* Used in components connected in series. |
||||||
|
*/ |
||||||
|
case BYPASS_MODE_PASS: |
||||||
|
if(!*p_blockL) // no channel left available
|
||||||
|
{ |
||||||
|
*p_blockL = AudioStream_F32::allocate_f32(); // try to allocate a new block
|
||||||
|
if( !*p_blockL) |
||||||
|
{ |
||||||
|
if (*p_blockR) AudioStream_F32::release(*p_blockR); // if the Rch is present, release/discard it
|
||||||
|
result = false; |
||||||
|
break; // operation failed due to no audio memory left
|
||||||
|
} |
||||||
|
memset(&(*p_blockL)->data[0], 0, (*p_blockL)->length*sizeof(float32_t)); // zero the data block to make it silent
|
||||||
|
} |
||||||
|
if(!*p_blockR) // no channel right available
|
||||||
|
{ |
||||||
|
*p_blockR = AudioStream_F32::allocate_f32(); |
||||||
|
if( !*p_blockR) // no memory for a new block, but we might have L channel zeroed
|
||||||
|
{ |
||||||
|
if (*p_blockL) AudioStream_F32::release(*p_blockL); // blockL is available and contains audio. Discard it
|
||||||
|
result = false; |
||||||
|
break; // and sigbnal failed operation
|
||||||
|
} |
||||||
|
memset(&(*p_blockR)->data[0], 0, (*p_blockR)->length*sizeof(float32_t));
|
||||||
|
} |
||||||
|
result = true; // audio data on L and R is avaialble
|
||||||
|
break; |
||||||
|
|
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
#ifndef _BASIC_BYPASSSTEREO_F32_H_ |
||||||
|
#define _BASIC_BYPASSSTEREO_F32_H_ |
||||||
|
|
||||||
|
#include "Arduino.h" |
||||||
|
#include "AudioStream_F32.h" |
||||||
|
|
||||||
|
|
||||||
|
typedef enum |
||||||
|
{ |
||||||
|
BYPASS_MODE_PASS, // pass the input signal to the output
|
||||||
|
BYPASS_MODE_OFF, // mute the output
|
||||||
|
BYPASS_MODE_TRAILS // mutes the input only
|
||||||
|
}bypass_mode_t; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stereo bypass handling and validating the input audio blocks |
||||||
|
* The main component has to provide the pointers to audio blocks received inside the "update" function |
||||||
|
* This function checks whether they are avaiable and genereates silence where needed (null block received) |
||||||
|
* With the bypass OFF (state=false) it can be used to validate the input blocks before processing. |
||||||
|
*
|
||||||
|
* @param p_blockL pointer to an audio_block_f32_t pointer received/allocated in the main compontnt, channel L |
||||||
|
* @param p_blockR pointer to an audio_block_f32_t pointer received/allocated in the main compontnt, channel R |
||||||
|
* @param mode one of the bypass models defined in bypass_mode_t enum |
||||||
|
* @param state bypass state, true = effect OFF, false = effect ON |
||||||
|
* @return true operation succesful, blocks are available for further processing |
||||||
|
* @return false fail, some of the blocks are not available, do not process the data |
||||||
|
*/ |
||||||
|
bool bypass_process(audio_block_f32_t** p_blockL, audio_block_f32_t** p_blockR, bypass_mode_t mode, bool state); |
||||||
|
|
||||||
|
|
||||||
|
#endif // _BASIC_BYPASSSTEREO_F32_H_
|
Loading…
Reference in new issue