mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-24 21:31:46 +00:00
157 lines
4.2 KiB
C
157 lines
4.2 KiB
C
|
/* C example that opens any music file type, opens an m3u playlist if present,
|
||
|
prints its info and voice names, customizes the sound, and fades a track out.
|
||
|
Records to "out.wav". */
|
||
|
|
||
|
static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
|
||
|
static char playlist [] = "test.m3u"; /* uses this playlist, if present*/
|
||
|
|
||
|
#include "gme/gme.h"
|
||
|
|
||
|
#include "Wave_Writer.h" /* wave_ functions for writing sound file */
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
void handle_error( const char* );
|
||
|
|
||
|
/* Example of loading from memory, which would be useful if using a zip file or
|
||
|
other custom format. In this example it's silly because we could just use
|
||
|
gme_load( &emu, sample_rate, path, 0 ). */
|
||
|
Music_Emu* load_file( const char* path, long sample_rate )
|
||
|
{
|
||
|
Music_Emu* emu;
|
||
|
char* data;
|
||
|
long size;
|
||
|
|
||
|
/* Read file data into memory. You might read the data from a zip file or
|
||
|
other compressed format. */
|
||
|
FILE* in = fopen( path, "rb" );
|
||
|
if ( !in )
|
||
|
handle_error( "Couldn't open file" );
|
||
|
fseek( in, 0, SEEK_END );
|
||
|
size = ftell( in );
|
||
|
rewind( in );
|
||
|
|
||
|
data = malloc( size );
|
||
|
if ( !data )
|
||
|
handle_error( "Out of memory" );
|
||
|
if ( fread( data, size, 1, in ) <= 0 )
|
||
|
handle_error( "Read error" );
|
||
|
fclose( in );
|
||
|
|
||
|
handle_error( gme_open_data( data, size, &emu, sample_rate ) );
|
||
|
free( data ); /* a copy is made of the data */
|
||
|
return emu;
|
||
|
}
|
||
|
|
||
|
/* Print any warning for most recent emulator action (load, start_track, play) */
|
||
|
void print_warning( Music_Emu* emu )
|
||
|
{
|
||
|
const char* warning = gme_warning( emu );
|
||
|
if ( warning )
|
||
|
printf( "**** Warning: %s\n\n", warning );
|
||
|
}
|
||
|
|
||
|
static char my_data [] = "Our cleanup function was called";
|
||
|
|
||
|
/* Example cleanup function automatically called when emulator is deleted. */
|
||
|
static void my_cleanup( void* my_data )
|
||
|
{
|
||
|
printf( "\n%s\n", (char*) my_data );
|
||
|
}
|
||
|
|
||
|
int main()
|
||
|
{
|
||
|
long sample_rate = 44100;
|
||
|
int track = 0; /* index of track to play (0 = first) */
|
||
|
int i;
|
||
|
|
||
|
/* Load file into emulator */
|
||
|
Music_Emu* emu = load_file( filename, sample_rate );
|
||
|
print_warning( emu );
|
||
|
|
||
|
/* Register cleanup function and confirmation string as data */
|
||
|
gme_set_user_data( emu, my_data );
|
||
|
gme_set_user_cleanup( emu, my_cleanup );
|
||
|
|
||
|
/* Load .m3u playlist file. All tracks are assumed to use current file.
|
||
|
We ignore error here in case there is no m3u file present. */
|
||
|
gme_load_m3u( emu, playlist );
|
||
|
print_warning( emu );
|
||
|
|
||
|
/* Get and print main info for track */
|
||
|
{
|
||
|
gme_info_t* info;
|
||
|
handle_error( gme_track_info( emu, &info, track ) );
|
||
|
|
||
|
printf( "System : %s\n", info->system );
|
||
|
printf( "Game : %s\n", info->game );
|
||
|
printf( "Author : %s\n", info->author );
|
||
|
printf( "Copyright: %s\n", info->copyright );
|
||
|
printf( "Comment : %s\n", info->comment );
|
||
|
printf( "Dumper : %s\n", info->dumper );
|
||
|
printf( "Tracks : %d\n", (int) gme_track_count( emu ) );
|
||
|
printf( "\n" );
|
||
|
printf( "Track : %d\n", (int) track + 1 );
|
||
|
printf( "Name : %s\n", info->song );
|
||
|
printf( "Length : %ld:%02ld",
|
||
|
(long) info->length / 1000 / 60, (long) info->length / 1000 % 60 );
|
||
|
if ( info->loop_length != 0 )
|
||
|
printf( " (endless)" );
|
||
|
printf( "\n\n" );
|
||
|
|
||
|
gme_free_info( info );
|
||
|
}
|
||
|
|
||
|
/* Print voice names */
|
||
|
for ( i = 0; i < gme_voice_count( emu ); i++ )
|
||
|
printf( "Voice %d: %s\n", i, gme_voice_name( emu, i ) );
|
||
|
|
||
|
/* Enable most accurate sound emulation */
|
||
|
gme_enable_accuracy( emu, 1 );
|
||
|
|
||
|
/* Add some stereo enhancement */
|
||
|
gme_set_stereo_depth( emu, 0.20 );
|
||
|
|
||
|
/* Adjust equalizer for crisp, bassy sound */
|
||
|
{
|
||
|
gme_equalizer_t eq;
|
||
|
gme_equalizer( emu, &eq );
|
||
|
eq.treble = 0.0;
|
||
|
eq.bass = 20;
|
||
|
gme_set_equalizer( emu, &eq );
|
||
|
}
|
||
|
|
||
|
/* Start track and begin fade at 10 seconds */
|
||
|
handle_error( gme_start_track( emu, track ) );
|
||
|
print_warning( emu );
|
||
|
gme_set_fade( emu, 10 * 1000L );
|
||
|
|
||
|
/* Record track until it ends */
|
||
|
wave_open( sample_rate, "out.wav" );
|
||
|
wave_enable_stereo();
|
||
|
while ( !gme_track_ended( emu ) )
|
||
|
{
|
||
|
#define buf_size 1024
|
||
|
short buf [buf_size];
|
||
|
handle_error( gme_play( emu, buf_size, buf ) );
|
||
|
print_warning( emu );
|
||
|
wave_write( buf, buf_size );
|
||
|
}
|
||
|
|
||
|
/* Cleanup */
|
||
|
gme_delete( emu );
|
||
|
wave_close();
|
||
|
|
||
|
getchar();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void handle_error( const char* str )
|
||
|
{
|
||
|
if ( str )
|
||
|
{
|
||
|
printf( "Error: %s\n", str ); getchar();
|
||
|
exit( EXIT_FAILURE );
|
||
|
}
|
||
|
}
|