@@ -176,7 +176,7 @@ Chain::~Chain ( ) | |||
client()->lock(); | |||
for ( unsigned int i = scratch_port.size(); i--; ) | |||
delete[] (sample_t*)scratch_port[i].buffer(); | |||
free( (sample_t*)scratch_port[i].buffer() ); | |||
/* if we leave this up to FLTK, it will happen after we've | |||
already destroyed the client */ | |||
@@ -376,13 +376,13 @@ Chain::configure_ports ( void ) | |||
if ( scratch_port.size() < req_buffers ) | |||
{ | |||
for ( unsigned int i = scratch_port.size(); i--; ) | |||
delete[] (sample_t*)scratch_port[i].buffer(); | |||
free(scratch_port[i].buffer()); | |||
scratch_port.clear(); | |||
for ( unsigned int i = 0; i < req_buffers; ++i ) | |||
{ | |||
Module::Port p( NULL, Module::Port::OUTPUT, Module::Port::AUDIO ); | |||
p.connect_to( new sample_t[client()->nframes()] ); | |||
p.connect_to( buffer_alloc( client()->nframes() ) ); | |||
buffer_fill_with_silence( (sample_t*)p.buffer(), client()->nframes() ); | |||
scratch_port.push_back( p ); | |||
} | |||
@@ -812,7 +812,7 @@ void | |||
Chain::buffer_size ( nframes_t nframes ) | |||
{ | |||
for ( unsigned int i = scratch_port.size(); i--; ) | |||
delete[] (sample_t*)scratch_port[i].buffer(); | |||
free(scratch_port[i].buffer()); | |||
scratch_port.clear(); | |||
configure_ports(); | |||
@@ -29,6 +29,7 @@ | |||
#include "Meter_Module.H" | |||
#include "DPM.H" | |||
#include "JACK/Port.H" | |||
#include "dsp.h" | |||
@@ -170,23 +171,6 @@ Meter_Module::handle ( int m ) | |||
/* Engine */ | |||
/**********/ | |||
static float | |||
get_peak_sample ( const sample_t* buf, nframes_t nframes ) | |||
{ | |||
float p = 0.0f; | |||
const sample_t *f = buf; | |||
for ( int j = nframes; j--; ++f ) | |||
{ | |||
const float s = fabs( *f ); | |||
if ( s > p ) | |||
p = s; | |||
} | |||
return p; | |||
} | |||
void | |||
Meter_Module::process ( nframes_t nframes ) | |||
@@ -196,7 +180,7 @@ Meter_Module::process ( nframes_t nframes ) | |||
if ( audio_input[i].connected() ) | |||
{ | |||
// float dB = 20 * log10( get_peak_sample( (float*)audio_input[i].buffer(), nframes ) / 2.0f ); | |||
float dB = 20 * log10( get_peak_sample( (float*)audio_input[i].buffer(), nframes ) ); | |||
float dB = 20 * log10( buffer_get_peak( (sample_t*) audio_input[i].buffer(), nframes ) ); | |||
((float*)control_output[0].buffer())[i] = dB; | |||
if (dB > control_value[i]) | |||
@@ -316,7 +316,7 @@ public: | |||
LOG_NAME_FUNC( Module ); | |||
nframes_t nframes ( void ) const { return _nframes; } | |||
void resize_buffers ( nframes_t v ) { _nframes = v; } | |||
virtual void resize_buffers ( nframes_t v ) { _nframes = v; } | |||
int instances ( void ) const { return _instances; } | |||
@@ -21,47 +21,73 @@ | |||
#include "dsp.h" | |||
#include "string.h" // for memset. | |||
#include <stdlib.h> | |||
/* TODO: these functions are all targets for optimization (SSE?) */ | |||
static const int ALIGNMENT = 16; | |||
sample_t * | |||
buffer_alloc ( nframes_t size ) | |||
{ | |||
void *p; | |||
posix_memalign( &p, ALIGNMENT, size * sizeof( sample_t ) ); | |||
return (sample_t*)p; | |||
} | |||
void | |||
buffer_apply_gain ( sample_t *buf, nframes_t nframes, float g ) | |||
buffer_apply_gain ( sample_t * __restrict__ buf, nframes_t nframes, float g ) | |||
{ | |||
sample_t * buf_ = (sample_t*) __builtin_assume_aligned(buf,ALIGNMENT); | |||
if ( g != 1.0f ) | |||
while ( nframes-- ) | |||
*(buf++) *= g; | |||
*(buf_++) *= g; | |||
} | |||
void | |||
buffer_apply_gain_buffer ( sample_t *buf, const sample_t *gainbuf, nframes_t nframes ) | |||
buffer_apply_gain_buffer ( sample_t * __restrict__ buf, const sample_t * __restrict__ gainbuf, nframes_t nframes ) | |||
{ | |||
sample_t * buf_ = (sample_t*) __builtin_assume_aligned(buf,ALIGNMENT); | |||
const sample_t * gainbuf_ = (const sample_t*) __builtin_assume_aligned(gainbuf,ALIGNMENT); | |||
while ( nframes-- ) | |||
*(buf++) *= *(gainbuf++); | |||
*(buf_++) *= *(gainbuf_++); | |||
} | |||
void | |||
buffer_copy_and_apply_gain_buffer ( sample_t *dst, const sample_t *src, const sample_t *gainbuf, nframes_t nframes ) | |||
buffer_copy_and_apply_gain_buffer ( sample_t * __restrict__ dst, const sample_t * __restrict__ src, const sample_t * __restrict__ gainbuf, nframes_t nframes ) | |||
{ | |||
while ( nframes-- ) | |||
*(dst++) = *(src++) * *(gainbuf++); | |||
sample_t * dst_ = (sample_t*) __builtin_assume_aligned(dst,ALIGNMENT); | |||
const sample_t * src_ = (const sample_t*) __builtin_assume_aligned(src,ALIGNMENT); | |||
const sample_t * gainbuf_ = (const sample_t*) __builtin_assume_aligned(gainbuf,ALIGNMENT); | |||
while ( nframes-- ) | |||
*(dst_++) = *(src_++) * *(gainbuf_++); | |||
} | |||
void | |||
buffer_mix ( sample_t *dst, const sample_t *src, nframes_t nframes ) | |||
buffer_mix ( sample_t * __restrict__ dst, const sample_t * __restrict__ src, nframes_t nframes ) | |||
{ | |||
sample_t * dst_ = (sample_t*) __builtin_assume_aligned(dst,ALIGNMENT); | |||
const sample_t * src_ = (const sample_t*) __builtin_assume_aligned(src,ALIGNMENT); | |||
while ( nframes-- ) | |||
*(dst++) += *(src++); | |||
*(dst_++) += *(src_++); | |||
} | |||
void | |||
buffer_mix_with_gain ( sample_t *dst, const sample_t *src, nframes_t nframes, float g ) | |||
buffer_mix_with_gain ( sample_t * __restrict__ dst, const sample_t * __restrict__ src, nframes_t nframes, float g ) | |||
{ | |||
sample_t * dst_ = (sample_t*) __builtin_assume_aligned(dst,ALIGNMENT); | |||
const sample_t * src_ = (const sample_t*) __builtin_assume_aligned(src,ALIGNMENT); | |||
while ( nframes-- ) | |||
*(dst++) += *(src++) * g; | |||
*(dst_++) += *(src_++) * g; | |||
} | |||
void | |||
buffer_interleave_one_channel ( sample_t *dst, const sample_t *src, int channel, int channels, nframes_t nframes ) | |||
buffer_interleave_one_channel ( sample_t * __restrict__ dst, const sample_t * __restrict__ src, int channel, int channels, nframes_t nframes ) | |||
{ | |||
dst += channel; | |||
@@ -73,7 +99,7 @@ buffer_interleave_one_channel ( sample_t *dst, const sample_t *src, int channel, | |||
} | |||
void | |||
buffer_interleave_one_channel_and_mix ( sample_t *dst, const sample_t *src, int channel, int channels, nframes_t nframes ) | |||
buffer_interleave_one_channel_and_mix ( sample_t *__restrict__ dst, const sample_t * __restrict__ src, int channel, int channels, nframes_t nframes ) | |||
{ | |||
dst += channel; | |||
@@ -85,7 +111,7 @@ buffer_interleave_one_channel_and_mix ( sample_t *dst, const sample_t *src, int | |||
} | |||
void | |||
buffer_deinterleave_one_channel ( sample_t *dst, const sample_t *src, int channel, int channels, nframes_t nframes ) | |||
buffer_deinterleave_one_channel ( sample_t * __restrict__ dst, const sample_t * __restrict__ src, int channel, int channels, nframes_t nframes ) | |||
{ | |||
src += channel; | |||
@@ -115,19 +141,36 @@ buffer_is_digital_black ( sample_t *buf, nframes_t nframes ) | |||
return true; | |||
} | |||
float | |||
buffer_get_peak ( const sample_t * __restrict__ buf, nframes_t nframes ) | |||
{ | |||
const sample_t * buf_ = (const sample_t*) __builtin_assume_aligned(buf,ALIGNMENT); | |||
float p = 0.0f; | |||
while ( nframes-- ) | |||
{ | |||
const float s = fabs(*(buf_++)); | |||
p = s > p ? s : p; | |||
} | |||
return p; | |||
} | |||
void | |||
buffer_copy ( sample_t *dst, const sample_t *src, nframes_t nframes ) | |||
buffer_copy ( sample_t * __restrict__ dst, const sample_t * __restrict__ src, nframes_t nframes ) | |||
{ | |||
memcpy( dst, src, nframes * sizeof( sample_t ) ); | |||
} | |||
void | |||
buffer_copy_and_apply_gain ( sample_t *dst, const sample_t *src, nframes_t nframes, float gain ) | |||
buffer_copy_and_apply_gain ( sample_t * __restrict__ dst, const sample_t * __restrict__ src, nframes_t nframes, float gain ) | |||
{ | |||
memcpy( dst, src, nframes * sizeof( sample_t ) ); | |||
buffer_apply_gain( dst, nframes, gain ); | |||
} | |||
void | |||
Value_Smoothing_Filter::sample_rate ( nframes_t n ) | |||
{ | |||
@@ -138,8 +181,10 @@ Value_Smoothing_Filter::sample_rate ( nframes_t n ) | |||
} | |||
bool | |||
Value_Smoothing_Filter::apply( sample_t *dst, nframes_t nframes, float gt ) | |||
Value_Smoothing_Filter::apply( sample_t * __restrict__ dst, nframes_t nframes, float gt ) | |||
{ | |||
sample_t * dst_ = (sample_t*) __builtin_assume_aligned(dst,ALIGNMENT); | |||
const float a = 0.07f; | |||
const float b = 1 + a; | |||
@@ -155,7 +200,7 @@ Value_Smoothing_Filter::apply( sample_t *dst, nframes_t nframes, float gt ) | |||
{ | |||
g1 += w * (gm - g1 - a * g2); | |||
g2 += w * (g1 - g2); | |||
dst[i] = g2; | |||
dst_[i] = g2; | |||
} | |||
if ( fabsf( gt - g2 ) < 0.0001f ) | |||
@@ -22,6 +22,8 @@ | |||
#include "JACK/Client.H" | |||
#include <math.h> | |||
sample_t *buffer_alloc ( nframes_t size ); | |||
void buffer_apply_gain ( sample_t *buf, nframes_t nframes, float g ); | |||
void buffer_apply_gain_buffer ( sample_t *buf, const sample_t *gainbuf, nframes_t nframes ); | |||
void buffer_copy_and_apply_gain_buffer ( sample_t *dst, const sample_t *src, const sample_t *gainbuf, nframes_t nframes ); | |||
@@ -31,7 +33,8 @@ void buffer_interleave_one_channel ( sample_t *dst, const sample_t *src, int cha | |||
void buffer_interleave_one_channel_and_mix ( sample_t *dst, const sample_t *src, int channel, int channels, nframes_t nframes ); | |||
void buffer_deinterleave_one_channel ( sample_t *dst, const sample_t *src, int channel, int channels, nframes_t nframes ); | |||
void buffer_fill_with_silence ( sample_t *buf, nframes_t nframes ); | |||
bool buffer_is_digital_black ( sample_t *buf, nframes_t nframes ); | |||
bool buffer_is_digital_black ( const sample_t *buf, nframes_t nframes ); | |||
float buffer_get_peak ( const sample_t *buf, nframes_t nframes ); | |||
void buffer_copy ( sample_t *dst, const sample_t *src, nframes_t nframes ); | |||
void buffer_copy_and_apply_gain ( sample_t *dst, const sample_t *src, nframes_t nframes, float gain ); | |||
@@ -119,9 +119,9 @@ Playback_DS::disk_thread ( void ) | |||
DMESSAGE( "playback thread running" ); | |||
/* buffer to hold the interleaved data returned by the track reader */ | |||
sample_t *buf = new sample_t[ _nframes * channels() * _disk_io_blocks ]; | |||
sample_t *buf = buffer_alloc( _nframes * channels() * _disk_io_blocks ); | |||
#ifndef AVOID_UNNECESSARY_COPYING | |||
sample_t *cbuf = new sample_t[ _nframes * _disk_io_blocks ]; | |||
sample_t *cbuf = buffer_alloc( _nframes * _disk_io_blocks ); | |||
#endif | |||
int blocks_ready = 0; | |||
@@ -168,6 +168,7 @@ Playback_DS::disk_thread ( void ) | |||
{ | |||
#ifdef AVOID_UNNECESSARY_COPYING | |||
/* deinterleave direcectly into the ringbuffer to avoid | |||
* unnecessary copying */ | |||
@@ -217,9 +218,9 @@ done: | |||
DMESSAGE( "playback thread terminating" ); | |||
delete[] buf; | |||
free(buf); | |||
#ifndef AVOID_UNNECESSARY_COPYING | |||
delete[] cbuf; | |||
free(cbuf); | |||
#endif | |||
_terminate = false; | |||
@@ -77,9 +77,9 @@ Record_DS::disk_thread ( void ) | |||
const nframes_t nframes = _nframes * _disk_io_blocks; | |||
/* buffer to hold the interleaved data returned by the track reader */ | |||
sample_t *buf = new sample_t[ nframes * channels() ]; | |||
sample_t *buf = buffer_alloc( nframes * channels() ); | |||
#ifndef AVOID_UNNECESSARY_COPYING | |||
sample_t *cbuf = new sample_t[ nframes ]; | |||
sample_t *cbuf = buffer_alloc( nframes ); | |||
#endif | |||
const size_t block_size = nframes * sizeof( sample_t ); | |||
@@ -98,7 +98,6 @@ Record_DS::disk_thread ( void ) | |||
{ | |||
#ifdef AVOID_UNNECESSARY_COPYING | |||
/* interleave direcectly from the ringbuffer to avoid | |||
* unnecessary copying */ | |||
@@ -122,7 +121,6 @@ Record_DS::disk_thread ( void ) | |||
const nframes_t f = rbd[ 0 ].len / sizeof( sample_t ); | |||
/* do the first half */ | |||
buffer_deinterleave_one_channel( (sample_t*)rbd[ 0 ].buf, buf, i, channels(), f ); | |||
buffer_interleave_one_channel( buf, (sample_t*)rbd[ 0 ].buf, i, channels(), f ); | |||
assert( rbd[ 1 ].len >= ( nframes - f ) * sizeof( sample_t ) ); | |||
@@ -158,7 +156,7 @@ Record_DS::disk_thread ( void ) | |||
const size_t block_size = _nframes * sizeof( sample_t ); | |||
#ifdef AVOID_UNNECESSARY_COPYING | |||
sample_t *cbuf = new sample_t[ nframes ]; | |||
sample_t *cbuf = buffer_alloc( nframes ); | |||
#endif | |||
while ( blocks_ready-- > 0 || ( ! sem_trywait( &_blocks ) && errno != EAGAIN ) ) | |||
@@ -184,14 +182,14 @@ Record_DS::disk_thread ( void ) | |||
} | |||
#ifdef AVOID_UNNECESSARY_COPYING | |||
delete[] cbuf; | |||
free(cbuf); | |||
#endif | |||
} | |||
delete[] buf; | |||
free(buf); | |||
#ifndef AVOID_UNNECESSARY_COPYING | |||
delete[] cbuf; | |||
free(cbuf); | |||
#endif | |||
DMESSAGE( "finalzing capture" ); | |||
@@ -76,8 +76,8 @@ def configure(conf): | |||
print('Using SSE optimization') | |||
optimization_flags.extend( [ | |||
"-msse2", | |||
"-mfpmath=sse", | |||
"-ftree-vectorize" ] ) | |||
"-mfpmath=sse" ] ); | |||
conf.define( 'USE_SSE', 1 ) | |||
debug_flags = [ '-O0', '-g3' ] | |||