PageRenderTime 29ms CodeModel.GetById 16ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/gme/Music_Emu.h

http://game-music-emu.googlecode.com/
C++ Header | 218 lines | 127 code | 46 blank | 45 comment | 0 complexity | 11f5ba716536716507d683c3b2329d8e MD5 | raw file
  1// Common interface to game music file emulators
  2
  3// Game_Music_Emu 0.5.5
  4#ifndef MUSIC_EMU_H
  5#define MUSIC_EMU_H
  6
  7#include "Gme_File.h"
  8class Multi_Buffer;
  9
 10struct Music_Emu : public Gme_File {
 11public:
 12// Basic functionality (see Gme_File.h for file loading/track info functions)
 13
 14	// Set output sample rate. Must be called only once before loading file.
 15	blargg_err_t set_sample_rate( long sample_rate );
 16	
 17	// Start a track, where 0 is the first track. Also clears warning string.
 18	blargg_err_t start_track( int );
 19	
 20	// Generate 'count' samples info 'buf'. Output is in stereo. Any emulation
 21	// errors set warning string, and major errors also end track.
 22	typedef short sample_t;
 23	blargg_err_t play( long count, sample_t* buf );
 24	
 25// Informational
 26	
 27	// Sample rate sound is generated at
 28	long sample_rate() const;
 29	
 30	// Index of current track or -1 if one hasn't been started
 31	int current_track() const;
 32	
 33	// Number of voices used by currently loaded file
 34	int voice_count() const;
 35	
 36	// Names of voices
 37	const char** voice_names() const;
 38	
 39// Track status/control
 40
 41	// Number of milliseconds (1000 msec = 1 second) played since beginning of track
 42	long tell() const;
 43	
 44	// Seek to new time in track. Seeking backwards or far forward can take a while.
 45	blargg_err_t seek( long msec );
 46	
 47	// Skip n samples
 48	blargg_err_t skip( long n );
 49	
 50	// True if a track has reached its end
 51	bool track_ended() const;
 52	
 53	// Set start time and length of track fade out. Once fade ends track_ended() returns
 54	// true. Fade time can be changed while track is playing.
 55	void set_fade( long start_msec, long length_msec = 8000 );
 56	
 57	// Disable automatic end-of-track detection and skipping of silence at beginning
 58	void ignore_silence( bool disable = true );
 59	
 60	// Info for current track
 61	Gme_File::track_info;
 62	blargg_err_t track_info( track_info_t* out ) const;
 63	
 64// Sound customization
 65	
 66	// Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
 67	// Track length as returned by track_info() assumes a tempo of 1.0.
 68	void set_tempo( double );
 69	
 70	// Mute/unmute voice i, where voice 0 is first voice
 71	void mute_voice( int index, bool mute = true );
 72	
 73	// Set muting state of all voices at once using a bit mask, where -1 mutes them all,
 74	// 0 unmutes them all, 0x01 mutes just the first voice, etc.
 75	void mute_voices( int mask );
 76	
 77	// Change overall output amplitude, where 1.0 results in minimal clamping.
 78	// Must be called before set_sample_rate().
 79	void set_gain( double );
 80	
 81	// Request use of custom multichannel buffer. Only supported by "classic" emulators;
 82	// on others this has no effect. Should be called only once *before* set_sample_rate().
 83	virtual void set_buffer( Multi_Buffer* ) { }
 84	
 85	// Enables/disables accurate emulation options, if any are supported. Might change
 86	// equalizer settings.
 87	void enable_accuracy( bool enable = true );
 88	
 89// Sound equalization (treble/bass)
 90
 91	// Frequency equalizer parameters (see gme.txt)
 92	// See gme.h for definition of struct gme_equalizer_t.
 93	typedef gme_equalizer_t equalizer_t;
 94	
 95	// Current frequency equalizater parameters
 96	equalizer_t const& equalizer() const;
 97	
 98	// Set frequency equalizer parameters
 99	void set_equalizer( equalizer_t const& );
100	
101	// Equalizer settings for TV speaker
102	static equalizer_t const tv_eq;
103	
104public:
105	Music_Emu();
106	~Music_Emu();
107protected:
108	void set_max_initial_silence( int n )       { max_initial_silence = n; }
109	void set_silence_lookahead( int n )         { silence_lookahead = n; }
110	void set_voice_count( int n )               { voice_count_ = n; }
111	void set_voice_names( const char* const* names );
112	void set_track_ended()                      { emu_track_ended_ = true; }
113	double gain() const                         { return gain_; }
114	double tempo() const                        { return tempo_; }
115	void remute_voices();
116	
117	virtual blargg_err_t set_sample_rate_( long sample_rate ) = 0;
118	virtual void set_equalizer_( equalizer_t const& ) { }
119	virtual void enable_accuracy_( bool enable ) { }
120	virtual void mute_voices_( int mask ) = 0;
121	virtual void set_tempo_( double ) = 0;
122	virtual blargg_err_t start_track_( int ) = 0; // tempo is set before this
123	virtual blargg_err_t play_( long count, sample_t* out ) = 0;
124	virtual blargg_err_t skip_( long count );
125protected:
126	virtual void unload();
127	virtual void pre_load();
128	virtual void post_load_();
129private:
130	// general
131	equalizer_t equalizer_;
132	int max_initial_silence;
133	const char** voice_names_;
134	int voice_count_;
135	int mute_mask_;
136	double tempo_;
137	double gain_;
138	
139	long sample_rate_;
140	blargg_long msec_to_samples( blargg_long msec ) const;
141	
142	// track-specific
143	int current_track_;
144	blargg_long out_time;  // number of samples played since start of track
145	blargg_long emu_time;  // number of samples emulator has generated since start of track
146	bool emu_track_ended_; // emulator has reached end of track
147	volatile bool track_ended_;
148	void clear_track_vars();
149	void end_track_if_error( blargg_err_t );
150	
151	// fading
152	blargg_long fade_start;
153	int fade_step;
154	void handle_fade( long count, sample_t* out );
155	
156	// silence detection
157	int silence_lookahead; // speed to run emulator when looking ahead for silence
158	bool ignore_silence_;
159	long silence_time;     // number of samples where most recent silence began
160	long silence_count;    // number of samples of silence to play before using buf
161	long buf_remain;       // number of samples left in silence buffer
162	enum { buf_size = 2048 };
163	blargg_vector<sample_t> buf;
164	void fill_buf();
165	void emu_play( long count, sample_t* out );
166	
167	Multi_Buffer* effects_buffer;
168	friend Music_Emu* gme_new_emu( gme_type_t, int );
169	friend void gme_set_stereo_depth( Music_Emu*, double );
170};
171
172// base class for info-only derivations
173struct Gme_Info_ : Music_Emu
174{
175	virtual blargg_err_t set_sample_rate_( long sample_rate );
176	virtual void set_equalizer_( equalizer_t const& );
177	virtual void enable_accuracy_( bool );
178	virtual void mute_voices_( int mask );
179	virtual void set_tempo_( double );
180	virtual blargg_err_t start_track_( int );
181	virtual blargg_err_t play_( long count, sample_t* out );
182	virtual void pre_load();
183	virtual void post_load_();
184};
185
186inline blargg_err_t Music_Emu::track_info( track_info_t* out ) const
187{
188	return track_info( out, current_track_ );
189}
190
191inline long Music_Emu::sample_rate() const          { return sample_rate_; }
192inline const char** Music_Emu::voice_names() const  { return voice_names_; }
193inline int Music_Emu::voice_count() const           { return voice_count_; }
194inline int Music_Emu::current_track() const         { return current_track_; }
195inline bool Music_Emu::track_ended() const          { return track_ended_; }
196inline const Music_Emu::equalizer_t& Music_Emu::equalizer() const { return equalizer_; }
197
198inline void Music_Emu::enable_accuracy( bool b )    { enable_accuracy_( b ); }
199inline void Music_Emu::set_tempo_( double t )       { tempo_ = t; }
200inline void Music_Emu::remute_voices()              { mute_voices( mute_mask_ ); }
201inline void Music_Emu::ignore_silence( bool b )     { ignore_silence_ = b; }
202inline blargg_err_t Music_Emu::start_track_( int )  { return 0; }
203
204inline void Music_Emu::set_voice_names( const char* const* names )
205{
206	// Intentional removal of const, so users don't have to remember obscure const in middle
207	voice_names_ = const_cast<const char**> (names);
208}
209
210inline void Music_Emu::mute_voices_( int ) { }
211
212inline void Music_Emu::set_gain( double g )
213{
214	assert( !sample_rate() ); // you must set gain before setting sample rate
215	gain_ = g;
216}
217
218#endif