- Split paula.cpp and modplayer.cpp into separate compilation units - Created config.h for centralized configuration constants - Created types.h for type definitions and utility functions - Added comprehensive comments throughout all files - Improved code organization with clear section dividers - Maintained all original functionality and logic
155 lines
6.7 KiB
C++
155 lines
6.7 KiB
C++
// =================== MOD File Player ===================
|
|
// Plays Amiga MOD (Protracker) format music files
|
|
// Handles all MOD format parsing, effect processing, and timing
|
|
|
|
#ifndef MODPLAYER_H
|
|
#define MODPLAYER_H
|
|
|
|
#include "types.h"
|
|
#include "config.h"
|
|
#include "paula.h"
|
|
|
|
// =================== ModPlayer Class ===================
|
|
// Represents a MOD file player with playback control and effect processing
|
|
class ModPlayer
|
|
{
|
|
private:
|
|
// === Paula Reference ===
|
|
Paula *P; // Pointer to Paula emulator instance
|
|
|
|
// === Period & Frequency Tables ===
|
|
// These tables convert MOD note values to Paula periods
|
|
static sInt BasePTable[5 * 12 + 1]; // Base period table (5 octaves x 12 semitones + extra)
|
|
static sInt PTable[16][60]; // Period table for each finetune (-8 to +7)
|
|
static sInt VibTable[3][15][64]; // Vibrato/tremolo lookup tables
|
|
|
|
// === Playback State ===
|
|
sInt Speed; // Ticks per row (default 6)
|
|
sInt TickRate; // Number of samples per tick
|
|
sInt TRCounter; // Tick rate counter (samples remaining)
|
|
|
|
sInt CurTick; // Current tick within row (0 to Speed-1)
|
|
sInt CurRow; // Current pattern row (0-63)
|
|
sInt CurPos; // Current song position (pattern index)
|
|
sInt Delay; // Pattern delay in ticks
|
|
|
|
// === Sample Storage ===
|
|
sS8 *SData[32]; // Pointers to sample data
|
|
sInt SampleCount; // Number of samples in file
|
|
sInt ChannelCount; // Number of channels (always 4 for standard MOD)
|
|
|
|
// === Song Structure ===
|
|
sU8 PatternList[128]; // List of which patterns to play in which order
|
|
sInt PositionCount; // Number of positions in song
|
|
sInt PatternCount; // Number of unique patterns
|
|
|
|
// =================== Sample Structure ===================
|
|
// Represents a single instrument/sample in MOD format
|
|
struct Sample
|
|
{
|
|
char Name[22]; // Sample name (22 bytes in MOD format)
|
|
sU16 Length; // Sample length in words (1 word = 2 bytes)
|
|
sS8 Finetune; // Finetune value (-8 to +7)
|
|
sU8 Volume; // Default volume (0-64)
|
|
sU16 LoopStart; // Loop start position in words
|
|
sU16 LoopLen; // Loop length in words
|
|
|
|
// Convert sample data from big-endian MOD format to native format
|
|
// MOD files store multi-byte values in big-endian format
|
|
void Prepare();
|
|
} *Samples; // Pointer to sample array
|
|
|
|
// =================== Pattern Structure ===================
|
|
// Represents a 64-row pattern with 4 channels of note data
|
|
struct Pattern
|
|
{
|
|
// Single note event (one channel, one row)
|
|
struct Event
|
|
{
|
|
sInt Sample; // Sample number (0-31)
|
|
sInt Note; // Note number (0-60)
|
|
sInt FX; // Effect type (0-15)
|
|
sInt FXParm; // Effect parameter value
|
|
} Events[64][4]; // 64 rows x 4 channels
|
|
|
|
// Zero out pattern data
|
|
Pattern();
|
|
|
|
// Parse pattern data from MOD file format
|
|
void Load(sU8 *ptr);
|
|
} Patterns[128]; // Array of patterns
|
|
|
|
// =================== Channel State Structure ===================
|
|
// Maintains playback state for a single audio channel
|
|
struct Chan
|
|
{
|
|
sInt Note; // Current note number
|
|
sInt Period; // Current period (Paula playback rate)
|
|
sInt Sample; // Current sample number
|
|
sInt FineTune; // Current finetune value
|
|
sInt Volume; // Current volume (0-64)
|
|
sInt FXBuf[16]; // Effect command values (command 0-15)
|
|
sInt FXBuf14[16]; // Effect parameters for command 14 (special)
|
|
sInt LoopStart; // Pattern loop start row
|
|
sInt LoopCount; // Pattern loop counter
|
|
sInt RetrigCount; // Retrigger counter (for effect 9)
|
|
sInt VibWave; // Vibrato waveform (0-3)
|
|
sInt VibRetr; // Vibrato retrigger flag
|
|
sInt VibPos; // Vibrato position (0-63)
|
|
sInt VibAmpl; // Vibrato amplitude (1-15)
|
|
sInt VibSpeed; // Vibrato speed
|
|
sInt TremWave; // Tremolo waveform (0-3)
|
|
sInt TremRetr; // Tremolo retrigger flag
|
|
sInt TremPos; // Tremolo position (0-63)
|
|
sInt TremAmpl; // Tremolo amplitude (1-15)
|
|
sInt TremSpeed; // Tremolo speed
|
|
|
|
// Initialize channel state to all zeros
|
|
Chan();
|
|
|
|
// Calculate Paula period from note and finetune values
|
|
sInt GetPeriod(sInt offs = 0, sInt fineoffs = 0);
|
|
|
|
// Set Paula period
|
|
void SetPeriod(sInt offs = 0, sInt fineoffs = 0);
|
|
} Chans[4]; // Array of 4 channels
|
|
|
|
// =================== Playback Control ===================
|
|
// Calculate number of samples per tick based on BPM
|
|
// Higher BPM = faster playback
|
|
void CalcTickRate(sInt bpm);
|
|
|
|
// Trigger a note on a channel (start playing sample)
|
|
void TrigNote(sInt ch, const Pattern::Event &e);
|
|
|
|
// Reset playback state to beginning of song
|
|
void Reset();
|
|
|
|
// Process one "tick" of MOD playback
|
|
// Updates effects, advances notes, handles timing
|
|
void Tick();
|
|
|
|
public:
|
|
// Song name from MOD file
|
|
char Name[21];
|
|
|
|
// ModPlayer constructor: load and initialize MOD file
|
|
// p: pointer to Paula emulator
|
|
// moddata: pointer to MOD file data in memory
|
|
ModPlayer(Paula *p, sU8 *moddata);
|
|
|
|
// =================== Audio Rendering ===================
|
|
// Render audio samples into buffer
|
|
// Called repeatedly by audio system to generate sound
|
|
// buf: output buffer for stereo samples (float, interleaved L/R)
|
|
// len: number of samples to generate
|
|
// Returns: number of samples generated
|
|
sU32 Render(sF32 *buf, sU32 len);
|
|
|
|
// Static callback function for audio systems
|
|
// Allows this to be used as a C-style callback
|
|
static sU32 __stdcall RenderProxy(void *parm, sF32 *buf, sU32 len);
|
|
};
|
|
|
|
#endif // MODPLAYER_H
|