Alchemy
Loading...
Searching...
No Matches

audio_engine_types.h

Go to the documentation of this file.
1#ifndef ALCHEMY_AUDIO_ENGINE_TYPES_H
2#define ALCHEMY_AUDIO_ENGINE_TYPES_H
3
4/// @file
5/// The sound driver's types, registers and work.
6
7#include "types.h"
9
10#define SOUND_LOCK 0x68736D53
11
12#define SOUND_WORK (*(struct SoundWork **)0x03007FF0)
13
14#define REG_NR10 (*(volatile u8 *)0x04000060)
15#define REG_NR11 (*(volatile u8 *)0x04000062)
16#define REG_NR12 (*(volatile u8 *)0x04000063)
17#define REG_NR13 (*(volatile u8 *)0x04000064)
18#define REG_NR14 (*(volatile u8 *)0x04000065)
19#define REG_NR21 (*(volatile u8 *)0x04000068)
20#define REG_NR22 (*(volatile u8 *)0x04000069)
21#define REG_NR23 (*(volatile u8 *)0x0400006c)
22#define REG_NR24 (*(volatile u8 *)0x0400006d)
23#define REG_NR30 (*(volatile u8 *)0x04000070)
24#define REG_NR31 (*(volatile u8 *)0x04000072)
25#define REG_NR32 (*(volatile u8 *)0x04000073)
26#define REG_NR33 (*(volatile u8 *)0x04000074)
27#define REG_NR34 (*(volatile u8 *)0x04000075)
28#define REG_NR41 (*(volatile u8 *)0x04000078)
29#define REG_NR42 (*(volatile u8 *)0x04000079)
30#define REG_NR43 (*(volatile u8 *)0x0400007c)
31#define REG_NR44 (*(volatile u8 *)0x0400007d)
32#define REG_NR51 (*(volatile u8 *)0x04000081)
33
34#define REG_NR50 (*(volatile u8 *)0x04000080)
35#define REG_SOUNDCNT_L (*(volatile u16 *)0x04000080)
36#define REG_SOUNDCNT_X (*(volatile u16 *)0x04000084)
37#define SOUNDCNT_X_ENABLE 0x80
38#define SOUNDCNT_X_ALL_TONES_ON 0x0f
39#define REG_SOUNDBIAS_H (*(volatile u8 *)0x04000089)
40#define REG_WAVE_RAM ((volatile u32 *)0x04000090)
41
42struct SoundNote;
43struct CgbNote;
44struct SoundPlayer;
45struct SoundTrack;
46
47/// A command table entry: the driver calls it with the player and the track.
48typedef void (*SoundCommand)(struct SoundPlayer *player,
49 struct SoundTrack *track);
50/// Converts between SoundCommand and a table entry that takes other
51/// parameters, through the generic function type so neither cast warns.
52#define SOUND_COMMAND_CAST(type, routine) ((type)(void (*)(void))(routine))
53
54/// Entries of gSound_CommandTable, in gSound_CommandTableTemplate's order. A
55/// song byte from 0xB1 to 0xCE runs entry (byte - 0xB1) for its track; bytes
56/// from 0xCF up start notes through the work's noteOn instead, so entries 30
57/// to 35 are the driver's helper tail, reached only by its own calls. Unused
58/// entries hold MusicTrack_FinishSequence.
59///@{
60/// Byte 0xB1: ends the track, releasing and unlinking its notes.
61#define SOUND_COMMAND_FINISH 0
62#define SOUND_COMMAND_GOTO 1 ///< Byte 0xB2: jumps to the address after it.
63/// Byte 0xB9, installed by CgbAudio_Initialize: an operation, a work byte and
64/// an operand; sets, adds to or compares a byte of the player's workBytes
65/// (SoundTrackWorkOperation), jumping like GOTO when a comparison holds.
66#define SOUND_COMMAND_WORK_BYTE 8
67/// Byte 0xC2: sets lfoSpeed from the next byte; 0 clears the modulation.
68#define SOUND_COMMAND_LFO_SPEED 17
69/// Byte 0xC4: sets modDepth from the next byte; 0 clears the modulation.
70#define SOUND_COMMAND_MODULATION 19
71/// Byte 0xCD, installed by CgbAudio_Initialize: runs the entry of
72/// gSound_ExtendedCommandTable the next byte names (voice fields, tail level
73/// and length).
74#define SOUND_COMMAND_EXTENDED 28
75/// Byte 0xCE: releases the track's sounding note of the key given (or of its
76/// last key when no key byte follows).
77#define SOUND_COMMAND_RELEASE_KEY 29
78#define SOUND_COMMAND_PCM_RATE 30 ///< AudioEngine_SetPcmRate.
79/// MusicTrack_Stop: silences the track's notes and empties its list.
80#define SOUND_COMMAND_STOP_TRACK 31
81#define SOUND_COMMAND_FADE 32 ///< MusicPlayer_StepFade: a frame of a fade.
82#define SOUND_COMMAND_CALCULATE_OUTPUT 33 ///< MusicTrack_CalcOutput.
83/// SoundNote_Detach: unlinks a note from its track's list
84/// (AudioCommand_InvokeSlot34).
85#define SOUND_COMMAND_DETACH_NOTE 34
86/// SoundDriver_ClearBuffer: zeroes the first 64 bytes of a player or track
87/// (AudioCommand_InvokeSlot35).
88#define SOUND_COMMAND_CLEAR_WORK 35
89///@}
90
92 /// The PCM notes in SoundWork.pcmNotes; mode changes and
93 /// AudioEngine_StopAllChannels clear all 12, though only pcmNoteCount play.
95 SOUND_CGB_CHANNEL_COUNT = 4, ///< CGB channels, numbered 1 to 4.
96 /// Most tracks a player takes; MusicPlayer_Initialize caps its count here,
97 /// and the track masks of the MusicPlayer_Set routines are 16 bits.
99};
100
105};
106
108
109#define SOUND_FADE_FULL_VOLUME 0x100
110#define SOUND_FADE_STEP 16
111
112/// A voice a track plays its notes with: its kind and base key, the sample or
113/// wave it plays, and its attack, decay, sustain and release.
115 /// bits: 7 rhythm | 6 key split | 3 fixed rate for PCM, bias rounding for
116 /// CGB | 2..0 CGB channel (0 PCM).
117 /// A rhythm or split voice plays an entry of the voice table at target,
118 /// chosen by the key (rhythm) or through the key map that attack's four
119 /// bytes point to (split).
121 u8 baseKey; ///< Key a rhythm entry plays every note at.
122 u8 length; ///< CGB sound length (NRx1); 0 plays until released.
123 /// CGB channel 1's sweep (NR10) when bit 7 is clear and bits 6..4 are not;
124 /// else no sweep. In a rhythm entry with bit 7 set, the note's pan is
125 /// (value - 192) * 2.
127 /// The PCM sample, the CGB wave pattern, duty or noise width, or for a
128 /// rhythm or split voice its voice table.
129 const void *target;
130 /// PCM: added to the envelope each frame until 255. CGB: frames a step.
131 /// In a split voice, these four bytes are a pointer to its key map.
133 u8 decay; ///< PCM: envelope * decay / 256 a frame. CGB: frames a step.
134 u8 sustain; ///< Level decay stops at: 0 to 255 for PCM, 0 to 15 for CGB.
135 u8 release; ///< PCM: envelope * release / 256 a frame. CGB: frames a step.
136};
137
138/// A PCM note, one of 12 the mixer renders: its state and envelope, its
139/// output levels, and its links to the other notes of its track. A track's
140/// note list holds CGB notes through this type too; the names from 0x0a to
141/// 0x1c come from the CGB layout (CgbNote).
142struct SoundNote {
143 /// 0 when free. bits: 7 start | 6 released | 4 looping | 2 echo |
144 /// 1..0 phase (3 attack, 2 decay, 1 sustain, 0 release).
146 u8 kind; ///< The voice's kind; bits 2..0 nonzero for a CGB note.
147 u8 outRight; ///< Velocity and track volume to the right, 0 to 255.
148 u8 outLeft; ///< Velocity and track volume to the left, 0 to 255.
149 u8 unk04[2]; ///< The voice's attack (0x04) and decay (0x05).
150 u8 sustain; ///< The voice's sustain level.
151 /// The voice's release (0x07), the key played (0x08) and the envelope level,
152 /// 0 to 255 (0x09).
154 /// For a PCM note, the mixer writes the envelope's right level here each
155 /// frame; the name comes from CgbNote.peak.
157 /// 0x0b left level, 0x0c echo level, 0x0d echo frames, 0x10 gate in ticks,
158 /// 0x11 the song's key, 0x12 velocity, 0x13 priority, 0x14 rhythm pan;
159 /// the mixer keeps a PCM note's samples left in the word at 0x18.
160 u8 unk0b[0x0e];
161 /// CgbNote.sustainLevel; inside the samples-left word for a PCM note.
163 u8 unk1a; ///< Inside the samples-left word for a PCM note.
164 u8 panBits; ///< CgbNote.panBits; inside the samples-left word for a PCM note.
165 /// CgbNote.channelBits; for a PCM note, the mixer's fractional sample
166 /// position is the word at 0x1c.
168 /// 0x1d CGB update bits, 0x1e CGB length, 0x1f CGB sweep, 0x20 the word
169 /// frequency, 0x24 the voice's target (the sample), 0x28 the next sample
170 /// byte (mixer).
171 u8 unk1d[0x0f];
172 /// The track whose list holds this note; NULL once detached.
174 /// The note started after this one in the track's list (nearer its head);
175 /// NULL at the head.
177 /// The note started before this one in the track's list; NULL at the end.
179 u8 unk38[8]; ///< Not named by TBS code.
180};
181
182/// A note on one of the four CGB channels of the hardware: its state and
183/// envelope, its levels and pan, its frequency and its wave.
184struct CgbNote {
185 u8 state; ///< CgbNoteState and CgbNotePhase; 0 when the channel is free.
186 /// Channel number 1 to 4 at setup, then the voice's kind; bit 3 rounds
187 /// the frequency to the sound bias's resolution on channels 1 to 3.
189 u8 outRight; ///< Velocity and track volume to the right, 0 to 255.
190 u8 outLeft; ///< Velocity and track volume to the left, 0 to 255.
191 u8 attack; ///< Frames per attack step.
192 u8 decay; ///< Frames per decay step.
193 u8 sustain; ///< Sustain level 0 to 15, scaled by peak.
194 u8 release; ///< Frames per release step.
195 u8 key; ///< The key played, before the track's pitch.
196 u8 level; ///< Envelope level 0 to 15 written to the channel.
197 /// Top of the envelope: (outRight + outLeft) / 16, at most 15 when one
198 /// side plays.
200 u8 counter; ///< Frames left in the current envelope step.
201 u8 echoLevel; ///< After release, the level held is peak * echoLevel / 256.
202 u8 echoLength; ///< Frames the echo lasts.
203 /// 0x10 gate in ticks, 0x11 the song's key, 0x12 velocity, 0x13 priority
204 /// (a new note of higher priority takes the channel), 0x14 rhythm pan.
205 u8 unk0e[0x0b];
206 u8 sustainLevel; ///< (peak * sustain + 15) / 16.
207 u8 trigger; ///< Value for NRx4: 7 restart, 6 length on, 2..0 frequency.
208 u8 panBits; ///< NR51 bits this note sets: one side or both.
209 u8 channelBits; ///< This channel's NR51 bits: 0x11, 0x22, 0x44, 0x88.
210 u8 modified; ///< CgbNoteModified: what to write to the channel.
211 u8 length; ///< The voice's length.
212 u8 sweep; ///< Channel 1's NR10 sweep; 8 when none.
213 /// Tone frequency from Cgb_KeyToFrequency (2048 added), or channel 4's
214 /// NR43 value.
216 /// Channel 3: the 16-byte wave pattern. Channels 1 and 2: the duty, into
217 /// NRx1's bits 7..6. Channel 4: the width, into NR43's bit 3.
219 u32 *loadedWave; ///< Channel 3: the pattern last copied into wave RAM.
220 /// 0x2c track, 0x30 prev and 0x34 next, as in SoundNote.
221 u8 unk2c[0x14];
222};
223
230};
231
237};
238
240
248};
249
251
271};
272
273/// A track of a playing song: the song commands it runs, its voice and notes,
274/// and the pitch, volume, pan and modulation it gives them.
276 /// SoundTrackFlag. bits: 7 active | 6 reset | 3..2 pitch to update |
277 /// 1..0 volume to update.
279 /// 0x01 ticks until the next command, 0x02 pattern depth (0 to 3), 0x03
280 /// repeat count, 0x04 gate of the last note in ticks, 0x05 its key, 0x06
281 /// its velocity, 0x07 the last command byte from 0xBD up, which a byte
282 /// below 0x80 repeats.
284 /// Whole semitones of the track's pitch, read as signed and added to each
285 /// note's key (a sum below 0 plays key 0).
287 /// The pitch's fraction, 0 to 255 in 1/256 semitone, passed as the fine
288 /// pitch to the key-to-frequency step.
290 s8 keyOffsetA; ///< Semitones, from the song's key-shift command.
291 s8 keyOffsetB; ///< Semitones, from MusicPlayer_SetPitch.
292 s8 tune; ///< The tune command's byte - 64: 1/64 semitone.
293 u8 fine; ///< 1/256 semitone, from MusicPlayer_SetPitch.
294 s8 bend; ///< The bend command's byte - 64: full bend is bendRange.
295 u8 bendRange; ///< Semitones a full bend reaches; 2 at reset.
296 u8 outVolumeA; ///< Right volume: (pan + 128) * scaled volume / 256.
297 u8 outVolumeB; ///< Left volume: (127 - pan) * scaled volume / 256.
298 u8 volume; ///< The song's volume command, scaled by volumeScale / 32.
299 /// 0 to 64 (full, the reset value): a player volume or fade level of 0 to
300 /// 0x100 divided by 4.
302 s8 pan; ///< The pan command's byte - 64, -64 to 63; doubled for output.
303 s8 panOffset; ///< Added to the doubled pan, from MusicPlayer_SetPan.
304 /// The LFO's output, modDepth * wave / 64: added to the pitch in 1/16
305 /// semitone, to the pan, or scaling the volume by (amount + 128) / 128.
307 /// 0 to 255, from the modulation command or MusicPlayer_SetModulationDepth;
308 /// 0 stops the LFO and clears modAmount.
310 u8 modTarget; ///< SoundModulationTarget.
311 /// LFO phase step a tick, 22 at reset; 0 stops the LFO and clears modAmount.
313 /// 0 to 255, wrapping; the wave is phase over 0 to 63, 128 - phase over 64
314 /// to 191 and phase - 256 over 192 to 255, so -64 to 64.
316 /// 0x1b LFO delay in ticks (song command), 0x1c its countdown, reloaded by
317 /// each note, 0x1d track priority added to the player's for its notes.
319 u8 tailLevel; ///< Each new note's echo level.
320 u8 tailLength; ///< Each new note's echo length in frames.
321 /// The notes this track started, newest first, linked through
322 /// SoundNote.next; PCM notes from SoundWork.pcmNotes and CGB notes. NULL
323 /// ends the list or leaves it empty.
325 /// Copied from the player's voice table by the voice command, or set a field
326 /// at a time by extended commands.
328 /// Not named by TBS code; zeroed with the first 64 bytes at reset.
329 u8 unk30[0x10];
330 /// The next command byte in the song's data, from the header's track
331 /// pointer; a track's commands end at a finish command (0xB1).
332 const u8 *cursor;
333 /// Cursors to return to after each of up to three nested patterns.
334 u8 unk44[0x0c];
335};
336
337/// A song's header: its track count, priority and mode, its voices, and where
338/// each track's commands start.
340 u8 trackCount; ///< At most 16; 0 in the empty songs.
341 u8 unk01; ///< 0 in every song; ags-music refuses another block count.
342 u8 priority; ///< Becomes the player's priority.
343 /// With bit 7 set, passed to AudioEngine_SetMode (bits 6..0 the reverb);
344 /// ags-music's reverb field.
346 const struct SoundVoice *voices; ///< The voice table its tracks choose from.
347 const u8 *tracks[1]; ///< Each track's first command, trackCount of them.
348};
349
350/// A player, which plays one song: its header and status, its tracks, its
351/// tempo and fade.
353 const struct SequenceHeader *header; ///< The song playing or last played.
354 /// bits: 31 paused | 15..0 tracks active after the last tick. Set to
355 /// SOUND_PLAYER_PAUSED alone when no track is left.
357 u8 trackCount; ///< Tracks this player owns, at most 16.
358 u8 priority; ///< The song's priority.
359 u8 unk0a; ///< The last command run: its byte - 0xB1.
360 /// Nonzero: a song of lower priority does not replace a playing one. From
361 /// gSound_PlayerSlots, 0 for every player.
363 u32 ticks; ///< Song ticks played since the song started.
364 u8 unk10[8]; ///< Not named by TBS code.
365 u8 *workBytes; ///< gSound_WorkBytes, which the work-byte command uses.
366 u16 tempo; ///< Twice the tempo command's byte; 150 at start.
367 u16 tempoScale; ///< 256 plays at the song's tempo.
368 /// tempo * tempoScale / 256, added to tempoCount each frame.
370 /// Each 150 in it runs one tick, so a tempoStep of 150 is a tick a frame.
372 u16 fadePeriod; ///< Frames between fade steps; 0 when not fading.
373 u16 fadeCounter; ///< Frames left until the next fade step.
374 /// bits: 8..4 level, 0 to 0x100 in steps of 16 | 1 fade in | 0 pause at the
375 /// end (SoundFadeFlag).
377 u8 unk2a[2]; ///< Not named by TBS code.
378 struct SoundTrack *tracks; ///< trackCount tracks.
379 const struct SoundVoice *voices; ///< The song's voice table.
380 /// SOUND_LOCK when free; raised while the player is changed or ticked.
382 /// The tick routine and player that were first in the chain before this
383 /// player was added; this player's tick runs them first.
384 void (*nextTick)(struct SoundPlayer *player);
385 struct SoundPlayer *nextTickPlayer; ///< Passed to nextTick.
386};
387
388/// The sound driver's work: its lock, the mixer's rate and buffers, the PCM
389/// and CGB notes, and the routines the driver calls.
390struct SoundWork {
391 u32 lock; ///< SOUND_LOCK when free; raised while the driver changes it.
392 /// Frames until the VBlank DMA restart, which reloads it from
393 /// transferPeriod; also picks the frame of the buffers being mixed.
394 /* FAKEMATCH: volatile steers library C only: without it
395 * AudioEngine_ResumeDirectSound: differ 9 in tbs-en, 22 instructions for 23.
396 */
398 u8 reverb; ///< 0 to 127 (mode bits 6..0); 0 skips the reverb pass.
399 u8 pcmNoteCount; ///< PCM notes in use, 8 at start (mode bits 11..8).
400 u8 volume; ///< PCM volume 0 to 15, 15 at start (mode bits 15..12).
401 u8 rate; ///< 1 to 12, indexes gSound_FrameLengths (mode bits 19..16).
402 u8 unk09; ///< Not named by TBS code.
403 /// Counts 14 down to 0 once a CGB update; at 0 the envelopes take an extra
404 /// step.
406 u8 transferPeriod; ///< Frames the buffers hold: 0x630 / frameSamples.
407 /// Nonzero: the mixer stops taking notes once the scanline passes this
408 /// many lines after its start. Sound_MaxLines, 0.
410 u8 unk0d[3]; ///< Not named by TBS code.
411 u32 frameSamples; ///< Samples mixed a frame, from gSound_FrameLengths.
412 u32 outputRate; ///< Samples a second: frameSamples * 59.7275, rounded.
413 /// 2^23 / outputRate, rounded; a note's frequency times it is its step a
414 /// sample.
416 struct CgbNote *cgbNotes; ///< gSound_CgbNotes; NULL before CGB setup.
417 /// First of the chain of player ticks run each mixer frame; NULL for none.
418 void (*tick)(struct SoundPlayer *player);
419 struct SoundPlayer *tickPlayer; ///< Passed to tick.
420 void (*cgbUpdate)(void); ///< Run each mixer frame: Cgb_UpdateChannels.
421 void (*cgbMute)(u8 channel); ///< CgbChannel_Mute, channel 1 to 4.
422 s32 (*cgbFrequency)(u8 kind, u8 key, u8 fine); ///< Cgb_KeyToFrequency.
423 SoundCommand *commands; ///< gSound_CommandTable.
424 /// MusicTrack_HandleNote, run for song bytes from 0xCF up with the byte
425 /// - 0xCF.
426 void (*noteOn)(u32 command, struct SoundPlayer *player,
427 struct SoundTrack *track);
428 /// Set to Audio_EmptyCallback by AudioEngine_Initialize; no TBS code reads
429 /// it by name.
430 void (*unk3c)(void);
431 u8 unk40[0x10]; ///< Not named by TBS code.
432 struct SoundNote pcmNotes[12]; ///< pcmNoteCount of them play.
433 /// Right (0, DMA 1 to FIFO A) and left (1, DMA 2 to FIFO B) samples,
434 /// transferPeriod frames of frameSamples each.
435 s8 buffers[2][0x630];
436};
437
438/// An entry of the player table: a player, its tracks and track count, and
439/// its priority check.
442 struct SoundTrack *tracks; ///< trackCount tracks for the player.
444 u8 unk09; ///< 0 in every entry; not named by TBS code.
445 u16 checkPriority; ///< Copied to the player's checkPriority; 0 everywhere.
446};
447
448/// An entry of the song table: a song's header and the player table entry
449/// that plays it.
450struct SongEntry {
451 const struct SequenceHeader *header;
452 /// Index into gSound_PlayerSlots; AudioCommand_Play gives slot 7's songs
453 /// the first player from 7 down to 4 with no active track, else 7.
455 u16 unk06; ///< The same value as slot in every entry; not named by TBS code.
456};
457
458STATIC_ASSERT(sizeof(struct SoundVoice) == 12);
459STATIC_ASSERT(sizeof(struct SoundNote) == 64);
460STATIC_ASSERT(sizeof(struct CgbNote) == 64);
461STATIC_ASSERT(offsetof(struct CgbNote, frequency) == 0x20);
462STATIC_ASSERT(offsetof(struct CgbNote, wave) == 0x24);
463STATIC_ASSERT(sizeof(struct SoundTrack) == 80);
464STATIC_ASSERT(offsetof(struct SoundTrack, voice) == 0x24);
465STATIC_ASSERT(offsetof(struct SoundTrack, cursor) == 0x40);
466STATIC_ASSERT(sizeof(struct SoundPlayer) == 64);
467STATIC_ASSERT(offsetof(struct SoundWork, cgbNotes) == 0x1c);
468STATIC_ASSERT(sizeof(struct SoundWork) == 0xfb0);
469
470void CgbAudio_Initialize(struct CgbNote *notes);
471void CgbNote_UpdatePanEnvelope(struct CgbNote *note);
472void MusicTrack_ReadVoiceTarget(struct SoundPlayer *player,
473 struct SoundTrack *track);
475 struct SoundTrack *track);
476void AudioCommand_InvokeSlot34(struct SoundNote *note);
477void AudioCommand_InvokeSlot35(void *block);
478
479void MusicPlayer_StartSong(struct SoundPlayer *player,
480 const struct SequenceHeader *header);
481void MusicPlayer_FadeOut(struct SoundPlayer *player, u16 speed);
483 u16 scale);
484void MusicPlayer_SetVolume(struct SoundPlayer *player, u16 mask, u16 volume);
485void MusicPlayer_SetPitch(struct SoundPlayer *player, u16 mask, s16 pitch);
486void MusicPlayer_SetPan(struct SoundPlayer *player, u16 mask, s8 pan);
487void MusicPlayer_SetModulationDepth(struct SoundPlayer *player, s32 mask,
488 s32 value);
489void MusicPlayer_SetLfoSpeed(struct SoundPlayer *player, u32 mask, u32 value);
490void MusicTrack_ClearModulation(struct SoundTrack *track);
491
492extern const struct PlayerSlot gSound_PlayerSlots[];
493extern const struct SongEntry gSound_SongTable[];
496
497#endif
void CgbAudio_Initialize(struct CgbNote *notes)
Resets the CGB sound hardware, installs the CGB-aware command handlers and callbacks in the sound wor...
Definition audio.c:272
const struct PlayerSlot gSound_PlayerSlots[]
void MusicPlayer_StartSong(struct SoundPlayer *player, const struct SequenceHeader *header)
Starts a song when its priority permits, resetting its tracks and tempo.
Definition engine.c:282
void MusicPlayer_FadeOut(struct SoundPlayer *player, u16 speed)
Begins the standard stop-and-clear fade.
Definition audio.c:228
SoundCommand gSound_CommandTable[36]
const struct SongEntry gSound_SongTable[]
SoundPlayerFlag
@ SOUND_PLAYER_PAUSED
SoundTrackWorkOperation
@ SOUND_WORK_GREATER_BYTE
@ SOUND_WORK_NOT_EQUAL_BYTE
@ SOUND_WORK_LESS_EQUAL_BYTE
@ SOUND_WORK_NOT_EQUAL
@ SOUND_WORK_SET
@ SOUND_WORK_GREATER
@ SOUND_WORK_SUBTRACT
@ SOUND_WORK_ADD
@ SOUND_WORK_SUBTRACT_BYTE
@ SOUND_WORK_LESS
@ SOUND_WORK_ADD_BYTE
@ SOUND_WORK_LESS_BYTE
@ SOUND_WORK_EQUAL
@ SOUND_WORK_GREATER_EQUAL
@ SOUND_WORK_GREATER_EQUAL_BYTE
@ SOUND_WORK_LESS_EQUAL
@ SOUND_WORK_EQUAL_BYTE
@ SOUND_WORK_COPY
@ CGB_PHASE_RELEASE
@ CGB_PHASE_SUSTAIN
@ CGB_PHASE_ATTACK
@ CGB_PHASE_DECAY
@ SOUND_FADE_PAUSE
@ SOUND_FADE_IN
@ SOUND_TRACK_RESET
@ SOUND_TRACK_PITCH_DIRTY
@ SOUND_TRACK_UPDATE_VOLUME
@ SOUND_TRACK_ACTIVE
@ SOUND_TRACK_UPDATE_PITCH
@ SOUND_TRACK_VOLUME_DIRTY
SoundDriverLimit
@ SOUND_PLAYER_TRACK_LIMIT
Most tracks a player takes; MusicPlayer_Initialize caps its count here, and the track masks of the Mu...
@ SOUND_CGB_CHANNEL_COUNT
CGB channels, numbered 1 to 4.
@ SOUND_PCM_NOTE_CAPACITY
The PCM notes in SoundWork.pcmNotes; mode changes and AudioEngine_StopAllChannels clear all 12,...
SoundModulationTarget
@ SOUND_MODULATION_VOLUME
@ SOUND_MODULATION_PITCH
@ SOUND_MODULATION_PAN
CgbNoteModified
@ CGB_NOTE_PITCH_DIRTY
@ CGB_NOTE_VOLUME_DIRTY
@ CGB_NOTE_START
@ CGB_NOTE_ON
@ CGB_NOTE_PHASE
@ CGB_NOTE_STOP
@ CGB_NOTE_ECHO
void MusicPlayer_SetPitch(struct SoundPlayer *player, u16 mask, s16 pitch)
Sets the semitone and fractional pitch offsets of selected active tracks and marks their pitch for re...
Definition engine.c:828
void MusicPlayer_SetLfoSpeed(struct SoundPlayer *player, u32 selectedTracks, u32 speedArgument)
Sets LFO speed on selected active tracks, resetting modulation when stopped.
Definition engine.c:925
void MusicPlayer_SetModulationDepth(struct SoundPlayer *player, s32 selectedTracks, s32 depthArgument)
Sets modulation depth on selected active tracks, resetting zero-depth modulation.
Definition engine.c:894
void CgbNote_UpdatePanEnvelope(struct CgbNote *note)
Chooses stereo routing and derives peak and sustain levels for a CGB note, writing them into note.
Definition engine.c:509
void AudioCommand_InvokeSlot34(struct SoundNote *note)
Detaches a note through the command table entry installed by the driver.
Definition engine.c:7
void MusicTrack_DispatchStreamCommand(struct SoundPlayer *player, struct SoundTrack *track)
Reads an extended-command index and invokes its handler.
Definition engine.c:1049
void MusicPlayer_SetPitchAndUpdateFrequency(struct SoundPlayer *player, u16 scale)
Sets the tempo multiplier and updates the number of ticks advanced per frame.
Definition engine.c:787
UNUSED void MusicPlayer_SetPan(struct SoundPlayer *player, u16 mask, s8 pan)
Sets the stereo pan offset of selected active tracks.
Definition engine.c:856
void AudioCommand_InvokeSlot35(void *block)
Clears a 64-byte player or track prefix through the driver command table.
Definition engine.c:19
void MusicTrack_ClearModulation(struct SoundTrack *track)
Resets the LFO phase and amount, marking the affected output for recalculation.
Definition engine.c:883
void MusicTrack_ReadVoiceTarget(struct SoundPlayer *player, struct SoundTrack *track)
Reads an unaligned little-endian voice target address from the sequence.
Definition engine.c:1078
void MusicPlayer_SetVolume(struct SoundPlayer *player, u16 mask, u16 volume)
Sets the volume scale of active tracks selected by the bit mask and marks their output for recalculat...
Definition engine.c:800
STATIC_ASSERT, a compile-time check that emits nothing.
#define STATIC_ASSERT(condition)
C89 permits repeated extern declarations of the same array.
#define offsetof(type, member)
Definition stddef.h:19
A note on one of the four CGB channels of the hardware: its state and envelope, its levels and pan,...
u8 attack
Frames per attack step.
u8 channelBits
This channel's NR51 bits: 0x11, 0x22, 0x44, 0x88.
u32 frequency
Tone frequency from Cgb_KeyToFrequency (2048 added), or channel 4's NR43 value.
u8 echoLevel
After release, the level held is peak * echoLevel / 256.
u8 outLeft
Velocity and track volume to the left, 0 to 255.
u8 release
Frames per release step.
u8 trigger
Value for NRx4: 7 restart, 6 length on, 2..0 frequency.
u8 echoLength
Frames the echo lasts.
u8 sweep
Channel 1's NR10 sweep; 8 when none.
u8 length
The voice's length.
u8 level
Envelope level 0 to 15 written to the channel.
u8 counter
Frames left in the current envelope step.
u8 peak
Top of the envelope: (outRight + outLeft) / 16, at most 15 when one side plays.
u8 modified
CgbNoteModified: what to write to the channel.
u8 panBits
NR51 bits this note sets: one side or both.
u32 * loadedWave
Channel 3: the pattern last copied into wave RAM.
u8 unk2c[0x14]
0x2c track, 0x30 prev and 0x34 next, as in SoundNote.
u8 state
CgbNoteState and CgbNotePhase; 0 when the channel is free.
u8 sustain
Sustain level 0 to 15, scaled by peak.
u8 key
The key played, before the track's pitch.
u8 decay
Frames per decay step.
u8 sustainLevel
(peak * sustain + 15) / 16.
u8 outRight
Velocity and track volume to the right, 0 to 255.
u8 unk0e[0x0b]
0x10 gate in ticks, 0x11 the song's key, 0x12 velocity, 0x13 priority (a new note of higher priority ...
u8 kind
Channel number 1 to 4 at setup, then the voice's kind; bit 3 rounds the frequency to the sound bias's...
u32 * wave
Channel 3: the 16-byte wave pattern.
An entry of the player table: a player, its tracks and track count, and its priority check.
struct SoundTrack * tracks
trackCount tracks for the player.
struct SoundPlayer * player
u8 unk09
0 in every entry; not named by TBS code.
u16 checkPriority
Copied to the player's checkPriority; 0 everywhere.
A song's header: its track count, priority and mode, its voices, and where each track's commands star...
u8 trackCount
At most 16; 0 in the empty songs.
u8 mode
With bit 7 set, passed to AudioEngine_SetMode (bits 6..0 the reverb); ags-music's reverb field.
const u8 * tracks[1]
Each track's first command, trackCount of them.
u8 unk01
0 in every song; ags-music refuses another block count.
u8 priority
Becomes the player's priority.
const struct SoundVoice * voices
The voice table its tracks choose from.
An entry of the song table: a song's header and the player table entry that plays it.
u16 slot
Index into gSound_PlayerSlots; AudioCommand_Play gives slot 7's songs the first player from 7 down to...
u16 unk06
The same value as slot in every entry; not named by TBS code.
const struct SequenceHeader * header
A PCM note, one of 12 the mixer renders: its state and envelope, its output levels,...
u8 outRight
Velocity and track volume to the right, 0 to 255.
u8 kind
The voice's kind; bits 2..0 nonzero for a CGB note.
u8 unk07[3]
The voice's release (0x07), the key played (0x08) and the envelope level, 0 to 255 (0x09).
u8 peak
For a PCM note, the mixer writes the envelope's right level here each frame; the name comes from CgbN...
u8 channelBits
CgbNote.channelBits; for a PCM note, the mixer's fractional sample position is the word at 0x1c.
u8 unk0b[0x0e]
0x0b left level, 0x0c echo level, 0x0d echo frames, 0x10 gate in ticks, 0x11 the song's key,...
u8 unk04[2]
The voice's attack (0x04) and decay (0x05).
u8 panBits
CgbNote.panBits; inside the samples-left word for a PCM note.
u8 outLeft
Velocity and track volume to the left, 0 to 255.
u8 state
0 when free.
struct SoundNote * prev
The note started after this one in the track's list (nearer its head); NULL at the head.
u8 unk1a
Inside the samples-left word for a PCM note.
u8 unk1d[0x0f]
0x1d CGB update bits, 0x1e CGB length, 0x1f CGB sweep, 0x20 the word frequency, 0x24 the voice's targ...
u8 sustain
The voice's sustain level.
u8 sustainLevel
CgbNote.sustainLevel; inside the samples-left word for a PCM note.
struct SoundNote * next
The note started before this one in the track's list; NULL at the end.
struct SoundTrack * track
The track whose list holds this note; NULL once detached.
u8 unk38[8]
Not named by TBS code.
A player, which plays one song: its header and status, its tracks, its tempo and fade.
const struct SequenceHeader * header
The song playing or last played.
u8 checkPriority
Nonzero: a song of lower priority does not replace a playing one.
u16 tempoStep
tempo * tempoScale / 256, added to tempoCount each frame.
u8 unk10[8]
Not named by TBS code.
u16 fadeCounter
Frames left until the next fade step.
u8 unk0a
The last command run: its byte - 0xB1.
u32 ticks
Song ticks played since the song started.
u16 tempoCount
Each 150 in it runs one tick, so a tempoStep of 150 is a tick a frame.
u8 unk2a[2]
Not named by TBS code.
u16 fadeVolume
bits: 8..4 level, 0 to 0x100 in steps of 16 | 1 fade in | 0 pause at the end (SoundFadeFlag).
u32 status
bits: 31 paused | 15..0 tracks active after the last tick.
void(*) nextTick(struct SoundPlayer *player)
The tick routine and player that were first in the chain before this player was added; this player's ...
u8 priority
The song's priority.
u8 trackCount
Tracks this player owns, at most 16.
u16 tempoScale
256 plays at the song's tempo.
u8 * workBytes
gSound_WorkBytes, which the work-byte command uses.
u16 tempo
Twice the tempo command's byte; 150 at start.
const struct SoundVoice * voices
The song's voice table.
u32 lock
SOUND_LOCK when free; raised while the player is changed or ticked.
struct SoundPlayer * nextTickPlayer
Passed to nextTick.
struct SoundTrack * tracks
trackCount tracks.
u16 fadePeriod
Frames between fade steps; 0 when not fading.
A track of a playing song: the song commands it runs, its voice and notes, and the pitch,...
u8 bendRange
Semitones a full bend reaches; 2 at reset.
s8 bend
The bend command's byte - 64: full bend is bendRange.
s8 modAmount
The LFO's output, modDepth * wave / 64: added to the pitch in 1/16 semitone, to the pan,...
u8 unk44[0x0c]
Cursors to return to after each of up to three nested patterns.
u8 unk01[7]
0x01 ticks until the next command, 0x02 pattern depth (0 to 3), 0x03 repeat count,...
u8 pitchHi
Whole semitones of the track's pitch, read as signed and added to each note's key (a sum below 0 play...
u8 pitchLo
The pitch's fraction, 0 to 255 in 1/256 semitone, passed as the fine pitch to the key-to-frequency st...
u8 tailLevel
Each new note's echo level.
u8 lfoSpeed
LFO phase step a tick, 22 at reset; 0 stops the LFO and clears modAmount.
struct SoundNote * notes
The notes this track started, newest first, linked through SoundNote.next; PCM notes from SoundWork....
u8 outVolumeB
Left volume: (127 - pan) * scaled volume / 256.
u8 outVolumeA
Right volume: (pan + 128) * scaled volume / 256.
struct SoundVoice voice
Copied from the player's voice table by the voice command, or set a field at a time by extended comma...
u8 unk1b[3]
0x1b LFO delay in ticks (song command), 0x1c its countdown, reloaded by each note,...
s8 pan
The pan command's byte - 64, -64 to 63; doubled for output.
u8 fine
1/256 semitone, from MusicPlayer_SetPitch.
s8 tune
The tune command's byte - 64: 1/64 semitone.
const u8 * cursor
The next command byte in the song's data, from the header's track pointer; a track's commands end at ...
u8 flags
SoundTrackFlag.
u8 volume
The song's volume command, scaled by volumeScale / 32.
u8 unk30[0x10]
Not named by TBS code; zeroed with the first 64 bytes at reset.
u8 modDepth
0 to 255, from the modulation command or MusicPlayer_SetModulationDepth; 0 stops the LFO and clears m...
u8 modTarget
SoundModulationTarget.
u8 tailLength
Each new note's echo length in frames.
u8 lfoPhase
0 to 255, wrapping; the wave is phase over 0 to 63, 128 - phase over 64 to 191 and phase - 256 over 1...
s8 panOffset
Added to the doubled pan, from MusicPlayer_SetPan.
s8 keyOffsetB
Semitones, from MusicPlayer_SetPitch.
u8 volumeScale
0 to 64 (full, the reset value): a player volume or fade level of 0 to 0x100 divided by 4.
s8 keyOffsetA
Semitones, from the song's key-shift command.
A voice a track plays its notes with: its kind and base key, the sample or wave it plays,...
const void * target
The PCM sample, the CGB wave pattern, duty or noise width, or for a rhythm or split voice its voice t...
u8 attack
PCM: added to the envelope each frame until 255.
u8 decay
PCM: envelope * decay / 256 a frame. CGB: frames a step.
u8 panOrSweep
CGB channel 1's sweep (NR10) when bit 7 is clear and bits 6..4 are not; else no sweep.
u8 release
PCM: envelope * release / 256 a frame. CGB: frames a step.
u8 kind
bits: 7 rhythm | 6 key split | 3 fixed rate for PCM, bias rounding for CGB | 2..0 CGB channel (0 PCM)...
u8 baseKey
Key a rhythm entry plays every note at.
u8 length
CGB sound length (NRx1); 0 plays until released.
u8 sustain
Level decay stops at: 0 to 255 for PCM, 0 to 15 for CGB.
The sound driver's work: its lock, the mixer's rate and buffers, the PCM and CGB notes,...
s32(*) cgbFrequency(u8 kind, u8 key, u8 fine)
Cgb_KeyToFrequency.
u8 pcmNoteCount
PCM notes in use, 8 at start (mode bits 11..8).
void(*) unk3c(void)
Set to Audio_EmptyCallback by AudioEngine_Initialize; no TBS code reads it by name.
u8 reverb
0 to 127 (mode bits 6..0); 0 skips the reverb pass.
u8 volume
PCM volume 0 to 15, 15 at start (mode bits 15..12).
s8 buffers[2][0x630]
Right (0, DMA 1 to FIFO A) and left (1, DMA 2 to FIFO B) samples, transferPeriod frames of frameSampl...
struct SoundPlayer * tickPlayer
Passed to tick.
u32 lock
SOUND_LOCK when free; raised while the driver changes it.
u8 rate
1 to 12, indexes gSound_FrameLengths (mode bits 19..16).
u8 unk0d[3]
Not named by TBS code.
u32 frameSamples
Samples mixed a frame, from gSound_FrameLengths.
struct SoundNote pcmNotes[12]
pcmNoteCount of them play.
u32 rateStep
2^23 / outputRate, rounded; a note's frequency times it is its step a sample.
struct CgbNote * cgbNotes
gSound_CgbNotes; NULL before CGB setup.
void(*) noteOn(u32 command, struct SoundPlayer *player, struct SoundTrack *track)
MusicTrack_HandleNote, run for song bytes from 0xCF up with the byte.
u8 maxLines
Nonzero: the mixer stops taking notes once the scanline passes this many lines after its start.
void(*) cgbUpdate(void)
Run each mixer frame: Cgb_UpdateChannels.
u8 unk09
Not named by TBS code.
void(*) cgbMute(u8 channel)
CgbChannel_Mute, channel 1 to 4.
SoundCommand * commands
gSound_CommandTable.
u32 outputRate
Samples a second: frameSamples * 59.7275, rounded.
volatile u8 transferCountdown
Frames until the VBlank DMA restart, which reloads it from transferPeriod; also picks the frame of th...
void(*) tick(struct SoundPlayer *player)
First of the chain of player ticks run each mixer frame; NULL for none.
u8 transferPeriod
Frames the buffers hold: 0x630 / frameSamples.
u8 cgbTick
Counts 14 down to 0 once a CGB update; at 0 the envelopes take an extra step.
u8 unk40[0x10]
Not named by TBS code.
void(*) SoundCommand(struct SoundPlayer *player, struct SoundTrack *track)
A command table entry: the driver calls it with the player and the track.
Definition tables.c:11
const SoundCommand gSound_ExtendedCommandTable[]
Extended commands; entries zero and three do nothing.
Definition tables.c:178
The integer types, TRUE, UNUSED and the fixed-address macros.
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed char s8
Definition types.h:10
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
unsigned char u8
Definition types.h:11