diff demo/trim_spc.c @ 0:e38dacceb958

initial import
author Robert McIntyre <rlm@mit.edu>
date Fri, 21 Oct 2011 05:53:11 -0700
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/demo/trim_spc.c	Fri Oct 21 05:53:11 2011 -0700
     1.3 @@ -0,0 +1,83 @@
     1.4 +/* Trims silence off beginning of SPC file.
     1.5 +Requires the accurate DSP; won't compile with the fast DSP.
     1.6 +Please note that the algorithm could be improved; this is just
     1.7 +a simple example showing the idea.
     1.8 +
     1.9 +Usage: trim_spc [test.spc [trimmed.spc]]
    1.10 +*/
    1.11 +
    1.12 +#include "snes_spc/spc.h"
    1.13 +
    1.14 +#include "demo_util.h" /* error(), load_file() */
    1.15 +
    1.16 +/* Change to 1 to have it trim to next key on event rather than trim silence */
    1.17 +enum { use_kon_check = 0 };
    1.18 +
    1.19 +/* True if all count samples from in are silent (or very close to it) */
    1.20 +int is_silent( short const* in, int count );
    1.21 +
    1.22 +int main( int argc, char** argv )
    1.23 +{
    1.24 +	/* Load file into memory */
    1.25 +	long spc_size;
    1.26 +	void* spc = load_file( (argc > 1) ? argv [1] : "test.spc", &spc_size );
    1.27 +	
    1.28 +	/* Load into emulator */
    1.29 +	SNES_SPC* snes_spc = spc_new();
    1.30 +	if ( !snes_spc ) error( "Out of memory" );
    1.31 +	error( spc_load_spc( snes_spc, spc, spc_size ) );
    1.32 +	
    1.33 +	/* Expand SPC data so there's enough room for emulator to save to.
    1.34 +	We simply overwrite the emulator data in the old SPC file rather
    1.35 +	than creating new SPC data. This preserves the text tags from
    1.36 +	the old file. */
    1.37 +	if ( spc_size < spc_file_size )
    1.38 +	{
    1.39 +		spc_size = spc_file_size;
    1.40 +		spc = realloc( spc, spc_size ); /* leaks memory if allocation fails */
    1.41 +		if ( !spc ) error( "Out of memory" );
    1.42 +	}
    1.43 +	
    1.44 +	/* Keep saving SPC, then playing a little more. Once SPC becomes non-silent,
    1.45 +	write the SPC data saved just before this. */
    1.46 +	{
    1.47 +		long samples_trimmed = 0;
    1.48 +		while ( 1 )
    1.49 +		{
    1.50 +			#define BUF_SIZE 1024
    1.51 +			short buf [BUF_SIZE];
    1.52 +			
    1.53 +			if ( samples_trimmed > 10 * spc_sample_rate * 2 )
    1.54 +				error( "Excess silence found" );
    1.55 +			
    1.56 +			spc_clear_echo( snes_spc );
    1.57 +			spc_save_spc( snes_spc, spc );
    1.58 +			
    1.59 +			/* Fill buffer */
    1.60 +			error( spc_play( snes_spc, BUF_SIZE, buf ) );
    1.61 +			samples_trimmed += BUF_SIZE;
    1.62 +			
    1.63 +			/* See if SPC became non-silent */
    1.64 +			if ( use_kon_check ? spc_check_kon( snes_spc ) : !is_silent( buf, BUF_SIZE ) )
    1.65 +				break;
    1.66 +		}
    1.67 +		
    1.68 +		printf( "Trimmed %.1f seconds\n", (double) samples_trimmed / spc_sample_rate / 2 );
    1.69 +	}
    1.70 +	
    1.71 +	spc_delete( snes_spc );
    1.72 +	write_file( (argc > 2) ? argv [2] : "trimmed.spc", spc, spc_size );
    1.73 +	
    1.74 +	return 0;
    1.75 +}
    1.76 +
    1.77 +int is_silent( short const* in, int count )
    1.78 +{
    1.79 +	unsigned const threshold = 0x10;
    1.80 +	while ( count-- )
    1.81 +	{
    1.82 +		if ( (unsigned) (*in++ + threshold / 2) > threshold )
    1.83 +			return 0;
    1.84 +	}
    1.85 +	return 1;
    1.86 +}