00001 // 00002 // 1997/04/24 22:55:14 00003 // 00004 // This is an interface to the Emulator Engine and does not access any 00005 // audio hardware or driver. 00006 // 00007 // THIS CLASS INTERFACE CAN ONLY BE USED TO INSTANTIATE A -SINGLE OBJECT-. 00008 // DUE TO EFFICIENCY CONCERNS, THE EMULATOR ENGINE CONSISTS OUT -GLOBAL- 00009 // OBJECTS. Currently, the only aim of this class is to allow a safe 00010 // initialization of those object. 00011 // 00012 00013 #ifndef __EMUCFG_H 00014 #define __EMUCFG_H 00015 00016 //#include "epocglue.h" 00017 00018 #include "compconf.h" 00019 //#include "mytypes.h" 00020 #include "sidtune.h" 00021 //#include "6581_.h" 00022 //#include "mixing.h" 00023 00024 00025 // An instance of this structure is used to transport emulator settings 00026 // to and from the interface class. 00027 struct emuConfig 00028 { 00029 uword frequency; 00030 int bitsPerSample; 00031 int sampleFormat; 00032 int channels; 00033 int sidChips; 00034 int volumeControl; 00035 00036 bool mos8580; 00037 bool measuredVolume; 00038 00039 bool emulateFilter; 00040 float filterFs; 00041 float filterFm; 00042 float filterFt; // 00043 00044 int memoryMode; 00045 int clockSpeed; 00046 00047 bool forceSongSpeed; 00048 00049 // 00050 // Working, but experimental. 00051 // 00052 int digiPlayerScans; 00053 00054 00055 int autoPanning; 00056 }; 00057 00058 00059 // Memory mode settings: 00060 // 00061 // MPU_BANK_SWITCHING: Does emulate every bank-switching that one can 00062 // consider as useful for music players. 00063 // 00064 // MPU_TRANSPARENT_ROM: An emulator environment with partial bank-switching. 00065 // Required to run sidtunes which: 00066 // 00067 // - use the RAM under the I/O address space 00068 // - use RAM at $E000-$FFFA + jump to Kernal functions 00069 // 00070 // MPU_PLAYSID_ENVIRONMENT: A PlaySID-like emulator environment. 00071 // Required to run sidtunes which: 00072 // 00073 // - are specific to PlaySID 00074 // - do not contain bank-switching code 00075 // 00076 // Sidtunes that would not run on a real C64 because their players were 00077 // prepared to assume the certain emulator environment provided by PlaySID. 00078 00079 enum 00080 { 00081 // Memory mode settings. 00082 // 00083 MPU_BANK_SWITCHING = 0x20, 00084 MPU_TRANSPARENT_ROM, 00085 MPU_PLAYSID_ENVIRONMENT, 00086 00087 // Volume control modes. Use ``SIDEMU_NONE'' for no control. 00088 // 00089 SIDEMU_VOLCONTROL = 0x40, 00090 SIDEMU_FULLPANNING, 00091 SIDEMU_HWMIXING, 00092 SIDEMU_STEREOSURROUND, 00093 00094 // Auto-panning modes. Use ``SIDEMU_NONE'' for none. 00095 // 00096 SIDEMU_CENTEREDAUTOPANNING = 0x50, 00097 00098 // This can either be used as a dummy, or where one does not 00099 // want to make an alternative setting. 00100 SIDEMU_NONE = 0x1000 00101 }; 00102 00103 00104 // Sample format and configuration constants. The values are intended to 00105 // be distinct from each other. Some of the constants have a most obvious 00106 // value, so they can be used in calculations. 00107 00108 // Sample encoding (format). 00109 const int SIDEMU_UNSIGNED_PCM = 0x80; 00110 const int SIDEMU_SIGNED_PCM = 0x7F; 00111 00112 // Number of physical audio channels. 00113 // ``Stereo'' means interleaved channel data. 00114 const int SIDEMU_MONO = 1; 00115 const int SIDEMU_STEREO = 2; 00116 00117 // Sample precision (bits per sample). The endianess of the stored samples 00118 // is machine dependent. 00119 const int SIDEMU_8BIT = 8; 00120 const int SIDEMU_16BIT = 16; 00121 00122 00123 // Auto-panning modes. Only valid for mixing modes ``SIDEMU_FULLPANNING'' 00124 // or ``SIDEMU_STEREOSURROUND''. 00125 // 00126 // The volume levels left/right build the panning boundaries. The panning 00127 // range is the difference between left and right level. After enabling 00128 // this you can override the default levels with your own ones using the 00129 // setVoiceVolume() function. A default is provided to ensure sane 00130 // initial settings. 00131 // NOTE: You can mute a voice by setting left=right=0 or total=0. 00132 // 00133 // Auto-panning starts each new note on the opposite pan-position and 00134 // then moves between the left and right volume level. 00135 // 00136 // Centered auto-panning starts in the middle, moves outwards and then 00137 // toggles between the two pan-positions like normal auto-panning. 00138 00139 00140 // Default filter parameters. 00141 const float SIDEMU_DEFAULTFILTERFS = 400.0; 00142 const float SIDEMU_DEFAULTFILTERFM = 60.0; 00143 const float SIDEMU_DEFAULTFILTERFT = (float)0.05; 00144 00145 00146 // Volume control modes 00147 // 00148 // int volumeControl; 00149 // bool setVoiceVolume(int voice, ubyte leftLevel, ubyte rightLevel, uword total); 00150 // uword getVoiceVolume(int voice); 00151 // 00152 // Relative voice volume is ``total'' from 0 (mute) to 256 (max). If you use it, 00153 // you don't have to modulate each L/R level yourself. 00154 // 00155 // A noticable difference between FULLPANNING and VOLCONTROL is FULLPANNING's 00156 // capability to mix four (all) logical voices to a single physical audio 00157 // channel, whereas VOLCONTROL is only able to mix two (half of all) logical 00158 // voices to a physical channel. 00159 // Therefore VOLCONTROL results in slightly better sample quality, because 00160 // it mixes at higher amplitude. Especially when using a sample precision of 00161 // 8-bit and stereo. In mono mode both modes operate equally. 00162 // 00163 // NOTE: Changing the volume control mode resets the current volume 00164 // level settings for all voices to a default: 00165 // 00166 // MONO | left | right STEREO | left | right 00167 // ----------------------- ----------------------- 00168 // voice 1 | 255 | 0 voice 1 | 255 | 0 00169 // voice 2 | 255 | 0 voice 2 | 0 | 255 00170 // voice 3 | 255 | 0 voice 3 | 255 | 0 00171 // voice 4 | 255 | 0 voice 4 | 0 | 255 00172 // 00173 // SURROUND | left | right 00174 // ------------------------ 00175 // voice 1 | 255 | 255 00176 // voice 2 | 255 | 255 00177 // voice 3 | 255 | 255 00178 // voice 4 | 255 | 255 00179 // 00180 // 00181 // Because of the asymmetric ``three-voice'' nature of most sidtunes, it is 00182 // strongly advised to *not* use plain stereo without pan-positioning the 00183 // voices. 00184 // 00185 // int digiPlayerScans; 00186 // 00187 // If the integer above is set to ``x'', the sidtune will be scanned x player 00188 // calls for PlaySID digis on the fourth channel. If no digis are used, the 00189 // sidtune is hopefully ``three-voice-only'' and can be amplified in 00190 // SIDEMU_FULLPANNING and SIDEMU_STEREOSURROUND modes. 00191 // 00192 // 00193 // SIDEMU_NONE 00194 // 00195 // No volume control at all. Volume level of each voice is not adjustable. 00196 // Voices cannot be turned off. No panning possible. Most likely maximum 00197 // software mixing speed. 00198 // 00199 // 00200 // SIDEMU_VOLCONTROL 00201 // 00202 // In SIDEMU_STEREO mode two voices should build a pair, satisfying the 00203 // equation (leftlevel_A + leftlevel_B) <= 255. Generally, the equations: 00204 // sum leftLevel(i) <= 512 and sum rightLevel(i) <= 512 00205 // must be satisfied, i = [1,2,3,4]. 00206 // 00207 // In SIDEMU_MONO mode only the left level is used to specify a voice's 00208 // volume. If you specify a right level, it will be set to zero. 00209 // 00210 // 00211 // SIDEMU_FULLPANNING 00212 // 00213 // Volume level of each voice is adjustable between 255 (max) and 0 (off). 00214 // Each voice can be freely positioned between left and right, or both. 00215 // 00216 // 00217 // SIDEMU_STEREOSURROUND 00218 // 00219 // Volume level of each voice is adjustable between 255 (max) and 0 (off). 00220 // Each voice can be freely positioned between left and right. 00221 // Effect is best for left=255 plus right=255. 00222 // 00223 // 00224 // SIDEMU_HWMIXING 00225 // 00226 // Used for external mixing only. The sample buffer is split into four (4) 00227 // equivalent chunks, each representing a single voice. The client has to 00228 // take care of the sample buffer length to be dividable by four. 00229 00230 #define numberOfC64addr 9 //TODO: sort this out 00231 00232 // 00233 // forward declarations 00234 // 00235 class sidTune; 00236 class sidEmu; 00237 class Mixer; 00238 class C6510; 00239 00240 #if defined (__SYMBIAN32__) 00241 class emuEngine : public CBase 00242 #else 00243 class emuEngine 00244 #endif 00245 { 00246 00247 public: // --------------------------------------------------------- public 00248 00249 // The constructor creates and initializes the object with defaults. 00250 // Upon successful creation, use emuEngine::getConfig(...) to 00251 // retrieve the default settings. 00252 IMPORT_C emuEngine(); //ALFRED 00253 virtual ~emuEngine(); // destructor 00254 00255 // Set and retrieve the SID emulator settings. Invalid values will not 00256 // be accepted. 00257 // Returns: false, if invalid values. 00258 // true, else. 00259 IMPORT_C bool setConfig( struct emuConfig& ); 00260 IMPORT_C void getConfig( struct emuConfig& ); 00261 void returnConfig( emuConfig& inEmuCfg ) { getConfig(inEmuCfg); } 00262 00263 // Use this function together with a valid sidTune-object to fill 00264 // a buffer with calculated sample data. 00265 00266 friend sidEmu; // the whole 6581 class is a good friend. 00267 00268 // See ``sidtune.h'' for info on these. 00269 // friend bool sidEmuInitializeSong(emuEngine &, sidTune &, uword songNum); 00270 friend bool sidEmuInitializeSongOld(emuEngine &, sidTune &, uword songNum); 00271 00272 // Reset the filter parameters to default settings. 00273 void setDefaultFilterStrength(); 00274 00275 // This will even work during playback, but only in volume control modes 00276 // SIDEMU_VOLCONTROL, SIDEMU_FULLPANNING or SIDEMU_STEREOSURROUND. For the 00277 // modes SIDEMU_NONE or SIDEMU_HWMIXING this function has no effect. 00278 // 00279 // voice=[1,2,3,4], leftLevel=[0,..,255], rightLevel=[0,...,255] 00280 // total: 0=mute, ~128=middle, 256=max 00281 bool setVoiceVolume(int voice, ubyte leftLevel, ubyte rightLevel, uword total); 00282 00283 // Returns: high-byte = left level, low-byte = right level. 00284 uword getVoiceVolume(int voice); 00285 uword returnVoiceVolume(int voice) { return getVoiceVolume(voice); } 00286 00287 // Only useful to determine the state of a newly created object and 00288 // the current state after returning from a member function. 00289 operator bool() { return isReady; } 00290 bool getStatus() { return isReady; } 00291 bool returnStatus() { return getStatus(); } 00292 00293 // Public to the user, but need not be used explicitly. 00294 bool reset(); 00295 bool resetSampleEmu(); 00296 void amplifyThreeVoiceTunes(bool isThreeVoiceTune); 00297 00298 // Used for a run-time endianess check on Unix. Verifies the compiled 00299 // code and returns ``false'' if incorrectly set up. 00300 IMPORT_C bool verifyEndianess(); 00301 IMPORT_C void FillBuffer(sidTune& thistune, void* buffer, udword bufferLen); 00302 00303 #if defined(SIDEMU_TIME_COUNT) 00304 IMPORT_C int getSecondsThisSong(); 00305 IMPORT_C int getSecondsTotal(); 00306 00307 void resetSecondsThisSong() { secondsThisSong = 0; } 00308 #endif 00309 00310 00311 protected: // --------------------------------------------------- protected 00312 00313 // Set a random (!) random seed value. 00314 virtual void setRandomSeed(); // default uses ``time.h'' 00315 00316 00317 private: // ------------------------------------------------------- private methods 00318 void MPUreset(); 00319 ubyte * MPUreturnRAMbase(); 00320 bool freeMem(); 00321 bool allocMem(); 00322 void configureSID(); 00323 void initMixerEngine(); 00324 void initMixerFunction(); 00325 void setDefaultVoiceVolumes(); 00326 void filterTableInit(); 00327 00328 public: // ------------------------------------------------------- public variables 00329 C6510* iThe6510; 00330 sidEmu* iTheSidEmu; 00331 Mixer* iTheMixer; 00332 sbyte* ampMod1x8; 00333 00334 // private: // ------------------------------------------------------- private variables 00335 public: // TODO // ------------------------------------------------------- private variables 00336 emuConfig config; 00337 00338 #if defined(SIDEMU_TIME_COUNT) 00339 udword bytesCount; 00340 int secondsTotal; 00341 int secondsThisSong; 00342 #endif 00343 00344 ubyte bufferScale; 00345 ubyte playRamRom; 00346 00347 ubyte oldValues[numberOfC64addr]; 00348 00349 // 6510-interpreter. 00350 // 00351 // int memoryMode, clockSpeed; 00352 ubyte randomSeed; 00353 bool MPUstatus; 00354 00355 // 00356 bool isThreeVoiceAmplified; 00357 bool isThreeVoiceTune; 00358 bool isReady; 00359 00360 }; 00361 00362 00363 #endif