#ifndef SPC_EMU_H
#define SPC_EMU_H
#include "Fir_Resampler.h"
#include "Music_Emu.h"
#include "Snes_Spc.h"
#include "Spc_Filter.h"
class Spc_Emu : public Music_Emu {
public:
enum { native_sample_rate = 32000 };
enum { header_size = 0x100 };
struct header_t
{
char tag [35];
byte format;
byte version;
byte pc [2];
byte a, x, y, psw, sp;
byte unused [2];
char song [32];
char game [32];
char dumper [16];
char comment [32];
byte date [11];
byte len_secs [3];
byte fade_msec [4];
char author [32]; byte mute_mask;
byte emulator;
byte unused2 [46];
};
header_t const& header() const { return *(header_t const*) file_data; }
void disable_surround( bool disable = true );
static gme_type_t static_type() { return gme_spc_type; }
public:
using Music_Emu::load;
blargg_err_t load( header_t const& h, Data_Reader& in ) { return load_remaining_( &h, sizeof h, in ); }
byte const* trailer() const; long trailer_size() const;
public:
Spc_Emu( gme_type_t );
Spc_Emu() : Spc_Emu( gme_spc_type ) {}
~Spc_Emu();
protected:
blargg_err_t load_mem_( byte const*, long );
blargg_err_t track_info_( track_info_t*, int track ) const;
blargg_err_t set_sample_rate_( long );
blargg_err_t start_track_( int );
blargg_err_t play_( long, sample_t* );
blargg_err_t skip_( long );
void mute_voices_( int );
void set_tempo_( double );
void enable_accuracy_( bool );
byte const* file_data;
long file_size;
private:
Fir_Resampler<24> resampler;
SPC_Filter filter;
Snes_Spc apu;
blargg_err_t play_and_filter( long count, sample_t out [] );
};
inline void Spc_Emu::disable_surround( bool b ) { apu.disable_surround( b ); }
class Rsn_Emu : public Spc_Emu {
public:
Rsn_Emu() : Spc_Emu( gme_rsn_type ) { is_archive = true; }
~Rsn_Emu();
blargg_err_t load_archive( const char* );
header_t const& header( int track ) const { return *(header_t const*) spc[track]; }
byte const* trailer( int ) const; long trailer_size( int ) const;
protected:
blargg_err_t track_info_( track_info_t*, int ) const;
blargg_err_t start_track_( int );
private:
blargg_vector<byte> rsn;
blargg_vector<byte*> spc;
};
#endif