1 /* C example that opens any music file type, opens an m3u playlist if present,
2 prints its info and voice names, customizes the sound, and fades a track out.
3 Records to "out.wav". */
4 
5 static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
6 static char playlist [] = "test.m3u"; /* uses this playlist, if present*/
7 
8 #include "gme/gme.h"
9 
10 #include "Wave_Writer.h" /* wave_ functions for writing sound file */
11 #include <stdlib.h>
12 #include <stdio.h>
13 
14 void handle_error( const char* );
15 
16 /* Example of loading from memory, which would be useful if using a zip file or
17 other custom format. In this example it's silly because we could just use
18 gme_load( &emu, sample_rate, path, 0 ).  */
load_file(const char * path,long sample_rate)19 Music_Emu* load_file( const char* path, long sample_rate )
20 {
21 	Music_Emu* emu;
22 	char* data;
23 	long  size;
24 
25 	/* Read file data into memory. You might read the data from a zip file or
26 	other compressed format. */
27 	FILE* in = fopen( path, "rb" );
28 	if ( !in )
29 		handle_error( "Couldn't open file" );
30 	fseek( in, 0, SEEK_END );
31 	size = ftell( in );
32 	rewind( in );
33 
34 	data = malloc( size );
35 	if ( !data )
36 		handle_error( "Out of memory" );
37 	if ( fread( data, size, 1, in ) <= 0 )
38 		handle_error( "Read error" );
39 	fclose( in );
40 
41 	handle_error( gme_open_data( data, size, &emu, sample_rate ) );
42 	free( data ); /* a copy is made of the data */
43 	return emu;
44 }
45 
46 /* Print any warning for most recent emulator action (load, start_track, play) */
print_warning(Music_Emu * emu)47 void print_warning( Music_Emu* emu )
48 {
49 	const char* warning = gme_warning( emu );
50 	if ( warning )
51 		printf( "**** Warning: %s\n\n", warning );
52 }
53 
54 static char my_data [] = "Our cleanup function was called";
55 
56 /* Example cleanup function automatically called when emulator is deleted. */
my_cleanup(void * my_data)57 static void my_cleanup( void* my_data )
58 {
59 	printf( "\n%s\n", (char*) my_data );
60 }
61 
main()62 int main()
63 {
64 	long sample_rate = 44100;
65 	int track = 0; /* index of track to play (0 = first) */
66 	int i;
67 
68 	/* Load file into emulator */
69 	Music_Emu* emu = load_file( filename, sample_rate );
70 	print_warning( emu );
71 
72 	/* Register cleanup function and confirmation string as data */
73 	gme_set_user_data( emu, my_data );
74 	gme_set_user_cleanup( emu, my_cleanup );
75 
76 	/* Load .m3u playlist file. All tracks are assumed to use current file.
77 	We ignore error here in case there is no m3u file present. */
78 	gme_load_m3u( emu, playlist );
79 	print_warning( emu );
80 
81 	/* Get and print main info for track */
82 	{
83 		gme_info_t* info;
84 		handle_error( gme_track_info( emu, &info, track ) );
85 
86 		printf( "System   : %s\n", info->system );
87 		printf( "Game     : %s\n", info->game );
88 		printf( "Author   : %s\n", info->author );
89 		printf( "Copyright: %s\n", info->copyright );
90 		printf( "Comment  : %s\n", info->comment );
91 		printf( "Dumper   : %s\n", info->dumper );
92 		printf( "Tracks   : %d\n", (int) gme_track_count( emu ) );
93 		printf( "\n" );
94 		printf( "Track    : %d\n", (int) track + 1 );
95 		printf( "Name     : %s\n", info->song );
96 		printf( "Length   : %ld:%02ld",
97 				(long) info->length / 1000 / 60, (long) info->length / 1000 % 60 );
98 		if ( info->loop_length != 0 )
99 			printf( " (endless)" );
100 		printf( "\n\n" );
101 
102 		gme_free_info( info );
103 	}
104 
105 	/* Print voice names */
106 	for ( i = 0; i < gme_voice_count( emu ); i++ )
107 		printf( "Voice %d: %s\n", i, gme_voice_name( emu, i ) );
108 
109 	/* Enable most accurate sound emulation */
110 	gme_enable_accuracy( emu, 1 );
111 
112 	/* Add some stereo enhancement */
113 	gme_set_stereo_depth( emu, 0.20 );
114 
115 	/* Adjust equalizer for crisp, bassy sound */
116 	{
117 		gme_equalizer_t eq;
118 		gme_equalizer( emu, &eq );
119 		eq.treble = 0.0;
120 		eq.bass   = 20;
121 		gme_set_equalizer( emu, &eq );
122 	}
123 
124 	/* Start track and begin fade at 10 seconds */
125 	handle_error( gme_start_track( emu, track ) );
126 	print_warning( emu );
127 	gme_set_fade( emu, 10 * 1000L );
128 
129 	/* Record track until it ends */
130 	wave_open( sample_rate, "out.wav" );
131 	wave_enable_stereo();
132 	while ( !gme_track_ended( emu ) )
133 	{
134 		#define buf_size 1024
135 		short buf [buf_size];
136 		handle_error( gme_play( emu, buf_size, buf ) );
137 		print_warning( emu );
138 		wave_write( buf, buf_size );
139 	}
140 
141 	/* Cleanup */
142 	gme_delete( emu );
143 	wave_close();
144 
145 	getchar();
146 	return 0;
147 }
148 
handle_error(const char * str)149 void handle_error( const char* str )
150 {
151 	if ( str )
152 	{
153 		printf( "Error: %s\n", str ); getchar();
154 		exit( EXIT_FAILURE );
155 	}
156 }
157