fmopl_midi.h

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2000, 2001, 2002  Ryan Nunn
00003 
00004 This program is free software; you can redistribute it and/or
00005 modify it under the terms of the GNU General Public License
00006 as published by the Free Software Foundation; either version 2
00007 of the License, or (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 */
00018 
00019 #ifndef FMOPL_MIDI_H
00020 #define FMOPL_MIDI_H
00021 
00022 #ifdef USE_FMOPL_MIDI
00023 
00024 // 22050/OPL_NUM_SAMPLES_PER_PASS = (120*OPL_TICK_MULTIPLIER)/OPL_TIME_PER_PASS
00025 #define OPL_TIME_PER_PASS     4
00026 #define OPL_NUM_SAMPLES_PER_PASS  49
00027 //#define OPL_TIME_PER_PASS     8
00028 //#define OPL_NUM_SAMPLES_PER_PASS  98
00029 //#define OPL_TIME_PER_PASS     32
00030 //#define OPL_NUM_SAMPLES_PER_PASS  392
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   // PSMDEX - Pentagram Streaming Midi Driver Extensions
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   // For Dual Opl2 Mode
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   // Communications
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   // Methods
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   // Sample Clock
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   // This stuff is only actually used by the play thread. it should NOT be touched
00145   // by anything else
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   // Xmidi Looping
00157   //
00158 
00159   // The for loop event
00160   midi_event  *loop_event[XMIDI_MAX_FOR_LOOP_COUNT];
00161 
00162   // The amount of times we have left that we can loop
00163   int   loop_count[XMIDI_MAX_FOR_LOOP_COUNT];
00164 
00165   // The level of the loop we are currently in
00166   int   loop_num;   
00167 
00168 
00169 };
00170 
00171 #endif //USE_FMOPL_MIDI
00172 
00173 #endif //FMOPL_MIDI_H

Generated on Mon Jul 9 14:42:40 2007 for ExultEngine by  doxygen 1.5.1