summaryrefslogtreecommitdiff
path: root/apps/codecs/libgme/vgm_emu.c
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2011-08-17 22:20:09 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2011-08-17 22:20:09 +0000
commit4d01ace73fdffca366211157b54418516b3a73b6 (patch)
tree8165a373967a826ba67826b60f55911ac344c028 /apps/codecs/libgme/vgm_emu.c
parent4070f4f17b77a030049e146245fc9a399bb68204 (diff)
downloadrockbox-4d01ace73fdffca366211157b54418516b3a73b6.tar.gz
rockbox-4d01ace73fdffca366211157b54418516b3a73b6.zip
Submit a patch to the VGM codec by Mauricio Gama which saves some more RAM through changes of the buffer configuration and an update of the resampler code. Additionally enable VGM for low memory targets and update the manual.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30327 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libgme/vgm_emu.c')
-rw-r--r--apps/codecs/libgme/vgm_emu.c59
1 files changed, 19 insertions, 40 deletions
diff --git a/apps/codecs/libgme/vgm_emu.c b/apps/codecs/libgme/vgm_emu.c
index d599056bca..391bd02d73 100644
--- a/apps/codecs/libgme/vgm_emu.c
+++ b/apps/codecs/libgme/vgm_emu.c
@@ -89,8 +89,7 @@ void Vgm_init( struct Vgm_Emu* this )
89 Synth_init( &this->pcm ); 89 Synth_init( &this->pcm );
90 90
91 Buffer_init( &this->buf ); 91 Buffer_init( &this->buf );
92 Buffer_init( &this->stereo_buf ); 92 Blip_init( &this->blip_buf );
93 this->blip_buf = &this->stereo_buf.bufs [0];
94 93
95 // Init fm chips 94 // Init fm chips
96 Ym2413_init( &this->ym2413 ); 95 Ym2413_init( &this->ym2413 );
@@ -279,7 +278,7 @@ blargg_err_t Vgm_load_mem( struct Vgm_Emu* this, byte const* new_data, long new_
279 if ( !this->psg_rate ) 278 if ( !this->psg_rate )
280 this->psg_rate = 3579545; 279 this->psg_rate = 3579545;
281 280
282 Buffer_clock_rate( &this->stereo_buf, this->psg_rate ); 281 Blip_set_clock_rate( &this->blip_buf, this->psg_rate );
283 282
284 // Disable FM 283 // Disable FM
285 this->fm_rate = 0; 284 this->fm_rate = 0;
@@ -342,14 +341,14 @@ blargg_err_t setup_fm( struct Vgm_Emu* this )
342{ 341{
343 int fm_rate = 0; 342 int fm_rate = 0;
344 if ( !this->disable_oversampling ) 343 if ( !this->disable_oversampling )
345 this->fm_rate = (this->sample_rate * 3) / 2; // oversample factor = 1.5 344 fm_rate = (this->sample_rate * 3) / 2; // oversample factor = 1.5
346 RETURN_ERR( init_fm( this, &fm_rate ) ); 345 RETURN_ERR( init_fm( this, &fm_rate ) );
347 346
348 if ( uses_fm( this ) ) 347 if ( uses_fm( this ) )
349 { 348 {
350 this->voice_count = 8; 349 this->voice_count = 8;
351 RETURN_ERR( Resampler_setup( &this->resampler, fm_rate, fm_gain, this->sample_rate, this->gain ) ); 350 RETURN_ERR( Resampler_setup( &this->resampler, fm_rate, fm_gain, this->sample_rate, this->gain ) );
352 RETURN_ERR( Resampler_reset( &this->resampler, Buffer_length( &this->stereo_buf ) * this->sample_rate / 1000 ) ); 351 RETURN_ERR( Resampler_reset( &this->resampler, Blip_length( &this->blip_buf ) * this->sample_rate / 1000 ) );
353 Sms_apu_volume( &this->psg, ((this->gain/5)-(this->gain*5)/1000) * fm_gain ); 352 Sms_apu_volume( &this->psg, ((this->gain/5)-(this->gain*5)/1000) * fm_gain );
354 } 353 }
355 else 354 else
@@ -399,7 +398,7 @@ static blargg_err_t play_( struct Vgm_Emu* this, long count, sample_t* out )
399 return 0; 398 return 0;
400 } 399 }
401 400
402 Resampler_play( &this->resampler, count, out, &this->stereo_buf ); 401 Resampler_play( &this->resampler, count, out, &this->blip_buf );
403 return 0; 402 return 0;
404} 403}
405 404
@@ -428,19 +427,16 @@ static inline blip_time_t to_psg_time( struct Vgm_Emu* this, vgm_time_t t )
428 427
429static void write_pcm( struct Vgm_Emu* this, vgm_time_t vgm_time, int amp ) 428static void write_pcm( struct Vgm_Emu* this, vgm_time_t vgm_time, int amp )
430{ 429{
431 if ( this->blip_buf ) 430 check( amp >= 0 );
432 { 431 blip_time_t blip_time = to_psg_time( this, vgm_time );
433 check( amp >= 0 ); 432 int old = this->dac_amp;
434 blip_time_t blip_time = to_psg_time( this, vgm_time ); 433 int delta = amp - old;
435 int old = this->dac_amp; 434 this->dac_amp = amp;
436 int delta = amp - old; 435 Blip_set_modified( &this->blip_buf );
437 this->dac_amp = amp; 436 if ( old >= 0 ) // first write is ignored, to avoid click
438 Blip_set_modified( this->blip_buf ); 437 Synth_offset_inline( &this->pcm, blip_time, delta, &this->blip_buf );
439 if ( old >= 0 ) // first write is ignored, to avoid click 438 else
440 Synth_offset_inline( &this->pcm, blip_time, delta, this->blip_buf ); 439 this->dac_amp |= this->dac_disabled;
441 else
442 this->dac_amp |= this->dac_disabled;
443 }
444} 440}
445 441
446blip_time_t run( struct Vgm_Emu* this, vgm_time_t end_time ) 442blip_time_t run( struct Vgm_Emu* this, vgm_time_t end_time )
@@ -514,22 +510,7 @@ blip_time_t run( struct Vgm_Emu* this, vgm_time_t end_time )
514 510
515 case cmd_ym2612_port1: 511 case cmd_ym2612_port1:
516 if ( Ym2612_run_until( &this->ym2612, to_fm_time( this, vgm_time ) ) ) 512 if ( Ym2612_run_until( &this->ym2612, to_fm_time( this, vgm_time ) ) )
517 {
518 if ( pos [0] == ym2612_dac_pan_port )
519 {
520 struct Blip_Buffer* blip_buf = NULL;
521 switch ( pos [1] >> 6 )
522 {
523 case 0: blip_buf = NULL; break;
524 case 1: blip_buf = &this->stereo_buf.bufs [2]; break;
525 case 2: blip_buf = &this->stereo_buf.bufs [1]; break;
526 case 3: blip_buf = &this->stereo_buf.bufs [0]; break;
527 }
528 this->blip_buf = blip_buf;
529 }
530
531 Ym2612_write1( &this->ym2612, pos [0], pos [1] ); 513 Ym2612_write1( &this->ym2612, pos [0], pos [1] );
532 }
533 pos += 2; 514 pos += 2;
534 break; 515 break;
535 516
@@ -664,7 +645,7 @@ void update_fm_rates( struct Vgm_Emu* this, int* ym2413_rate, int* ym2612_rate )
664blargg_err_t Vgm_set_sample_rate( struct Vgm_Emu* this, long rate ) 645blargg_err_t Vgm_set_sample_rate( struct Vgm_Emu* this, long rate )
665{ 646{
666 require( !this->sample_rate ); // sample rate can't be changed once set 647 require( !this->sample_rate ); // sample rate can't be changed once set
667 RETURN_ERR( Buffer_set_sample_rate( &this->stereo_buf, rate, 1000 / 30 ) ); 648 RETURN_ERR( Blip_set_sample_rate( &this->blip_buf, rate, 1000 / 30 ) );
668 RETURN_ERR( Buffer_set_sample_rate( &this->buf, rate, 1000 / 20 ) ); 649 RETURN_ERR( Buffer_set_sample_rate( &this->buf, rate, 1000 / 20 ) );
669 650
670 // Set bass frequency 651 // Set bass frequency
@@ -712,7 +693,7 @@ void Sound_mute_voices( struct Vgm_Emu* this, int mask )
712 if ( uses_fm( this ) ) 693 if ( uses_fm( this ) )
713 { 694 {
714 for ( i = sms_osc_count; --i >= 0; ) 695 for ( i = sms_osc_count; --i >= 0; )
715 Sms_apu_set_output( &this->psg, i, ( mask & 0x80 ) ? 0 : &this->stereo_buf.bufs [0], NULL, NULL ); 696 Sms_apu_set_output( &this->psg, i, ( mask & 0x80 ) ? 0 : &this->blip_buf, NULL, NULL );
716 if ( Ym2612_enabled( &this->ym2612 ) ) 697 if ( Ym2612_enabled( &this->ym2612 ) )
717 { 698 {
718 Synth_volume( &this->pcm, (mask & 0x40) ? 0 : (int)((long long)(0.1115*FP_ONE_VOLUME) / 256 * fm_gain * this->gain / FP_ONE_VOLUME) ); 699 Synth_volume( &this->pcm, (mask & 0x40) ? 0 : (int)((long long)(0.1115*FP_ONE_VOLUME) / 256 * fm_gain * this->gain / FP_ONE_VOLUME) );
@@ -743,7 +724,7 @@ void Sound_set_tempo( struct Vgm_Emu* this, int t )
743 if ( this->file_begin ) 724 if ( this->file_begin )
744 { 725 {
745 this->vgm_rate = (long) ((44100LL * t) / FP_ONE_TEMPO); 726 this->vgm_rate = (long) ((44100LL * t) / FP_ONE_TEMPO);
746 this->blip_time_factor = (int) (((1LL << blip_time_bits) * Blip_clock_rate( &this->stereo_buf.bufs [0] )) / this->vgm_rate); 727 this->blip_time_factor = (int) (((1LL << blip_time_bits) * Blip_clock_rate( &this->blip_buf )) / this->vgm_rate);
747 //debug_printf( "blip_time_factor: %ld\n", blip_time_factor ); 728 //debug_printf( "blip_time_factor: %ld\n", blip_time_factor );
748 //debug_printf( "vgm_rate: %ld\n", vgm_rate ); 729 //debug_printf( "vgm_rate: %ld\n", vgm_rate );
749 // TODO: remove? calculates vgm_rate more accurately (above differs at most by one Hz only) 730 // TODO: remove? calculates vgm_rate more accurately (above differs at most by one Hz only)
@@ -761,8 +742,6 @@ blargg_err_t Vgm_start_track( struct Vgm_Emu* this )
761 742
762 Sms_apu_reset( &this->psg, get_le16( header( this )->noise_feedback ), header( this )->noise_width ); 743 Sms_apu_reset( &this->psg, get_le16( header( this )->noise_feedback ), header( this )->noise_width );
763 744
764 this->blip_buf = &this->stereo_buf.bufs [0];
765
766 this->dac_disabled = -1; 745 this->dac_disabled = -1;
767 this->pos = this->file_begin + header_size; 746 this->pos = this->file_begin + header_size;
768 this->pcm_data = this->pos; 747 this->pcm_data = this->pos;
@@ -785,7 +764,7 @@ blargg_err_t Vgm_start_track( struct Vgm_Emu* this )
785 if ( Ym2612_enabled( &this->ym2612 ) ) 764 if ( Ym2612_enabled( &this->ym2612 ) )
786 Ym2612_reset( &this->ym2612 ); 765 Ym2612_reset( &this->ym2612 );
787 766
788 Buffer_clear( &this->stereo_buf ); 767 Blip_clear( &this->blip_buf, 1 );
789 Resampler_clear( &this->resampler ); 768 Resampler_clear( &this->resampler );
790 } 769 }
791 770