00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef FMOPL_MIDI_H
00020 #define FMOPL_MIDI_H
00021
00022 #ifdef USE_FMOPL_MIDI
00023
00024
00025 #define OPL_TIME_PER_PASS 4
00026 #define OPL_NUM_SAMPLES_PER_PASS 49
00027
00028
00029
00030
00031 #define OPL_TICK_MULTIPLIER 15
00032
00033 #include "Midi.h"
00034 #include "exceptions.h"
00035 #include "SDL_thread.h"
00036 #include "SDL.h"
00037
00038 class OplDriver;
00039 class RingBuffer16;
00040
00041 class FMOpl_Midi : virtual public MidiAbstract
00042 {
00043 public:
00044 virtual void start_track(XMIDIEventList *, bool repeat);
00045 virtual void stop_track(void);
00046 virtual bool is_playing(void);
00047 virtual const char *copyright(void);
00048 virtual void load_patches(bool force_xmidi);
00049 virtual bool is_fm_synth();
00050 virtual bool use_gs127();
00051
00052
00053 virtual int max_streams();
00054 virtual void start_stream(int str_num, XMIDIEventList *, bool repeat, bool activate, int vol);
00055 virtual void activate_stream(int str_num);
00056 virtual void stop_stream(int str_num);
00057 virtual void set_volume(int str_num, int level);
00058 virtual bool is_playing(int str_num);
00059 virtual int get_active();
00060
00061
00062 FMOpl_Midi();
00063 virtual ~FMOpl_Midi();
00064
00065 private:
00066 UNREPLICATABLE_CLASS(FMOpl_Midi);
00067
00068 struct mid_data {
00069 XMIDIEventList *list;
00070 bool repeat;
00071 };
00072
00073 static const unsigned short centre_value;
00074 static const unsigned char fine_value;
00075 static const unsigned char coarse_value;
00076 static const unsigned short combined_value;
00077
00078 int is_available;
00079 OplDriver *opl;
00080 RingBuffer16 *buffer;
00081
00082
00083 bool dual;
00084 int global_volume;
00085 uint8 volumes[16];
00086 uint8 balances[16];
00087 OplDriver *opl_right;
00088 RingBuffer16 *buffer_right;
00089
00090
00091 int &LockComs();
00092 void UnlockComs();
00093 void ClearComs();
00094
00095 bool playing;
00096 int comMessage_priv;
00097 XMIDIEventList *new_list;
00098 SDL_mutex *mutex;
00099 SDL_mutex *comMutex;
00100
00101
00102 static void mixer_hook_static(void *udata, Uint8 *stream, int len);
00103 void mixer_hook(Uint8 *stream, int len);
00104
00105 void init_device();
00106 void deinit_device();
00107 void reset_channel (int i);
00108
00109
00110 unsigned long total_sample_ticks;
00111 unsigned long start;
00112
00113 inline void wmoClockIncTime(unsigned long c)
00114 { total_sample_ticks += c; }
00115
00116 inline unsigned long wmoGetRealTime ()
00117 { return total_sample_ticks*OPL_TIME_PER_PASS; }
00118
00119 inline void wmoInitClock ()
00120 { start = wmoGetRealTime(); }
00121
00122 inline void wmoAddOffset (unsigned long offset)
00123 { start += offset; }
00124
00125 inline void wmoSubOffset (unsigned long offset)
00126 { start -= offset; }
00127
00128 inline unsigned long wmoGetTime ()
00129 { return wmoGetRealTime() - start; }
00130
00131 inline unsigned long wmoGetStart ()
00132 { return start; }
00133
00134 inline void send(uint32 b);
00135 inline void send_vol_or_balance(uint32 chan);
00136 void PlayNotes();
00137 void HandlePlay();
00138 void HandleStop();
00139
00140 uint32 GenerateSamples(uint32 count_required, uint32 sample_rate);
00141 void GetSamples(uint32 samples);
00142
00143
00144
00145
00146 int repeat;
00147 uint32 aim;
00148 sint32 diff;
00149 uint32 last_tick;
00150 XMIDIEventList *evntlist;
00151 midi_event *event;
00152 NoteStack notes_on;
00153 uint32 generate_rem;
00154
00155
00156
00157
00158
00159
00160 midi_event *loop_event[XMIDI_MAX_FOR_LOOP_COUNT];
00161
00162
00163 int loop_count[XMIDI_MAX_FOR_LOOP_COUNT];
00164
00165
00166 int loop_num;
00167
00168
00169 };
00170
00171 #endif //USE_FMOPL_MIDI
00172
00173 #endif //FMOPL_MIDI_H