summaryrefslogtreecommitdiff
path: root/apps/codecs/libgme/kss_emu.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libgme/kss_emu.h')
-rw-r--r--apps/codecs/libgme/kss_emu.h228
1 files changed, 228 insertions, 0 deletions
diff --git a/apps/codecs/libgme/kss_emu.h b/apps/codecs/libgme/kss_emu.h
new file mode 100644
index 0000000000..81db2ae708
--- /dev/null
+++ b/apps/codecs/libgme/kss_emu.h
@@ -0,0 +1,228 @@
1// MSX computer KSS music file emulator
2
3// Game_Music_Emu 0.5.5
4#ifndef KSS_EMU_H
5#define KSS_EMU_H
6
7#include "gme.h"
8#include "blargg_common.h"
9
10#include "rom_data.h"
11#include "multi_buffer.h"
12
13#include "kss_scc_apu.h"
14#include "z80_cpu.h"
15#include "sms_apu.h"
16#include "ay_apu.h"
17#include "opl_apu.h"
18#include "m3u_playlist.h"
19
20typedef short sample_t;
21typedef int kss_time_t;
22typedef int kss_addr_t;
23typedef struct Z80_Cpu Kss_Cpu;
24
25// Sound chip flags
26enum {
27 sms_psg_flag = 1 << 0,
28 sms_fm_flag = 1 << 1,
29 msx_psg_flag = 1 << 2,
30 msx_scc_flag = 1 << 3,
31 msx_music_flag = 1 << 4,
32 msx_audio_flag = 1 << 5
33};
34
35enum { idle_addr = 0xFFFF };
36enum { scc_enabled_true = 0xC000 };
37enum { mem_size = 0x10000 };
38enum { buf_size = 2048 };
39
40// KSS file header
41enum { header_size = 0x20 };
42enum { header_base_size = 0x10 };
43enum { header_ext_size = header_size - header_base_size };
44
45struct header_t
46{
47 byte tag [4];
48 byte load_addr [2];
49 byte load_size [2];
50 byte init_addr [2];
51 byte play_addr [2];
52 byte first_bank;
53 byte bank_mode;
54 byte extra_header;
55 byte device_flags;
56
57 // KSSX extended data, if extra_header==0x10
58 byte data_size [4];
59 byte unused [4];
60 byte first_track [2];
61 byte last_track [2]; // if no extended data, we set this to 0xFF
62 byte psg_vol;
63 byte scc_vol;
64 byte msx_music_vol;
65 byte msx_audio_vol;
66};
67
68struct sms_t {
69 struct Sms_Apu psg;
70 struct Opl_Apu fm;
71};
72
73struct msx_t {
74 struct Ay_Apu psg;
75 struct Scc_Apu scc;
76 struct Opl_Apu music;
77 struct Opl_Apu audio;
78};
79
80struct Kss_Emu {
81 struct header_t header;
82
83 int chip_flags;
84 bool scc_accessed;
85 bool gain_updated;
86
87 int track_count;
88
89 unsigned scc_enabled; // 0 or 0xC000
90 int bank_count;
91
92 blip_time_t play_period;
93 blip_time_t next_play;
94 int ay_latch;
95
96 // general
97 int max_initial_silence;
98 int voice_count;
99 int mute_mask_;
100 double tempo;
101 double gain;
102
103 long sample_rate;
104
105 // track-specific
106 int current_track;
107 blargg_long out_time; // number of samples played since start of track
108 blargg_long emu_time; // number of samples emulator has generated since start of track
109 bool emu_track_ended_; // emulator has reached end of track
110 volatile bool track_ended;
111
112 // fading
113 blargg_long fade_start;
114 int fade_step;
115
116 // silence detection
117 int silence_lookahead; // speed to run emulator when looking ahead for silence
118 bool ignore_silence;
119 long silence_time; // number of samples where most recent silence began
120 long silence_count; // number of samples of silence to play before using buf
121 long buf_remain; // number of samples left in silence buffer
122
123 struct Stereo_Buffer stereo_buffer; // NULL if using custom buffer
124 long clock_rate_;
125 unsigned buf_changed_count;
126
127 // M3u Playlist
128 struct M3u_Playlist m3u;
129
130 // large items
131 sample_t buf [buf_size];
132
133 struct sms_t sms;
134 struct msx_t msx;
135
136 Kss_Cpu cpu;
137 struct Rom_Data rom;
138
139 byte unmapped_read [0x100];
140 byte unmapped_write [page_size];
141 byte ram [mem_size + cpu_padding];
142};
143
144// Basic functionality (see Gme_File.h for file loading/track info functions)
145
146void Kss_init( struct Kss_Emu* this );
147blargg_err_t Kss_load_mem( struct Kss_Emu* this, const void* data, long size );
148blargg_err_t end_frame( struct Kss_Emu* this, kss_time_t );
149
150// Set output sample rate. Must be called only once before loading file.
151blargg_err_t Kss_set_sample_rate( struct Kss_Emu* this, long sample_rate );
152
153// Start a track, where 0 is the first track. Also clears warning string.
154blargg_err_t Kss_start_track( struct Kss_Emu* this, int track );
155
156// Generate 'count' samples info 'buf'. Output is in stereo. Any emulation
157// errors set warning string, and major errors also end track.
158blargg_err_t Kss_play( struct Kss_Emu* this, long count, sample_t* buf ) ICODE_ATTR;
159
160// Track status/control
161
162// Number of milliseconds (1000 msec = 1 second) played since beginning of track
163long Track_tell( struct Kss_Emu* this );
164
165// Seek to new time in track. Seeking backwards or far forward can take a while.
166blargg_err_t Track_seek( struct Kss_Emu* this, long msec );
167
168// Skip n samples
169blargg_err_t Track_skip( struct Kss_Emu* this, long n );
170
171// Set start time and length of track fade out. Once fade ends track_ended() returns
172// true. Fade time can be changed while track is playing.
173void Track_set_fade( struct Kss_Emu* this, long start_msec, long length_msec );
174
175// Get track length in milliseconds
176static inline long Track_get_length( struct Kss_Emu* this, int n )
177{
178 long length = 0;
179
180 if ( (this->m3u.size > 0) && (n < this->m3u.size) ) {
181 struct entry_t* entry = &this->m3u.entries [n];
182 length = entry->length;
183 }
184
185 if ( length <= 0 )
186 length = 120 * 1000; /* 2 minutes */
187
188 return length;
189}
190
191// Sound customization
192
193// Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
194// Track length as returned by track_info() assumes a tempo of 1.0.
195void Sound_set_tempo( struct Kss_Emu* this, double t );
196
197// Mute/unmute voice i, where voice 0 is first voice
198void Sound_mute_voice( struct Kss_Emu* this, int index, bool mute );
199
200// Set muting state of all voices at once using a bit mask, where -1 mutes them all,
201// 0 unmutes them all, 0x01 mutes just the first voice, etc.
202void Sound_mute_voices( struct Kss_Emu* this, int mask );
203
204// Change overall output amplitude, where 1.0 results in minimal clamping.
205// Must be called before set_sample_rate().
206static inline void Sound_set_gain( struct Kss_Emu* this, double g )
207{
208 assert( !this->sample_rate ); // you must set gain before setting sample rate
209 this->gain = g;
210}
211
212// Emulation (You shouldn't touch these
213void cpu_write( struct Kss_Emu* this, kss_addr_t, int ) ICODE_ATTR;
214int cpu_in( struct Kss_Emu* this, kss_time_t, kss_addr_t ) ICODE_ATTR;
215void cpu_out( struct Kss_Emu* this, kss_time_t, kss_addr_t, int ) ICODE_ATTR;
216
217void cpu_write_( struct Kss_Emu* this, kss_addr_t addr, int data ) ICODE_ATTR;
218bool run_cpu( struct Kss_Emu* this, kss_time_t end ) ICODE_ATTR;
219void jsr( struct Kss_Emu* this, byte const addr [] ) ICODE_ATTR;
220
221static inline int sms_psg_enabled( struct Kss_Emu* this ) { return this->chip_flags & sms_psg_flag; }
222static inline int sms_fm_enabled( struct Kss_Emu* this ) { return this->chip_flags & sms_fm_flag; }
223static inline int msx_psg_enabled( struct Kss_Emu* this ) { return this->chip_flags & msx_psg_flag; }
224static inline int msx_scc_enabled( struct Kss_Emu* this ) { return this->chip_flags & msx_scc_flag; }
225static inline int msx_music_enabled( struct Kss_Emu* this ) { return this->chip_flags & msx_music_flag;}
226static inline int msx_audio_enabled( struct Kss_Emu* this ) { return this->chip_flags & msx_audio_flag;}
227
228#endif