106 lines
3.3 KiB
C++
106 lines
3.3 KiB
C++
// Removes silence from beginning of track, fades end of track. Also looks ahead
|
|
// for excessive silence, and if found, ends track.
|
|
|
|
// Game_Music_Emu $vers
|
|
#ifndef TRACK_FILTER_H
|
|
#define TRACK_FILTER_H
|
|
|
|
#include "blargg_common.h"
|
|
|
|
class Track_Filter {
|
|
public:
|
|
typedef int sample_count_t;
|
|
typedef short sample_t;
|
|
|
|
enum { indefinite_count = INT_MAX/2 + 1 };
|
|
|
|
struct callbacks_t {
|
|
// Samples may be stereo or mono
|
|
virtual blargg_err_t play_( int count, sample_t* out ) BLARGG_PURE( { return blargg_ok; } )
|
|
virtual blargg_err_t skip_( int count ) BLARGG_PURE( { return blargg_ok; } )
|
|
virtual ~callbacks_t() { } // avoids silly "non-virtual dtor" warning
|
|
};
|
|
|
|
// Initializes filter. Must be done once before using object.
|
|
blargg_err_t init( callbacks_t* );
|
|
|
|
struct setup_t {
|
|
sample_count_t max_initial; // maximum silence to strip from beginning of track
|
|
sample_count_t max_silence; // maximum silence in middle of track without it ending
|
|
int lookahead; // internal speed when looking ahead for silence (2=200% etc.)
|
|
};
|
|
|
|
// Gets/sets setup
|
|
setup_t const& setup() const { return setup_; }
|
|
void setup( setup_t const& s ) { setup_ = s; }
|
|
|
|
// Disables automatic end-of-track detection and skipping of silence at beginning
|
|
void ignore_silence( bool disable = true ) { silence_ignored_ = disable; }
|
|
|
|
// Clears state and skips initial silence in track
|
|
blargg_err_t start_track();
|
|
|
|
// Sets time that fade starts, and how long until track ends.
|
|
void set_fade( sample_count_t start, sample_count_t length );
|
|
|
|
// Generates n samples into buf
|
|
blargg_err_t play( int n, sample_t buf [] );
|
|
|
|
// Skips n samples
|
|
blargg_err_t skip( int n );
|
|
|
|
// Number of samples played/skipped since start_track()
|
|
int sample_count() const { return out_time; }
|
|
|
|
// True if track ended. Causes are end of source samples, end of fade,
|
|
// or excessive silence.
|
|
bool track_ended() const { return track_ended_; }
|
|
|
|
// Clears state
|
|
void stop();
|
|
|
|
// For use by callbacks
|
|
|
|
// Sets internal "track ended" flag and stops generation of further source samples
|
|
void set_track_ended() { emu_track_ended_ = true; }
|
|
|
|
// For use by skip_() callback
|
|
blargg_err_t skip_( int count );
|
|
|
|
// Implementation
|
|
public:
|
|
Track_Filter();
|
|
~Track_Filter();
|
|
|
|
private:
|
|
callbacks_t* callbacks;
|
|
setup_t setup_;
|
|
const char* emu_error;
|
|
bool silence_ignored_;
|
|
|
|
// Timing
|
|
int out_time; // number of samples played since start of track
|
|
int emu_time; // number of samples emulator has generated since start of track
|
|
int emu_track_ended_; // emulator has reached end of track
|
|
volatile int track_ended_;
|
|
void clear_time_vars();
|
|
void end_track_if_error( blargg_err_t );
|
|
|
|
// Fading
|
|
int fade_start;
|
|
int fade_step;
|
|
bool is_fading() const;
|
|
void handle_fade( sample_t out [], int count );
|
|
|
|
// Silence detection
|
|
int silence_time; // absolute number of samples where most recent silence began
|
|
int silence_count; // number of samples of silence to play before using buf
|
|
int buf_remain; // number of samples left in silence buffer
|
|
enum { buf_size = 2048 };
|
|
blargg_vector<sample_t> buf;
|
|
void fill_buf();
|
|
void emu_play( sample_t out [], int count );
|
|
};
|
|
|
|
#endif
|