f_cnt_t SampleBuffer::decodeSampleSF( const char * _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _samplerate ) { SNDFILE * snd_file; SF_INFO sf_info; f_cnt_t frames = 0; bool sf_rr = false; sample_t * fbuf = 0; if( ( snd_file = sf_open( _f, SFM_READ, &sf_info ) ) != NULL ) { frames = sf_info.frames; // check if float if ( (sf_info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_FLOAT ) // if yes, use float format for buffer { fbuf = new sample_t[sf_info.channels * frames]; sf_rr = sf_read_float( snd_file, fbuf, sf_info.channels * frames ); } else // otherwise, use int { _buf = new int_sample_t[sf_info.channels * frames]; sf_rr = sf_read_short( snd_file, _buf, sf_info.channels * frames ); } if( sf_rr < sf_info.channels * frames ) { #ifdef DEBUG_LMMS printf( "SampleBuffer::decodeSampleSF(): could not read" " sample %s: %s\n", _f, sf_strerror( NULL ) ); #endif } _channels = sf_info.channels; _samplerate = sf_info.samplerate; sf_close( snd_file ); } else { #ifdef DEBUG_LMMS printf( "SampleBuffer::decodeSampleSF(): could not load " "sample %s: %s\n", _f, sf_strerror( NULL ) ); #endif } //write down either directly or convert i->f depending on file type if ( frames > 0 && fbuf != NULL ) { directFloatWrite ( fbuf, frames, _channels); } else if ( frames > 0 && _buf != NULL ) { convertIntToFloat ( _buf, frames, _channels); } return frames; }
f_cnt_t SampleBuffer::decodeSampleDS( const char * _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _samplerate ) { DrumSynth ds; f_cnt_t frames = ds.GetDSFileSamples( _f, _buf, _channels, _samplerate ); if ( frames > 0 && _buf != NULL ) { convertIntToFloat ( _buf, frames, _channels); } return frames; }
f_cnt_t SampleBuffer::decodeSampleOGGVorbis( const char * _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _samplerate ) { static ov_callbacks callbacks = { qfileReadCallback, qfileSeekCallback, qfileCloseCallback, qfileTellCallback } ; OggVorbis_File vf; f_cnt_t frames = 0; QFile * f = new QFile( _f ); if( f->open( QFile::ReadOnly ) == false ) { delete f; return 0; } int err = ov_open_callbacks( f, &vf, NULL, 0, callbacks ); if( err < 0 ) { switch( err ) { case OV_EREAD: printf( "SampleBuffer::decodeSampleOGGVorbis():" " media read error\n" ); break; case OV_ENOTVORBIS: /* printf( "SampleBuffer::decodeSampleOGGVorbis():" " not an Ogg Vorbis file\n" );*/ break; case OV_EVERSION: printf( "SampleBuffer::decodeSampleOGGVorbis():" " vorbis version mismatch\n" ); break; case OV_EBADHEADER: printf( "SampleBuffer::decodeSampleOGGVorbis():" " invalid Vorbis bitstream header\n" ); break; case OV_EFAULT: printf( "SampleBuffer::decodeSampleOgg(): " "internal logic fault\n" ); break; } delete f; return 0; } ov_pcm_seek( &vf, 0 ); _channels = ov_info( &vf, -1 )->channels; _samplerate = ov_info( &vf, -1 )->rate; ogg_int64_t total = ov_pcm_total( &vf, -1 ); _buf = new int_sample_t[total * _channels]; int bitstream = 0; long bytes_read = 0; do { bytes_read = ov_read( &vf, (char *) &_buf[frames * _channels], ( total - frames ) * _channels * BYTES_PER_INT_SAMPLE, isLittleEndian() ? 0 : 1, BYTES_PER_INT_SAMPLE, 1, &bitstream ); if( bytes_read < 0 ) { break; } frames += bytes_read / ( _channels * BYTES_PER_INT_SAMPLE ); } while( bytes_read != 0 && bitstream == 0 ); ov_clear( &vf ); // if buffer isn't empty, convert it to float and write it down if ( frames > 0 && _buf != NULL ) { convertIntToFloat ( _buf, frames, _channels); } return frames; }