mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-27 02:01:32 +11:00
320 lines
7.3 KiB
C
320 lines
7.3 KiB
C
/* Copyright (c) 2013-2016 Jeffrey Pfau
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
#ifndef GBA_AUDIO_H
|
|
#define GBA_AUDIO_H
|
|
|
|
#include <mgba-util/common.h>
|
|
|
|
CXX_GUARD_START
|
|
|
|
#include <mgba/core/cpu.h>
|
|
#include <mgba/core/log.h>
|
|
#include <mgba/internal/gb/audio.h>
|
|
#include <mgba-util/circle-buffer.h>
|
|
|
|
#define GBA_AUDIO_FIFO_SIZE 8
|
|
|
|
#define MP2K_MAGIC 0x68736D53
|
|
#define MP2K_MAX_SOUND_CHANNELS 12
|
|
|
|
mLOG_DECLARE_CATEGORY(GBA_AUDIO);
|
|
|
|
struct GBADMA;
|
|
|
|
extern const unsigned GBA_AUDIO_SAMPLES;
|
|
extern const int GBA_AUDIO_VOLUME_MAX;
|
|
|
|
struct GBAAudioFIFO {
|
|
uint32_t fifo[GBA_AUDIO_FIFO_SIZE];
|
|
int fifoWrite;
|
|
int fifoRead;
|
|
uint32_t internalSample;
|
|
int internalRemaining;
|
|
int dmaSource;
|
|
int8_t sample;
|
|
};
|
|
|
|
DECL_BITFIELD(GBARegisterSOUNDCNT_HI, uint16_t);
|
|
DECL_BITS(GBARegisterSOUNDCNT_HI, Volume, 0, 2);
|
|
DECL_BIT(GBARegisterSOUNDCNT_HI, VolumeChA, 2);
|
|
DECL_BIT(GBARegisterSOUNDCNT_HI, VolumeChB, 3);
|
|
DECL_BIT(GBARegisterSOUNDCNT_HI, ChARight, 8);
|
|
DECL_BIT(GBARegisterSOUNDCNT_HI, ChALeft, 9);
|
|
DECL_BIT(GBARegisterSOUNDCNT_HI, ChATimer, 10);
|
|
DECL_BIT(GBARegisterSOUNDCNT_HI, ChAReset, 11);
|
|
DECL_BIT(GBARegisterSOUNDCNT_HI, ChBRight, 12);
|
|
DECL_BIT(GBARegisterSOUNDCNT_HI, ChBLeft, 13);
|
|
DECL_BIT(GBARegisterSOUNDCNT_HI, ChBTimer, 14);
|
|
DECL_BIT(GBARegisterSOUNDCNT_HI, ChBReset, 15);
|
|
|
|
DECL_BITFIELD(GBARegisterSOUNDBIAS, uint16_t);
|
|
DECL_BITS(GBARegisterSOUNDBIAS, Bias, 0, 10);
|
|
DECL_BITS(GBARegisterSOUNDBIAS, Resolution, 14, 2);
|
|
|
|
struct GBAAudioMixer;
|
|
struct GBAAudio {
|
|
struct GBA* p;
|
|
|
|
struct GBAudio psg;
|
|
struct GBAAudioFIFO chA;
|
|
struct GBAAudioFIFO chB;
|
|
|
|
int16_t lastLeft;
|
|
int16_t lastRight;
|
|
int clock;
|
|
|
|
uint8_t volume;
|
|
bool volumeChA;
|
|
bool volumeChB;
|
|
bool chARight;
|
|
bool chALeft;
|
|
bool chATimer;
|
|
bool chBRight;
|
|
bool chBLeft;
|
|
bool chBTimer;
|
|
bool enable;
|
|
|
|
size_t samples;
|
|
unsigned sampleRate;
|
|
|
|
GBARegisterSOUNDBIAS soundbias;
|
|
|
|
struct GBAAudioMixer* mixer;
|
|
bool externalMixing;
|
|
int32_t sampleInterval;
|
|
|
|
bool forceDisableChA;
|
|
bool forceDisableChB;
|
|
int masterVolume;
|
|
|
|
struct mTimingEvent sampleEvent;
|
|
};
|
|
|
|
struct GBAStereoSample {
|
|
int16_t left;
|
|
int16_t right;
|
|
};
|
|
|
|
struct GBAMP2kADSR {
|
|
uint8_t attack;
|
|
uint8_t decay;
|
|
uint8_t sustain;
|
|
uint8_t release;
|
|
};
|
|
|
|
struct GBAMP2kSoundChannel {
|
|
uint8_t status;
|
|
uint8_t type;
|
|
uint8_t rightVolume;
|
|
uint8_t leftVolume;
|
|
struct GBAMP2kADSR adsr;
|
|
uint8_t ky;
|
|
uint8_t envelopeV;
|
|
uint8_t envelopeRight;
|
|
uint8_t envelopeLeft;
|
|
uint8_t echoVolume;
|
|
uint8_t echoLength;
|
|
uint8_t d1;
|
|
uint8_t d2;
|
|
uint8_t gt;
|
|
uint8_t midiKey;
|
|
uint8_t ve;
|
|
uint8_t pr;
|
|
uint8_t rp;
|
|
uint8_t d3[3];
|
|
uint32_t ct;
|
|
uint32_t fw;
|
|
uint32_t freq;
|
|
uint32_t waveData;
|
|
uint32_t cp;
|
|
uint32_t track;
|
|
uint32_t pp;
|
|
uint32_t np;
|
|
uint32_t d4;
|
|
uint16_t xpi;
|
|
uint16_t xpc;
|
|
};
|
|
|
|
struct GBAMP2kContext {
|
|
uint32_t magic;
|
|
uint8_t pcmDmaCounter;
|
|
uint8_t reverb;
|
|
uint8_t maxChans;
|
|
uint8_t masterVolume;
|
|
uint8_t freq;
|
|
uint8_t mode;
|
|
uint8_t c15;
|
|
uint8_t pcmDmaPeriod;
|
|
uint8_t maxLines;
|
|
uint8_t gap[3];
|
|
int32_t pcmSamplesPerVBlank;
|
|
int32_t pcmFreq;
|
|
int32_t divFreq;
|
|
uint32_t cgbChans;
|
|
uint32_t func;
|
|
uint32_t intp;
|
|
uint32_t cgbSound;
|
|
uint32_t cgbOscOff;
|
|
uint32_t midiKeyToCgbFreq;
|
|
uint32_t mPlayJumpTable;
|
|
uint32_t plynote;
|
|
uint32_t extVolPit;
|
|
uint8_t gap2[16];
|
|
struct GBAMP2kSoundChannel chans[MP2K_MAX_SOUND_CHANNELS];
|
|
};
|
|
|
|
struct GBAMP2kMusicPlayerInfo {
|
|
uint32_t songHeader;
|
|
uint32_t status;
|
|
uint8_t trackCount;
|
|
uint8_t priority;
|
|
uint8_t cmd;
|
|
uint8_t unk_B;
|
|
uint32_t clock;
|
|
uint8_t gap[8];
|
|
uint32_t memAccArea;
|
|
uint16_t tempoD;
|
|
uint16_t tempoU;
|
|
uint16_t tempoI;
|
|
uint16_t tempoC;
|
|
uint16_t fadeOI;
|
|
uint16_t fadeOC;
|
|
uint16_t fadeOV;
|
|
uint32_t tracks;
|
|
uint32_t tone;
|
|
uint32_t magic;
|
|
uint32_t func;
|
|
uint32_t intp;
|
|
};
|
|
|
|
struct GBAMP2kInstrument {
|
|
uint8_t type;
|
|
uint8_t key;
|
|
uint8_t length;
|
|
union {
|
|
uint8_t pan;
|
|
uint8_t sweep;
|
|
} ps;
|
|
union {
|
|
uint32_t waveData;
|
|
uint32_t subTable;
|
|
} data;
|
|
union {
|
|
struct GBAMP2kADSR adsr;
|
|
uint32_t map;
|
|
} extInfo;
|
|
};
|
|
|
|
struct GBAMP2kMusicPlayerTrack {
|
|
uint8_t flags;
|
|
uint8_t wait;
|
|
uint8_t patternLevel;
|
|
uint8_t repN;
|
|
uint8_t gateTime;
|
|
uint8_t key;
|
|
uint8_t velocity;
|
|
uint8_t runningStatus;
|
|
uint8_t keyM;
|
|
uint8_t pitM;
|
|
int8_t keyShift;
|
|
int8_t keyShiftX;
|
|
int8_t tune;
|
|
uint8_t pitX;
|
|
int8_t bend;
|
|
uint8_t bendRange;
|
|
uint8_t volMR;
|
|
uint8_t volML;
|
|
uint8_t vol;
|
|
uint8_t volX;
|
|
int8_t pan;
|
|
int8_t panX;
|
|
int8_t modM;
|
|
uint8_t mod;
|
|
uint8_t modT;
|
|
uint8_t lfoSpeed;
|
|
uint8_t lfoSpeedC;
|
|
uint8_t lfoDelay;
|
|
uint8_t lfoDelayC;
|
|
uint8_t priority;
|
|
uint8_t echoVolume;
|
|
uint8_t echoLength;
|
|
uint32_t chan;
|
|
struct GBAMP2kInstrument instrument;
|
|
uint8_t gap[10];
|
|
uint16_t unk_3A;
|
|
uint32_t unk_3C;
|
|
uint32_t cmdPtr;
|
|
uint32_t patternStack[3];
|
|
};
|
|
|
|
struct GBAMP2kTrack {
|
|
struct GBAMP2kMusicPlayerTrack track;
|
|
struct GBAMP2kSoundChannel* channel;
|
|
uint8_t lastCommand;
|
|
struct CircleBuffer buffer;
|
|
uint32_t samplePlaying;
|
|
float currentOffset;
|
|
bool waiting;
|
|
};
|
|
|
|
struct GBAAudioMixer {
|
|
struct mCPUComponent d;
|
|
struct GBAAudio* p;
|
|
|
|
uint32_t contextAddress;
|
|
|
|
bool (*engage)(struct GBAAudioMixer* mixer, uint32_t address);
|
|
void (*vblank)(struct GBAAudioMixer* mixer);
|
|
void (*step)(struct GBAAudioMixer* mixer);
|
|
|
|
struct GBAMP2kContext context;
|
|
struct GBAMP2kMusicPlayerInfo player;
|
|
struct GBAMP2kTrack activeTracks[MP2K_MAX_SOUND_CHANNELS];
|
|
|
|
double tempo;
|
|
double frame;
|
|
|
|
struct GBAStereoSample last;
|
|
};
|
|
|
|
void GBAAudioInit(struct GBAAudio* audio, size_t samples);
|
|
void GBAAudioReset(struct GBAAudio* audio);
|
|
void GBAAudioDeinit(struct GBAAudio* audio);
|
|
|
|
void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples);
|
|
|
|
void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info);
|
|
|
|
void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUND2CNT_LO(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUND2CNT_HI(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUND3CNT_LO(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUND3CNT_HI(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUND3CNT_X(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUND4CNT_LO(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value);
|
|
void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value);
|
|
|
|
void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value);
|
|
uint32_t GBAAudioReadWaveRAM(struct GBAAudio* audio, int address);
|
|
uint32_t GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value);
|
|
void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles);
|
|
|
|
struct GBASerializedState;
|
|
void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state);
|
|
void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state);
|
|
|
|
float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRatio);
|
|
|
|
CXX_GUARD_END
|
|
|
|
#endif
|