/* Namco custom waveform sound generator 3 (Pacman hardware) Copyright (c) 2003,2004 Alessandro Scotti http://www.ascotti.org/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef NAMCO_WSG3_H_ #define NAMCO_WSG3_H_ /** Namco 3-channel sound generator voice properties. This information is only needed by applications that want to do their own sound rendering, as the playSound() function already plays and mixes all three voices. @see PacmanMachine::playSound */ struct NamcoWsg3Voice { /** Volume (from 0 to 15) */ unsigned volume; /** Index into the 4-bit 32-entry waveform table (0 to 7) */ unsigned waveform; /** Frequency */ unsigned frequency; /** Default constructor */ NamcoWsg3Voice() : volume(0), waveform(0), frequency(0) { } /** Returns true if the voice is active, false otherwise. */ int isActive() const { return (volume > 0) && (frequency > 0); } }; /** */ class NamcoWsg3 { public: /** Constructor. @param masterClock clock frequency of sound chip (in Hertz) @param samplingRate sampling rate of the generated sound @see #playSound */ NamcoWsg3( unsigned masterClock ); /** Destructor. */ virtual ~NamcoWsg3() { } /** Sets the 256 byte PROM that contains the waveform table used by the sound chip. */ void setSoundPROM( const unsigned char * prom ); /** Returns the 256 byte PROM with waveform data info for the sound generator. */ const unsigned char * getSoundROM() const { return sound_prom_; } /** Sets the value of the specified register. */ void setRegister( unsigned reg, unsigned char value ) { sound_regs_[reg] = value; } /** Returns the value of the specified register. */ unsigned char getRegister( unsigned reg ) const { return sound_regs_[reg]; } /** Reproduces the sound that is currently being generated by the sound chip into the specified buffer. The sound chip has three independent voices that generate 8-bit signed PCM audio. This function resamples the voices at the currently specified sampling rate and mixes them into the output buffer. The output buffer can be converted to 8-bit (signed) PCM by dividing each sample by 3 (since there are three voices) or it can be expanded to 16-bit by multiplying each sample by 85 (i.e. 256 divided by 3). If necessary, it is possible to approximate these values with 4 and 64 in order to use arithmetic shifts that are usually faster to execute. Note: this function does not clear the content of the output buffer before mixing voices into it. @param buf pointer to sound buffer that receives the audio samples @param len length of the sound buffer */ void playSound( int * buf, int len ); /** Returns a pointer to a structure describing the current status of the specified voice in the sound generator. This is only useful if the application wants to reproduce the sound by itself, as the playSound() function already transforms and mixes all sound voices in a format useable by an application. @param voice structure to receive voice information @param index voice index (0, 1 or 2) @see #playSound */ void getVoice( NamcoWsg3Voice * voice, int index ) const; /** Sets the output sampling rate for playSound(). @param samplingRate sampling rate in Hertz (samples per second) */ void setSamplingRate( unsigned samplingRate ) { sampling_rate_ = samplingRate; // Compute the resampling increment, in fixed point // format with 10 bits for decimals resample_step_ = samplingRate ? (master_clock_ << 10) / samplingRate : 0; } /** Returns the sampling rate currently in use for rendering sound. */ unsigned getSamplingRate() const { return sampling_rate_; } /** Returns the size of the buffer needed to take a snapshot of the sound chip. @see PacmanMachine::getSizeOfSnapshotBuffer */ unsigned getSizeOfSnapshotBuffer() const; /** Takes a snapshot of the sound chip. A snapshot saves the chip registers and the wave PROM. Note: the size of the snapshot buffer must be no less than the size returned by the getSizeOfSnapshotBuffer() function. @param buffer buffer where the snapshot data is stored @return the number of bytes written into the buffer @see PacmanMachine::takeSnapshot @see MsPacmanMachine::takeSnapshot */ unsigned takeSnapshot( unsigned char * buffer ); /** Restores a snapshot taken with takeSnapshot(). This function uses the data saved in the snapshot buffer to restore the sound chip status. @param buffer buffer where the snapshot data is stored @return the number of bytes read from the buffer @see PacmanMachine::restoreSnapshot @see MsPacmanMachine::restoreSnapshot */ unsigned restoreSnapshot( unsigned char * buffer ); private: unsigned master_clock_; // Master clock of sound chip unsigned sampling_rate_; // Sampling rate for generated sound unsigned char sound_regs_[0x20]; // Sound registers unsigned char sound_prom_[32*8]; // Sound chip wavetable PROM // Internal variable for faster sound generation unsigned resample_step_; unsigned wave_offset_[3]; // Current sample offset (for each voice) int sound_wave_data_[32*8]; // Wave data for sound generation }; #endif // NAMCO_WSG3_H_