Mercurial > audlegacy-plugins
diff src/console/Vgm_Emu.h @ 12:3da1b8942b8b trunk
[svn] - remove src/Input src/Output src/Effect src/General src/Visualization src/Container
author | nenolod |
---|---|
date | Mon, 18 Sep 2006 03:14:20 -0700 |
parents | src/Input/console/Vgm_Emu.h@13389e613d67 |
children | fb513e10174e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/console/Vgm_Emu.h Mon Sep 18 03:14:20 2006 -0700 @@ -0,0 +1,118 @@ + +// Multi-format VGM music emulator with support for SMS PSG and Mega Drive FM + +// Game_Music_Emu 0.3.0 + +#ifndef VGM_EMU_H +#define VGM_EMU_H + +#include "abstract_file.h" +#include "Vgm_Emu_Impl.h" + +// Emulates VGM music using SN76489/SN76496 PSG, YM2612, and YM2413 FM sound chips. +// Supports custom sound buffer and frequency equalization when VGM uses just the PSG. +// FM sound chips can be run at their proper rates, or slightly higher to reduce +// aliasing on high notes. Currently YM2413 support requires that you supply a +// YM2413 sound chip emulator. I can provide one I've modified to work with the library. +class Vgm_Emu : public Vgm_Emu_Impl { +public: + + // Oversample runs FM chips at higher than normal rate. Tempo adjusts speed of + // music, but not pitch. + Vgm_Emu( bool oversample = true, double tempo = 1.0 ); + + // VGM header format + struct header_t + { + char tag [4]; + byte data_size [4]; + byte version [4]; + byte psg_rate [4]; + byte ym2413_rate [4]; + byte gd3_offset [4]; + byte track_duration [4]; + byte loop_offset [4]; + byte loop_duration [4]; + byte frame_rate [4]; + byte noise_feedback [2]; + byte noise_width; + byte unused1; + byte ym2612_rate [4]; + byte ym2151_rate [4]; + byte data_offset [4]; + byte unused2 [8]; + + enum { track_count = 1 }; // one track per file + enum { time_rate = 44100 }; // all times specified at this rate + + // track information is in gd3 data + enum { game = 0 }; + enum { song = 0 }; + enum { author = 0 }; + enum { copyright = 0 }; + }; + BOOST_STATIC_ASSERT( sizeof (header_t) == 64 ); + + // Load VGM data + blargg_err_t load( Data_Reader& ); + + // Load VGM using already-loaded header and remaining data + blargg_err_t load( header_t const&, Data_Reader& ); + + // Load VGM using pointer to file data. Keeps pointer to data. + blargg_err_t load( void const* data, long size ); + + // Header for currently loaded VGM + header_t const& header() const { return header_; } + + // Pointer to gd3 data, or NULL if none. Optionally returns size of data. + // Checks for GD3 header and that version is less than 2.0. + byte const* gd3_data( int* size_out = NULL ) const; + + // to do: find better name for this + // True if Classic_Emu operations are supported + bool is_classic_emu() const { return !uses_fm; } + +public: + ~Vgm_Emu(); + blargg_err_t set_sample_rate( long sample_rate ); + void start_track( int ); + void mute_voices( int mask ); + const char** voice_names() const; + void play( long count, sample_t* ); +public: + // deprecated + int track_length( const byte** end_out = NULL, int* remain_out = NULL ) const + { + return (header().track_duration [3]*0x1000000L + + header().track_duration [2]*0x0010000L + + header().track_duration [1]*0x0000100L + + header().track_duration [0]) / header_t::time_rate; + } +protected: + // Classic_Emu + void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* ); + void update_eq( blip_eq_t const& ); + blip_time_t run( int, bool* ); +private: + header_t header_; + blargg_vector<byte> mem; + long vgm_rate; + bool oversample; + bool uses_fm; + + blargg_err_t init_( long sample_rate ); + blargg_err_t load_( const header_t&, void const* data, long size ); + blargg_err_t setup_fm(); + void unload(); +}; + +inline blargg_err_t Vgm_Emu::load( void const* data, long size ) +{ + unload(); + return load_( *(header_t*) data, (char*) data + sizeof (header_t), + size - sizeof (header_t) ); +} + +#endif +