diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libgme/vgm_emu.h | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libgme/vgm_emu.h')
-rw-r--r-- | lib/rbcodec/codecs/libgme/vgm_emu.h | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libgme/vgm_emu.h b/lib/rbcodec/codecs/libgme/vgm_emu.h new file mode 100644 index 0000000000..8c39482008 --- /dev/null +++ b/lib/rbcodec/codecs/libgme/vgm_emu.h | |||
@@ -0,0 +1,206 @@ | |||
1 | // Sega Master System/Mark III, Sega Genesis/Mega Drive, BBC Micro VGM music file emulator | ||
2 | |||
3 | // Game_Music_Emu 0.6-pre | ||
4 | #ifndef VGM_EMU_H | ||
5 | #define VGM_EMU_H | ||
6 | |||
7 | #include "blargg_common.h" | ||
8 | #include "blargg_source.h" | ||
9 | |||
10 | #include "track_filter.h" | ||
11 | #include "resampler.h" | ||
12 | #include "multi_buffer.h" | ||
13 | #include "ym2413_emu.h" | ||
14 | #include "ym2612_emu.h" | ||
15 | #include "sms_apu.h" | ||
16 | |||
17 | typedef int vgm_time_t; | ||
18 | typedef int fm_time_t; | ||
19 | |||
20 | enum { fm_time_bits = 12 }; | ||
21 | enum { blip_time_bits = 12 }; | ||
22 | |||
23 | // VGM header format | ||
24 | enum { header_size = 0x40 }; | ||
25 | struct header_t | ||
26 | { | ||
27 | char tag [4]; | ||
28 | byte data_size [4]; | ||
29 | byte version [4]; | ||
30 | byte psg_rate [4]; | ||
31 | byte ym2413_rate [4]; | ||
32 | byte gd3_offset [4]; | ||
33 | byte track_duration [4]; | ||
34 | byte loop_offset [4]; | ||
35 | byte loop_duration [4]; | ||
36 | byte frame_rate [4]; | ||
37 | byte noise_feedback [2]; | ||
38 | byte noise_width; | ||
39 | byte unused1; | ||
40 | byte ym2612_rate [4]; | ||
41 | byte ym2151_rate [4]; | ||
42 | byte data_offset [4]; | ||
43 | byte unused2 [8]; | ||
44 | }; | ||
45 | |||
46 | enum { gme_max_field = 63 }; | ||
47 | struct track_info_t | ||
48 | { | ||
49 | /* times in milliseconds; -1 if unknown */ | ||
50 | int length; | ||
51 | int intro_length; | ||
52 | int loop_length; | ||
53 | |||
54 | /* empty string if not available */ | ||
55 | char game [64]; | ||
56 | char song [96]; | ||
57 | char author [64]; | ||
58 | }; | ||
59 | |||
60 | // Emulates VGM music using SN76489/SN76496 PSG, YM2612, and YM2413 FM sound chips. | ||
61 | // Supports custom sound buffer and frequency equalization when VGM uses just the PSG. | ||
62 | // FM sound chips can be run at their proper rates, or slightly higher to reduce | ||
63 | // aliasing on high notes. Currently YM2413 support requires that you supply a | ||
64 | // YM2413 sound chip emulator. I can provide one I've modified to work with the library. | ||
65 | struct Vgm_Emu { | ||
66 | int fm_rate; | ||
67 | int psg_rate; | ||
68 | int vgm_rate; | ||
69 | bool disable_oversampling; | ||
70 | |||
71 | int fm_time_offset; | ||
72 | int fm_time_factor; | ||
73 | |||
74 | int blip_time_factor; | ||
75 | |||
76 | byte const* file_begin; | ||
77 | byte const* file_end; | ||
78 | |||
79 | vgm_time_t vgm_time; | ||
80 | byte const* loop_begin; | ||
81 | byte const* pos; | ||
82 | |||
83 | byte const* pcm_data; | ||
84 | byte const* pcm_pos; | ||
85 | int dac_amp; | ||
86 | int dac_disabled; // -1 if disabled | ||
87 | |||
88 | // general | ||
89 | int current_track; | ||
90 | int clock_rate_; | ||
91 | unsigned buf_changed_count; | ||
92 | int max_initial_silence; | ||
93 | int voice_count; | ||
94 | int const *voice_types; | ||
95 | int mute_mask_; | ||
96 | int tempo; | ||
97 | int gain; | ||
98 | |||
99 | int sample_rate; | ||
100 | |||
101 | // larger items at the end | ||
102 | struct track_info_t info; | ||
103 | |||
104 | struct setup_t tfilter; | ||
105 | struct Track_Filter track_filter; | ||
106 | |||
107 | struct Ym2612_Emu ym2612; | ||
108 | struct Ym2413_Emu ym2413; | ||
109 | |||
110 | struct Sms_Apu psg; | ||
111 | struct Blip_Synth pcm; | ||
112 | struct Blip_Buffer blip_buf; | ||
113 | |||
114 | struct Resampler resampler; | ||
115 | struct Multi_Buffer stereo_buf; | ||
116 | }; | ||
117 | |||
118 | void Vgm_init( struct Vgm_Emu* this ); | ||
119 | |||
120 | // Disable running FM chips at higher than normal rate. Will result in slightly | ||
121 | // more aliasing of high notes. | ||
122 | static inline void Vgm_disable_oversampling( struct Vgm_Emu* this, bool disable ) { this->disable_oversampling = disable; } | ||
123 | |||
124 | // Header for currently loaded file | ||
125 | static inline struct header_t *header( struct Vgm_Emu* this ) { return (struct header_t*) this->file_begin; } | ||
126 | |||
127 | // Basic functionality (see Gme_File.h for file loading/track info functions) | ||
128 | blargg_err_t Vgm_load_mem( struct Vgm_Emu* this, byte const* new_data, long new_size, bool parse_info ); | ||
129 | |||
130 | // True if any FM chips are used by file. Always false until init_fm() | ||
131 | // is called. | ||
132 | static inline bool uses_fm( struct Vgm_Emu* this ) { return Ym2612_enabled( &this->ym2612 ) || Ym2413_enabled( &this->ym2413 ); } | ||
133 | |||
134 | // Set output sample rate. Must be called only once before loading file. | ||
135 | blargg_err_t Vgm_set_sample_rate( struct Vgm_Emu* this, int sample_rate ); | ||
136 | |||
137 | // Start a track, where 0 is the first track. Also clears warning string. | ||
138 | blargg_err_t Vgm_start_track( struct Vgm_Emu* this ); | ||
139 | |||
140 | // Generate 'count' samples info 'buf'. Output is in stereo. Any emulation | ||
141 | // errors set warning string, and major errors also end track. | ||
142 | blargg_err_t Vgm_play( struct Vgm_Emu* this, int count, sample_t* buf ); | ||
143 | |||
144 | // Track status/control | ||
145 | |||
146 | // Number of milliseconds (1000 msec = 1 second) played since beginning of track | ||
147 | int Track_tell( struct Vgm_Emu* this ); | ||
148 | |||
149 | // Seek to new time in track. Seeking backwards or far forward can take a while. | ||
150 | blargg_err_t Track_seek( struct Vgm_Emu* this, int msec ); | ||
151 | |||
152 | // Skip n samples | ||
153 | blargg_err_t Track_skip( struct Vgm_Emu* this, int n ); | ||
154 | |||
155 | // Set start time and length of track fade out. Once fade ends track_ended() returns | ||
156 | // true. Fade time can be changed while track is playing. | ||
157 | void Track_set_fade( struct Vgm_Emu* this, int start_msec, int length_msec ); | ||
158 | |||
159 | // True if a track has reached its end | ||
160 | static inline bool Track_ended( struct Vgm_Emu* this ) | ||
161 | { | ||
162 | return track_ended( &this->track_filter ); | ||
163 | } | ||
164 | |||
165 | // Disables automatic end-of-track detection and skipping of silence at beginning | ||
166 | static inline void Track_ignore_silence( struct Vgm_Emu* this, bool disable ) | ||
167 | { | ||
168 | this->track_filter.silence_ignored_ = disable; | ||
169 | } | ||
170 | |||
171 | // Get track length in milliseconds | ||
172 | static inline int Track_get_length( struct Vgm_Emu* this ) | ||
173 | { | ||
174 | int length = this->info.length; | ||
175 | if ( length <= 0 ) | ||
176 | { | ||
177 | length = this->info.intro_length + 2 * this->info.loop_length; // intro + 2 loops | ||
178 | if ( length <= 0 ) | ||
179 | length = 150 * 1000; // 2.5 minutes | ||
180 | } | ||
181 | |||
182 | return length; | ||
183 | } | ||
184 | |||
185 | // Sound customization | ||
186 | |||
187 | // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed. | ||
188 | // Track length as returned by track_info() assumes a tempo of 1.0. | ||
189 | void Sound_set_tempo( struct Vgm_Emu* this, int t ); | ||
190 | |||
191 | // Mute/unmute voice i, where voice 0 is first voice | ||
192 | void Sound_mute_voice( struct Vgm_Emu* this, int index, bool mute ); | ||
193 | |||
194 | // Set muting state of all voices at once using a bit mask, where -1 mutes them all, | ||
195 | // 0 unmutes them all, 0x01 mutes just the first voice, etc. | ||
196 | void Sound_mute_voices( struct Vgm_Emu* this, int mask ); | ||
197 | |||
198 | // Change overall output amplitude, where 1.0 results in minimal clamping. | ||
199 | // Must be called before set_sample_rate(). | ||
200 | static inline void Sound_set_gain( struct Vgm_Emu* this, int g ) | ||
201 | { | ||
202 | assert( !this->sample_rate ); // you must set gain before setting sample rate | ||
203 | this->gain = g; | ||
204 | } | ||
205 | |||
206 | #endif | ||