620
#ifdef HAVE_SAMPLERATE_H
621
588
void sampleBuffer::initResampling( void )
623
m_srcState = createResamplingContext();
624
590
m_srcData.end_of_input = 0;
630
void sampleBuffer::quitResampling( void )
632
destroyResamplingContext( m_srcState );
638
SRC_STATE * sampleBuffer::createResamplingContext( void )
642
if( ( state = src_new(/*
643
( eng()->getMixer()->highQuality() == TRUE ) ?
646
DEFAULT_CHANNELS, &error ) ) == NULL )
648
printf( "Error: src_new() failed in sample_buffer.cpp!\n" );
656
void sampleBuffer::destroyResamplingContext( SRC_STATE * _context )
658
src_delete( _context );
665
bool FASTCALL sampleBuffer::play( sampleFrame * _ab,
666
const f_cnt_t _start_frame,
667
const fpab_t _frames,
596
bool FASTCALL sampleBuffer::play( sampleFrame * _ab, handleState * _state,
668
598
const float _freq,
670
void * * _resampling_data )
672
eng()->getMixer()->clearAudioBuffer( _ab, _frames );
601
engine::getMixer()->clearAudioBuffer( _ab, _frames );
674
if( m_data == NULL || m_frames == 0 || m_endFrame == 0 || _frames == 0 )
603
if( m_endFrame == 0 || _frames == 0 )
679
const double freq_factor = (double) _freq / (double) BASE_FREQ;
680
const Sint16 freq_diff = static_cast<Sint16>( BASE_FREQ - _freq );
682
fpab_t frames_to_process = _frames;
608
const double freq_factor = (double) _freq / (double) m_frequency
609
* m_sample_rate / engine::getMixer()->sampleRate();
684
611
// calculate how many frames we have in requested pitch
685
612
const f_cnt_t total_frames_for_current_pitch = static_cast<f_cnt_t>( (
693
// do we have frames left?? this is only important when not in
694
// looping-mode because in looping-mode we loop to start-frame...
695
if( _start_frame >= total_frames_for_current_pitch && _looped == FALSE )
700
620
// this holds the number of the first frame to play
701
const f_cnt_t play_frame = m_startFrame + ( _start_frame %
702
total_frames_for_current_pitch );
621
f_cnt_t play_frame = _state->m_frame_index;
622
if( play_frame < m_startFrame )
624
play_frame = m_startFrame;
704
627
// this holds the number of remaining frames in current loop
705
f_cnt_t frames_for_loop = total_frames_for_current_pitch -
706
( play_frame - m_startFrame );
708
// make sure, data isn't accessed in any other way (e.g. deleting
709
// of this buffer...)
712
if( _looped == FALSE && frames_for_loop < frames_to_process )
714
frames_to_process = frames_for_loop;
716
const f_cnt_t f1 = static_cast<f_cnt_t>( m_startFrame +
717
( play_frame - m_startFrame ) * freq_factor );
721
f2 += frames_to_process * freq_factor;
723
if( f2 > f1 && f2 >= frames_to_process )
725
f2 -= frames_to_process * freq_factor;
727
// static int foo = 0;
728
// calc pointer of first frame
729
sampleFrame * start_frame = (sampleFrame *) m_data + f1;
730
//printf("diff:%d %f %d f2: %d input: %d\n", f2 -foo, play_frame * freq_factor, static_cast<Uint32>( play_frame * freq_factor ), f2, (Uint32)( frames_for_loop * freq_factor ) );
732
sampleFrame * loop_start = (sampleFrame *) m_data + m_startFrame;
628
f_cnt_t frames_for_loop;
631
play_frame = getLoopedIndex( play_frame );
632
frames_for_loop = static_cast<f_cnt_t>(
633
( m_loop_endFrame - play_frame ) /
638
if( play_frame >= m_endFrame )
642
frames_for_loop = static_cast<f_cnt_t>(
643
( m_endFrame - play_frame ) /
645
if( frames_for_loop == 0 )
734
651
// check whether we have to change pitch...
652
if( freq_factor != 1.0 || _state->m_varying_pitch )
737
#ifdef HAVE_SAMPLERATE_H
738
SRC_STATE * state = m_srcState;
739
if( _resampling_data != NULL )
741
if( _start_frame == 0 )
743
*_resampling_data = createResamplingContext();
745
state = static_cast<SRC_STATE *>( *_resampling_data );
749
if( _looped && frames_for_loop < frames_to_process )
751
f_cnt_t total_frames_copied = 0;
752
while( total_frames_copied < frames_to_process )
755
m_srcData.data_in = start_frame[0];
756
m_srcData.data_out = _ab[total_frames_copied];
757
m_srcData.input_frames = static_cast<f_cnt_t>(
758
frames_for_loop * freq_factor );
759
m_srcData.output_frames = frames_for_loop;
760
m_srcData.src_ratio = 1.0 / freq_factor;
761
int error = src_process( state, &m_srcData );
764
printf( "sampleBuffer: error while "
655
const f_cnt_t margin = 64;
656
f_cnt_t fragment_size = (f_cnt_t)( _frames * freq_factor )
658
m_srcData.data_in = getSampleFragment( play_frame,
659
fragment_size, _looped )[0];
660
m_srcData.data_out = _ab[0];
661
m_srcData.input_frames = fragment_size;
662
m_srcData.output_frames = _frames;
663
m_srcData.src_ratio = 1.0 / freq_factor;
664
int error = src_process( _state->m_resampling_data,
668
printf( "sampleBuffer: error while resampling: %s\n",
766
669
src_strerror( error ) );
769
total_frames_copied += frames_for_loop;
771
// reset start_frame to start
772
start_frame = loop_start;
773
// and calculate frames for next loop
774
frames_for_loop = frames_to_process
775
- total_frames_copied;
777
> total_frames_for_current_pitch )
780
total_frames_for_current_pitch;
787
m_srcData.data_in = start_frame[0];
788
m_srcData.data_out = _ab[0];
789
m_srcData.input_frames = static_cast<f_cnt_t>(
790
frames_for_loop * freq_factor );
791
m_srcData.output_frames = frames_to_process;
792
m_srcData.src_ratio = 1.0 / freq_factor;
793
int error = src_process( state, &m_srcData );
796
printf( "sampleBuffer: error while resampling: "
797
"%s\n", src_strerror( error ) );
801
f_cnt_t src_frame_base = 0;
802
// check whether we're in high-quality-mode
803
if( eng()->getMixer()->highQuality() == TRUE )
805
// we are, so let's use cubic interpolation...
806
for( f_cnt_t frame = 0; frame < frames_to_process;
809
// current loop done?
810
if( _looped && ( frame-src_frame_base ) >
813
start_frame = loop_start;
814
src_frame_base = frame;
815
frames_for_loop = frames_to_process %
816
total_frames_for_current_pitch;
819
const float src_frame_idx = frame * freq_factor;
820
f_cnt_t frame_num = static_cast<f_cnt_t>(
821
src_frame_idx) - src_frame_base;
822
const float frac_pos = src_frame_idx -
823
static_cast<f_cnt_t>( src_frame_idx );
825
// because of cubic interpolation we have to
826
// access start_frame[frame_num-1], so make
827
// sure we don't access data out of
828
// buffer-array-boundaries
829
if( frame_num == 0 && play_frame == 0 )
833
for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS;
836
_ab[frame][chnl] = cubicInterpolate(
837
start_frame[frame_num-1][chnl],
838
start_frame[frame_num+0][chnl],
839
start_frame[frame_num+1][chnl],
840
start_frame[frame_num+2][chnl],
847
// just normal mode, so we can use linear
849
for( f_cnt_t frame = 0; frame < frames_to_process;
852
if( _looped && ( frame - src_frame_base ) >
855
start_frame = loop_start;
856
src_frame_base = frame;
857
frames_for_loop = frames_to_process %
858
total_frames_for_current_pitch;
860
const float src_frame_idx = frame * freq_factor;
861
const f_cnt_t frame_num =
862
(f_cnt_t)src_frame_idx-src_frame_base;
863
const float frac_pos = src_frame_idx -
864
(f_cnt_t) src_frame_idx;
865
for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS;
868
_ab[frame][chnl] = linearInterpolate(
869
start_frame[frame_num][chnl],
870
start_frame[frame_num+1][chnl],
671
if( m_srcData.output_frames_gen != _frames )
673
printf( "sampleBuffer: not enough frames: %ld / %d\n",
674
m_srcData.output_frames_gen, _frames );
677
play_frame += m_srcData.input_frames_used;
680
play_frame = getLoopedIndex( play_frame );
879
685
// we don't have to pitch, so we just copy the sample-data
880
686
// as is into pitched-copy-buffer
883
if( _looped && frames_for_loop < frames_to_process )
885
f_cnt_t total_frames_copied = 0;
886
while( total_frames_copied < frames_to_process )
889
memcpy( _ab[total_frames_copied], start_frame,
890
frames_for_loop * BYTES_PER_FRAME );
892
total_frames_copied += frames_for_loop;
894
// reset start_frame to start
895
start_frame = loop_start;
896
// and calculate frames for next loop
897
frames_for_loop = frames_to_process
898
- total_frames_copied;
900
> total_frames_for_current_pitch )
903
total_frames_for_current_pitch;
910
memcpy( _ab, start_frame,
911
frames_to_process * BYTES_PER_FRAME );
689
memcpy( _ab, getSampleFragment( play_frame, _frames, _looped ),
690
_frames * BYTES_PER_FRAME );
692
play_frame += _frames;
695
play_frame = getLoopedIndex( play_frame );
915
m_dataMutex.unlock();
699
_state->m_frame_index = play_frame;
708
sampleFrame * sampleBuffer::getSampleFragment( f_cnt_t _start,
709
f_cnt_t _frames, bool _looped )
713
if( _start + _frames <= m_loop_endFrame )
715
return( m_data + _start );
720
if( _start + _frames <= m_endFrame )
722
return( m_data + _start );
726
delete[] m_sample_fragment;
727
m_sample_fragment = new sampleFrame[_frames];
731
f_cnt_t copied = m_loop_endFrame - _start;
732
memcpy( m_sample_fragment, m_data + _start, copied
734
f_cnt_t loop_frames = m_loop_endFrame - m_loop_startFrame;
735
while( _frames - copied > 0 )
737
f_cnt_t todo = tMin( _frames - copied, loop_frames );
738
memcpy( m_sample_fragment + copied,
739
m_data + m_loop_startFrame,
740
todo * BYTES_PER_FRAME );
746
f_cnt_t available = m_endFrame - _start;
747
memcpy( m_sample_fragment, m_data + _start, available
749
memset( m_sample_fragment + available, 0, ( _frames -
750
available ) * BYTES_PER_FRAME );
753
return( m_sample_fragment );
759
f_cnt_t sampleBuffer::getLoopedIndex( f_cnt_t _index )
761
if( _index < m_loop_endFrame )
765
return( m_loop_startFrame + ( _index - m_loop_startFrame )
766
% ( m_loop_endFrame - m_loop_startFrame ) );
924
772
void sampleBuffer::visualize( QPainter & _p, const QRect & _dr,
925
773
const QRect & _clip, drawMethods _dm )