Finally get rid of that distortion issue.
This commit is contained in:
parent
ebb86a1e62
commit
3d2580dd64
|
@ -33,6 +33,7 @@ Audio_File_SF::from_file ( const char *filename )
|
||||||
SNDFILE *in;
|
SNDFILE *in;
|
||||||
SF_INFO si;
|
SF_INFO si;
|
||||||
|
|
||||||
|
|
||||||
Audio_File_SF *c = NULL;
|
Audio_File_SF *c = NULL;
|
||||||
|
|
||||||
memset( &si, 0, sizeof( si ) );
|
memset( &si, 0, sizeof( si ) );
|
||||||
|
@ -51,6 +52,7 @@ Audio_File_SF::from_file ( const char *filename )
|
||||||
|
|
||||||
c = new Audio_File_SF;
|
c = new Audio_File_SF;
|
||||||
|
|
||||||
|
c->_current_read = 0;
|
||||||
c->_filename = strdup( filename );
|
c->_filename = strdup( filename );
|
||||||
c->_length = si.frames;
|
c->_length = si.frames;
|
||||||
c->_channels = si.channels;
|
c->_channels = si.channels;
|
||||||
|
@ -90,7 +92,10 @@ Audio_File_SF::close ( void )
|
||||||
void
|
void
|
||||||
Audio_File_SF::seek ( nframes_t offset )
|
Audio_File_SF::seek ( nframes_t offset )
|
||||||
{
|
{
|
||||||
sf_seek( _in, offset, SEEK_SET );
|
if ( offset != _current_read )
|
||||||
|
{
|
||||||
|
sf_seek( _in, _current_read = offset, SEEK_SET );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if channels is -1, then all channels are read into buffer
|
/* if channels is -1, then all channels are read into buffer
|
||||||
|
@ -103,22 +108,26 @@ Audio_File_SF::read ( sample_t *buf, int channel, nframes_t len )
|
||||||
|
|
||||||
// printf( "len = %lu, channels = %d\n", len, _channels );
|
// printf( "len = %lu, channels = %d\n", len, _channels );
|
||||||
|
|
||||||
|
nframes_t rlen;
|
||||||
|
|
||||||
if ( _channels == 1 || channel == -1 )
|
if ( _channels == 1 || channel == -1 )
|
||||||
return sf_readf_float( _in, buf, len );
|
rlen = sf_readf_float( _in, buf, len );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sample_t *tmp = new sample_t[ len * _channels ];
|
sample_t *tmp = new sample_t[ len * _channels ];
|
||||||
|
|
||||||
nframes_t rlen = sf_readf_float( _in, tmp, len );
|
rlen = sf_readf_float( _in, tmp, len );
|
||||||
|
|
||||||
/* extract the requested channel */
|
/* extract the requested channel */
|
||||||
for ( int i = channel; i < rlen; i += _channels )
|
for ( int i = channel; i < rlen; i += _channels )
|
||||||
*(buf++) = tmp[ i ];
|
*(buf++) = tmp[ i ];
|
||||||
|
|
||||||
delete tmp;
|
delete tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
_current_read += rlen;
|
||||||
|
|
||||||
return rlen;
|
return rlen;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** read samples from /start/ to /end/ into /buf/ */
|
/** read samples from /start/ to /end/ into /buf/ */
|
||||||
|
|
|
@ -27,6 +27,10 @@ class Audio_File_SF : public Audio_File
|
||||||
|
|
||||||
SNDFILE *_in;
|
SNDFILE *_in;
|
||||||
|
|
||||||
|
/* used to avoid unnecessary seeking--libsndfile isn't smart
|
||||||
|
* enough to do this for us */
|
||||||
|
nframes_t _current_read;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static Audio_File_SF *from_file ( const char *filename );
|
static Audio_File_SF *from_file ( const char *filename );
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
#include "Port.H"
|
#include "Port.H"
|
||||||
|
|
||||||
// float Disk_Stream::seconds_to_buffer = 5.0f;
|
// float Disk_Stream::seconds_to_buffer = 5.0f;
|
||||||
float Disk_Stream::seconds_to_buffer = 1.0f;
|
float Disk_Stream::seconds_to_buffer = 5.0f;
|
||||||
|
// size_t Disk_Stream::disk_block_frames = 2048;
|
||||||
|
|
||||||
/* A Disk_Stream uses a separate I/O thread to stream a track's
|
/* A Disk_Stream uses a separate I/O thread to stream a track's
|
||||||
regions from disk into a ringbuffer, to be processed by the RT
|
regions from disk into a ringbuffer, to be processed by the RT
|
||||||
|
@ -48,6 +49,9 @@ Disk_Stream::Disk_Stream ( Track_Header *th, float frame_rate, nframes_t nframes
|
||||||
|
|
||||||
size_t bufsize = blocks * nframes * sizeof( sample_t );
|
size_t bufsize = blocks * nframes * sizeof( sample_t );
|
||||||
|
|
||||||
|
/* const int blocks = 64; */
|
||||||
|
/* const size_t bufsize = (blocks * (nframes * sizeof( sample_t ))) + sizeof( sample_t ); */
|
||||||
|
|
||||||
for ( int i = channels; i--; )
|
for ( int i = channels; i--; )
|
||||||
_rb.push_back( jack_ringbuffer_create( bufsize ) );
|
_rb.push_back( jack_ringbuffer_create( bufsize ) );
|
||||||
|
|
||||||
|
@ -151,6 +155,12 @@ Disk_Stream::io_thread ( void )
|
||||||
for ( unsigned int j = i; k < _nframes; j += channels() )
|
for ( unsigned int j = i; k < _nframes; j += channels() )
|
||||||
cbuf[ k++ ] = buf[ j ];
|
cbuf[ k++ ] = buf[ j ];
|
||||||
|
|
||||||
|
while ( jack_ringbuffer_write_space( _rb[ i ] ) < block_size )
|
||||||
|
{
|
||||||
|
printf( "IO: disk buffer overrun!\n" );
|
||||||
|
usleep( 2000 );
|
||||||
|
}
|
||||||
|
|
||||||
jack_ringbuffer_write( _rb[ i ], (char*)cbuf, block_size );
|
jack_ringbuffer_write( _rb[ i ], (char*)cbuf, block_size );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,15 +175,35 @@ Disk_Stream::io_thread ( void )
|
||||||
nframes_t
|
nframes_t
|
||||||
Disk_Stream::process ( nframes_t nframes )
|
Disk_Stream::process ( nframes_t nframes )
|
||||||
{
|
{
|
||||||
const size_t block_size = _nframes * sizeof( sample_t );
|
const size_t block_size = nframes * sizeof( sample_t );
|
||||||
|
|
||||||
|
// printf( "process: %lu %lu %lu\n", _frame, _frame + nframes, nframes );
|
||||||
|
|
||||||
for ( int i = channels(); i--; )
|
for ( int i = channels(); i--; )
|
||||||
{
|
{
|
||||||
void *buf = (_th->output)[ i ].buffer( _nframes );
|
|
||||||
|
void *buf = _th->output[ i ].buffer( nframes );
|
||||||
|
|
||||||
/* FIXME: handle underrun */
|
/* FIXME: handle underrun */
|
||||||
|
|
||||||
|
/* if ( jack_ringbuffer_read_space( _rb[ i ] ) < block_size ) */
|
||||||
|
/* { */
|
||||||
|
/* printf( "disktream (rt): buffer underrun!\n" ); */
|
||||||
|
/* memset( buf, 0, block_size ); */
|
||||||
|
/* } */
|
||||||
|
/* else */
|
||||||
|
|
||||||
if ( jack_ringbuffer_read( _rb[ i ], (char*)buf, block_size ) < block_size )
|
if ( jack_ringbuffer_read( _rb[ i ], (char*)buf, block_size ) < block_size )
|
||||||
printf( "disktream (rt): buffer underrun!\n" );
|
{
|
||||||
|
printf( "RT: buffer underrun (disk can't keep up).\n" );
|
||||||
|
memset( buf, 0, block_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* /\* testing. *\/ */
|
||||||
|
/* FILE *fp = fopen( "testing.au", "a" ); */
|
||||||
|
/* fwrite( buf, block_size, 1, fp ); */
|
||||||
|
/* fclose( fp ); */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block_processed();
|
block_processed();
|
||||||
|
|
|
@ -49,6 +49,8 @@ class Disk_Stream
|
||||||
|
|
||||||
sem_t _blocks; /* semaphore to wake the IO thread with */
|
sem_t _blocks; /* semaphore to wake the IO thread with */
|
||||||
|
|
||||||
|
// volatile nframes_t _seek_request;
|
||||||
|
|
||||||
int channels ( void ) const { return _rb.size(); }
|
int channels ( void ) const { return _rb.size(); }
|
||||||
|
|
||||||
Audio_Track * track ( void );
|
Audio_Track * track ( void );
|
||||||
|
|
|
@ -62,7 +62,6 @@ Engine::process ( nframes_t nframes )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* handle chicken/egg problem */
|
/* handle chicken/egg problem */
|
||||||
if ( timeline )
|
if ( timeline )
|
||||||
/* this will initiate the process() call graph for the various
|
/* this will initiate the process() call graph for the various
|
||||||
|
|
|
@ -30,7 +30,6 @@ public:
|
||||||
|
|
||||||
Mutex ( )
|
Mutex ( )
|
||||||
{
|
{
|
||||||
// _lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
|
||||||
pthread_mutex_init( &_lock, NULL );
|
pthread_mutex_init( &_lock, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,10 +50,10 @@ public:
|
||||||
pthread_mutex_unlock( &_lock );
|
pthread_mutex_unlock( &_lock );
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
bool
|
||||||
trylock ( void )
|
trylock ( void )
|
||||||
{
|
{
|
||||||
return pthread_mutex_trylock( &_lock );
|
return pthread_mutex_trylock( &_lock ) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue