Browse Source

Finally get rid of that distortion issue.

tags/non-daw-v1.1.0
Jonathan Moore Liles 17 years ago
parent
commit
3d2580dd64
6 changed files with 57 additions and 14 deletions
  1. +14
    -5
      Timeline/Audio_File_SF.C
  2. +4
    -0
      Timeline/Audio_File_SF.H
  3. +35
    -5
      Timeline/Disk_Stream.C
  4. +2
    -0
      Timeline/Disk_Stream.H
  5. +0
    -1
      Timeline/Engine.C
  6. +2
    -3
      Timeline/Mutex.H

+ 14
- 5
Timeline/Audio_File_SF.C View File

@@ -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;

return rlen;
} }

_current_read += rlen;

return rlen;
} }


/** read samples from /start/ to /end/ into /buf/ */ /** read samples from /start/ to /end/ into /buf/ */


+ 4
- 0
Timeline/Audio_File_SF.H View File

@@ -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 );


+ 35
- 5
Timeline/Disk_Stream.C View File

@@ -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 );
} }
} }
@@ -161,19 +171,39 @@ Disk_Stream::io_thread ( void )


/* THREAD: RT */ /* THREAD: RT */
/** take a block from the ringbuffers and send it out the track's /** take a block from the ringbuffers and send it out the track's
* ports */
* ports */
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();


+ 2
- 0
Timeline/Disk_Stream.H View File

@@ -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 );


+ 0
- 1
Timeline/Engine.C View File

@@ -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


+ 2
- 3
Timeline/Mutex.H View File

@@ -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…
Cancel
Save