comparison src/console/gme.cxx @ 341:986f098da058 trunk

[svn] - merge in blargg's changes
author nenolod
date Thu, 07 Dec 2006 15:20:41 -0800
parents fb513e10174e
children
comparison
equal deleted inserted replaced
340:9e5a7158fa80 341:986f098da058
1 // Game_Music_Emu 0.5.1. http://www.slack.net/~ant/ 1 // Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
2 2
3 #include "Music_Emu.h" 3 #include "Music_Emu.h"
4 4
5 #if !GME_DISABLE_STEREO_DEPTH
5 #include "Effects_Buffer.h" 6 #include "Effects_Buffer.h"
7 #endif
6 #include "blargg_endian.h" 8 #include "blargg_endian.h"
7 #include <string.h> 9 #include <string.h>
8 #include <ctype.h> 10 #include <ctype.h>
9 11
10 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you 12 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you
17 details. You should have received a copy of the GNU Lesser General Public 19 details. You should have received a copy of the GNU Lesser General Public
18 License along with this module; if not, write to the Free Software Foundation, 20 License along with this module; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 21 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
20 22
21 #include "blargg_source.h" 23 #include "blargg_source.h"
24
25 #ifndef GME_TYPE_LIST
26
27 // Default list of all supported game music types (copy this to blargg_config.h
28 // if you want to modify it)
29 #define GME_TYPE_LIST \
30 gme_ay_type,\
31 gme_gbs_type,\
32 gme_gym_type,\
33 gme_hes_type,\
34 gme_kss_type,\
35 gme_nsf_type,\
36 gme_nsfe_type,\
37 gme_sap_type,\
38 gme_spc_type,\
39 gme_vgm_type,\
40 gme_vgz_type
41
42 #endif
43
44 static gme_type_t const gme_type_list_ [] = { GME_TYPE_LIST, 0 };
45
46 gme_type_t const* gme_type_list()
47 {
48 return gme_type_list_;
49 }
22 50
23 const char* gme_identify_header( void const* header ) 51 const char* gme_identify_header( void const* header )
24 { 52 {
25 switch ( get_be32( header ) ) 53 switch ( get_be32( header ) )
26 { 54 {
47 return; 75 return;
48 } 76 }
49 *out = 0; // extension too long 77 *out = 0; // extension too long
50 } 78 }
51 79
52 gme_type_t gme_identify_extension( const char* extension_, gme_type_t const* types ) 80 gme_type_t gme_identify_extension( const char* extension_ )
53 { 81 {
54 char const* end = strrchr( extension_, '.' ); 82 char const* end = strrchr( extension_, '.' );
55 if ( end ) 83 if ( end )
56 extension_ = end + 1; 84 extension_ = end + 1;
57 85
58 char extension [6]; 86 char extension [6];
59 to_uppercase( extension_, sizeof extension, extension ); 87 to_uppercase( extension_, sizeof extension, extension );
60 88
61 for ( ; *types; types++ ) 89 for ( gme_type_t const* types = gme_type_list_; *types; types++ )
62 if ( !strcmp( extension, (*types)->extension_ ) ) 90 if ( !strcmp( extension, (*types)->extension_ ) )
63 return *types; 91 return *types;
64 return 0; 92 return 0;
65 } 93 }
66 94
67 gme_err_t gme_identify_file( const char* path, gme_type_t const* types, gme_type_t* type_out ) 95 gme_err_t gme_identify_file( const char* path, gme_type_t* type_out )
68 { 96 {
69 *type_out = gme_identify_extension( path, types ); 97 *type_out = gme_identify_extension( path );
98 // TODO: don't examine header if file has extension?
70 if ( !*type_out ) 99 if ( !*type_out )
71 { 100 {
72 char header [4] = { }; 101 char header [4];
73 GME_FILE_READER in; 102 GME_FILE_READER in;
74 RETURN_ERR( in.open( path ) ); 103 RETURN_ERR( in.open( path ) );
75 RETURN_ERR( in.read( header, sizeof header ) ); 104 RETURN_ERR( in.read( header, sizeof header ) );
76 *type_out = gme_identify_extension( gme_identify_header( header ), types ); 105 *type_out = gme_identify_extension( gme_identify_header( header ) );
77 } 106 }
78 return 0; 107 return 0;
79 } 108 }
80 109
110 gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, long sample_rate )
111 {
112 require( (data || !size) && out );
113 *out = 0;
114
115 gme_type_t file_type = 0;
116 if ( size >= 4 )
117 file_type = gme_identify_extension( gme_identify_header( data ) );
118 if ( !file_type )
119 return gme_wrong_file_type;
120
121 Music_Emu* emu = gme_new_emu( file_type, sample_rate );
122 CHECK_ALLOC( emu );
123
124 gme_err_t err = gme_load_data( emu, data, size );
125
126 if ( err )
127 delete emu;
128 else
129 *out = emu;
130
131 return err;
132 }
133
134 gme_err_t gme_open_file( const char* path, Music_Emu** out, long sample_rate )
135 {
136 require( path && out );
137 *out = 0;
138
139 GME_FILE_READER in;
140 RETURN_ERR( in.open( path ) );
141
142 char header [4];
143 int header_size = 0;
144
145 gme_type_t file_type = gme_identify_extension( path );
146 if ( !file_type )
147 {
148 header_size = sizeof header;
149 RETURN_ERR( in.read( header, sizeof header ) );
150 file_type = gme_identify_extension( gme_identify_header( header ) );
151 }
152 if ( !file_type )
153 return gme_wrong_file_type;
154
155 Music_Emu* emu = gme_new_emu( file_type, sample_rate );
156 CHECK_ALLOC( emu );
157
158 // optimization: avoids seeking/re-reading header
159 Remaining_Reader rem( header, header_size, &in );
160 gme_err_t err = emu->load( rem );
161 in.close();
162
163 if ( err )
164 delete emu;
165 else
166 *out = emu;
167
168 return err;
169 }
170
81 Music_Emu* gme_new_emu( gme_type_t type, long rate ) 171 Music_Emu* gme_new_emu( gme_type_t type, long rate )
82 { 172 {
83 if ( type ) 173 if ( type )
84 { 174 {
175 if ( rate == gme_info_only )
176 return type->new_info();
177
85 Music_Emu* me = type->new_emu(); 178 Music_Emu* me = type->new_emu();
86 if ( me ) 179 if ( me )
87 { 180 {
181 #if !GME_DISABLE_STEREO_DEPTH
88 if ( type->flags_ & 1 ) 182 if ( type->flags_ & 1 )
89 { 183 {
90 me->effects_buffer = BLARGG_NEW Effects_Buffer; 184 me->effects_buffer = BLARGG_NEW Effects_Buffer;
91 if ( me->effects_buffer ) 185 if ( me->effects_buffer )
92 me->set_buffer( me->effects_buffer ); 186 me->set_buffer( me->effects_buffer );
93 } 187 }
94 188
95 if ( !(type->flags_ & 1) || me->effects_buffer ) 189 if ( !(type->flags_ & 1) || me->effects_buffer )
190 #endif
96 { 191 {
97 if ( !me->set_sample_rate( rate ) ) 192 if ( !me->set_sample_rate( rate ) )
98 { 193 {
99 check( me->type() == type ); 194 check( me->type() == type );
100 return me; 195 return me;
104 } 199 }
105 } 200 }
106 return 0; 201 return 0;
107 } 202 }
108 203
109 Music_Emu* gme_new_info( gme_type_t type ) 204 gme_err_t gme_load_file( Music_Emu* me, const char* path ) { return me->load_file( path ); }
110 { 205
111 if ( !type ) 206 gme_err_t gme_load_data( Music_Emu* me, void const* data, long size )
112 return 0;
113
114 return type->new_info();
115 }
116
117 const char* gme_load_file( Music_Emu* me, const char* path ) { return me->load_file( path ); }
118
119 const char* gme_load_data( Music_Emu* me, const char* data, long size )
120 { 207 {
121 Mem_File_Reader in( data, size ); 208 Mem_File_Reader in( data, size );
122 return me->load( in ); 209 return me->load( in );
123 } 210 }
124 211
141 return me->track_info( out, track ); 228 return me->track_info( out, track );
142 } 229 }
143 230
144 void gme_set_stereo_depth( Music_Emu* me, double depth ) 231 void gme_set_stereo_depth( Music_Emu* me, double depth )
145 { 232 {
233 #if !GME_DISABLE_STEREO_DEPTH
146 if ( me->effects_buffer ) 234 if ( me->effects_buffer )
147 STATIC_CAST(Effects_Buffer*,me->effects_buffer)->set_depth( depth ); 235 STATIC_CAST(Effects_Buffer*,me->effects_buffer)->set_depth( depth );
148 } 236 #endif
149 237 }
150 gme_err_t gme_start_track( Music_Emu* me, int index ) { return me->start_track( index ); } 238
151 239 void* gme_user_data ( Music_Emu const* me ) { return me->user_data(); }
152 gme_err_t gme_play( Music_Emu* me, long n, short* p ) { return me->play( n, p ); } 240 void gme_set_user_data ( Music_Emu* me, void* new_user_data ) { me->set_user_data( new_user_data ); }
153 241 void gme_set_user_cleanup(Music_Emu* me, gme_user_cleanup_t func ) { me->set_user_cleanup( func ); }
154 void gme_set_fade( Music_Emu* me, long start_msec ) { me->set_fade( start_msec ); } 242
155 243 gme_err_t gme_start_track ( Music_Emu* me, int index ) { return me->start_track( index ); }
156 int gme_track_ended( Music_Emu const* me ) { return me->track_ended(); } 244 gme_err_t gme_play ( Music_Emu* me, long n, short* p ) { return me->play( n, p ); }
157 245 void gme_set_fade ( Music_Emu* me, long start_msec ) { me->set_fade( start_msec ); }
158 long gme_tell( Music_Emu const* me ) { return me->tell(); } 246 int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
159 247 long gme_tell ( Music_Emu const* me ) { return me->tell(); }
160 gme_err_t gme_seek( Music_Emu* me, long msec ) { return me->seek( msec ); } 248 gme_err_t gme_seek ( Music_Emu* me, long msec ) { return me->seek( msec ); }
161 249 int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
162 int gme_voice_count( Music_Emu const* me ) { return me->voice_count(); } 250 void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
163 251 void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }
164 const char** gme_voice_names( Music_Emu const* me ) { return me->voice_names(); } 252 void gme_mute_voice ( Music_Emu* me, int index, int mute ) { me->mute_voice( index, mute != 0 ); }
165 253 void gme_mute_voices ( Music_Emu* me, int mask ) { me->mute_voices( mask ); }
166 void gme_ignore_silence( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); } 254 void gme_set_equalizer ( Music_Emu* me, gme_equalizer_t const* eq ) { me->set_equalizer( *eq ); }
167 255 gme_equalizer_t gme_equalizer( Music_Emu const* me ) { return me->equalizer(); }
168 void gme_set_tempo( Music_Emu* me, double t ) { me->set_tempo( t ); } 256 const char** gme_voice_names ( Music_Emu const* me ) { return me->voice_names(); }
169
170 void gme_mute_voice( Music_Emu* me, int index, int mute ) { me->mute_voice( index, mute != 0 ); }
171
172 void gme_mute_voices( Music_Emu* me, int mask ) { me->mute_voices( mask ); }
173
174 gme_equalizer_t gme_equalizer( Music_Emu const* me ) { return me->equalizer(); }
175
176 void gme_set_equalizer( Music_Emu* me, gme_equalizer_t const* eq ) { me->set_equalizer( *eq ); }