diff --git a/common/resample/resampler.h b/common/resample/resampler.h index f3d448d9..75566b49 100644 --- a/common/resample/resampler.h +++ b/common/resample/resampler.h @@ -21,21 +21,51 @@ #include +/** Interface to a Resampler. */ class Resampler { long inRate_; long outRate_; protected: void setRate(const long inRate, const long outRate) { inRate_ = inRate; outRate_ = outRate; } + Resampler() : inRate_(0), outRate_(0) {} public: - Resampler() : inRate_(0), outRate_(0) {} + /** Returns the sampling rate of the input that this resampler expects. */ long inRate() const { return inRate_; } + + /** Returns the approximate sampling rate of the output. */ long outRate() const { return outRate_; } + /** Can be used to adjust the input and output sampling rates slightly with minimal disturbance in the output. + * Should only be used for slight changes or the quality could detoriate. + * It can for instance be useful to tweak the output rate slightly to synchronize production speed to playback + * speed when synchronizing video frame rate to refresh rate while playing back audio from the same source. + * This can reduce skipped or duplicated video frames (or avoid audio underruns if no frame skipping is done). + * + * @param inRate New input sampling rate. + * @param outRate Desired new output sampling rate. + */ virtual void adjustRate(long inRate, long outRate) = 0; + + /** Returns the exact ratio that this resampler is configured to use, + * such that the actual output sampling rate is (input rate) * mul / div. + * outRate() / inRate() is not necessarily equal to mul / div. + * Many resampler are intended for real-time purposes where it does not matter + * much whether the output sampling rate is 100% exact. Playback hardware is also slightly off. + */ virtual void exactRatio(unsigned long &mul, unsigned long &div) const = 0; + + /** Returns an upper bound on how many samples are produced for 'inlen' input samples. + * Can be used to calculate buffer sizes. + */ virtual std::size_t maxOut(std::size_t inlen) const = 0; + + /** Resamples the samples in 'in' and puts the resulting samples in 'out'. + * + * @param inlen The number of samples in 'in' to be resampled/consumed. + * @return The number of samples produced in 'out'. + */ virtual std::size_t resample(short *out, const short *in, std::size_t inlen) = 0; virtual ~Resampler() {} }; diff --git a/common/resample/resamplerinfo.h b/common/resample/resamplerinfo.h index 23f4a545..294034ac 100644 --- a/common/resample/resamplerinfo.h +++ b/common/resample/resamplerinfo.h @@ -21,11 +21,27 @@ #include "resampler.h" +/** Used for creating instances of resamplers, and getting information on available resamplers. + * Currently creates resamplers that expect stereo samples. All 'numbers of samples' are in + * number of stereo samples. (This can be changed by adjusting the 'channels' enum in src/chainresampler.h + * to the number of desired channels.). + */ struct ResamplerInfo { + /** Short character string description of the resampler. */ const char *desc; + + /** Points to a function that can be used to create an instance of the resampler. + * @param inRate The input sampling rate. + * @param outRate The desired output sampling rate. + * @param periodSz The maximum number of input samples to resample at a time. That is the maximal inlen passed to Resampler::resample. + * @return Pointer to the created instance (on the heap). Caller must free this with the delete operator. + */ Resampler* (*create)(long inRate, long outRate, std::size_t periodSz); + /** Returns the number of ResamplerInfos that can be gotten with get(). */ static unsigned num() { return num_; } + + /** Returns ResamplerInfo number n. Where n is less than num(). */ static const ResamplerInfo& get(unsigned n) { return resamplers[n]; } private: diff --git a/common/resample/src/chainresampler.h b/common/resample/src/chainresampler.h index df44e7b5..9cc28114 100644 --- a/common/resample/src/chainresampler.h +++ b/common/resample/src/chainresampler.h @@ -29,8 +29,6 @@ #include "upsampler.h" class ChainResampler : public Resampler { - enum { channels = 2 }; - typedef std::list list_t; list_t list; @@ -64,6 +62,7 @@ class ChainResampler : public Resampler { std::size_t upinit(long inRate, long outRate, std::size_t periodSize); public: + enum { channels = 2 }; ChainResampler() : bigSinc(NULL), buffer(NULL), buffer2(NULL), bufferSize(0), periodSize(0) {} ~ChainResampler() { uninit(); } diff --git a/common/resample/src/resamplerinfo.cpp b/common/resample/src/resamplerinfo.cpp index c8eff172..0cf41aa6 100644 --- a/common/resample/src/resamplerinfo.cpp +++ b/common/resample/src/resamplerinfo.cpp @@ -26,7 +26,7 @@ #include "linint.h" struct LinintInfo { - static Resampler* create(long inRate, long outRate, std::size_t) { return new Linint<2>(inRate, outRate); } + static Resampler* create(long inRate, long outRate, std::size_t) { return new Linint(inRate, outRate); } }; template class T> diff --git a/gambatte_qt/src/framework/mainwindow.h b/gambatte_qt/src/framework/mainwindow.h index 8cb8944f..409a69af 100644 --- a/gambatte_qt/src/framework/mainwindow.h +++ b/gambatte_qt/src/framework/mainwindow.h @@ -286,20 +286,20 @@ public: void setResampler(unsigned resamplerNo); /** Pause doesn't take effect immediately. Call this to wait until the worker thread is paused. - * Meant as a tool to simplify thread-safety. + * Meant as a tool to simplify thread safety. */ void waitUntilPaused(); /** Temporarily pauses the worker thread and calls fun once it has paused. Then unpauses. * Returns before fun is actually called. Fun is called in an event at a later time. * fun should implement operator() and have a copy-constructor. - * Meant as a tool to simplify thread-safety. + * Meant as a tool to simplify thread safety. */ template void callWhenPaused(const T& fun); /** Puts fun into a queue of functors that are called in the worker thread at a later time. * fun should implement operator() and have a copy-constructor. - * Meant as a tool to simplify thread-safety. + * Meant as a tool to simplify thread safety. * Generally you should prefer this to callWhenPaused, because callWhenPaused * is more likely to cause audio underruns. */ diff --git a/libgambatte/include/gambatte.h b/libgambatte/include/gambatte.h index de668ebf..10b11b55 100644 --- a/libgambatte/include/gambatte.h +++ b/libgambatte/include/gambatte.h @@ -32,10 +32,20 @@ class GB { int stateNo; void loadState(const char *filepath, bool osdMessage); + GB(const GB&); + GB& operator=(const GB&); public: GB(); ~GB(); + + /** Load Game Boy Color ROM image. + * You should always load a ROM image before calling runFor, reset, saveState or loadState functions. + * + * @param romfile Path to rom image file. Typically a .gbc, .gb, or .zip-file (if zip-support is compiled in). + * @param forceDmg Treat the ROM as not having CGB support regardless of what its header advertises. + * @return true if failed to load ROM image. + */ bool load(const char* romfile, bool forceDmg = false); /** Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer, @@ -53,6 +63,8 @@ public: * The return value indicates whether a new video frame has been drawn, and the * exact time (in number of samples) at which it was drawn. * + * Should not be called unless a ROM images is loaded. + * * @param videoBuf 160x144 RGB32 (native endian) video frame buffer or 0 * @param pitch distance in number of pixels (not bytes) from the start of one line to the next in videoBuf. * @param soundBuf buffer with space >= samples + 2064 @@ -62,6 +74,10 @@ public: int runFor(Gambatte::uint_least32_t *videoBuf, unsigned pitch, Gambatte::uint_least32_t *soundBuf, unsigned &samples); + /** Reset to initial state. + * Equivalent to reloading a ROM image, or turning a Game Boy Color off and on again. + * Should not be called unless a ROM images is loaded. + */ void reset(); /** @param palNum 0 <= palNum < 3. One of BG_PALETTE, SP1_PALETTE and SP2_PALETTE. @@ -69,15 +85,48 @@ public: */ void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32); + /** Sets the callback used for getting input state. */ void setInputGetter(InputGetter *getInput); + /** Sets the directory used for storing save data. The default is the same directory as the ROM Image file. */ void setSaveDir(const char *sdir); + + /** Returns true if the currently loaded ROM image is treated as having CGB support. */ bool isCgb() const; + + /** Saves emulator state to the state slot selected with selectState(). + * The data will be stored in the directory given by setSaveDir(). + * Should not be called unless a ROM images is loaded. + * + * @param videoBuf 160x144 RGB32 (native endian) video frame buffer or 0. Used for storing a thumbnail. + * @param pitch distance in number of pixels (not bytes) from the start of one line to the next in videoBuf. + */ void saveState(const Gambatte::uint_least32_t *videoBuf, unsigned pitch); + + /** Loads emulator state from the state slot selected with selectState(). + * Should not be called unless a ROM images is loaded. + */ void loadState(); + + /** Saves emulator state to the file given by 'filepath'. + * Should not be called unless a ROM images is loaded. + * + * @param videoBuf 160x144 RGB32 (native endian) video frame buffer or 0. Used for storing a thumbnail. + * @param pitch distance in number of pixels (not bytes) from the start of one line to the next in videoBuf. + */ void saveState(const Gambatte::uint_least32_t *videoBuf, unsigned pitch, const char *filepath); + + /** Loads emulator state from the file given by 'filepath'. + * Should not be called unless a ROM images is loaded. + */ void loadState(const char *filepath); + + /** Selects which state slot to save state to or load state from. + * There are 10 such slots, numbered from 0 to 9 (periodically extended for all n). + */ void selectState(int n); + + /** Current state slot selected with selectState(). Returns a value between 0 and 9 inclusive. */ int currentState() const { return stateNo; } }; }