mirror of
https://github.com/birth1mark/orbis8.git
synced 2026-10-28 23:00:29 +01:00
122 lines
4.1 KiB
C++
122 lines
4.1 KiB
C++
#pragma once
|
|
|
|
#include "PicoRam.h"
|
|
#include "synth.h"
|
|
|
|
#include <string>
|
|
|
|
#define MAX_SFX = 64
|
|
#define BYTES_PER_SFX = 68;
|
|
|
|
#define MAX_MUSIC = 64
|
|
#define BYTES_PER_MUSIC = 4;
|
|
|
|
//best info about sfx/music and differences between cart and memory that I've found
|
|
//https://github.com/dansanderson/picotool:
|
|
/*
|
|
|
|
MUSIC:
|
|
The music region consists of 256 bytes. The .p8 representation is one
|
|
line for each of 64 patterns, with a hex-encoded flags byte, a space,
|
|
and four hex-encoded one-byte sound numbers.
|
|
The flags are:
|
|
1: begin pattern loop
|
|
2: end pattern loop
|
|
4: stop at end of pattern
|
|
The sound numbers represents four channels played simultaneously up to
|
|
the shortest pattern. The sounds are numbered 0 through 63
|
|
(0x00-0x3f). If a channel is silent for a song pattern, its number is
|
|
64 + the channel number (0x41, 0x42, 0x43, or 0x44).
|
|
The in-memory (and PNG) representation is slightly different from the
|
|
.p8 representation. Instead of storing the flags in a separate byte,
|
|
the flags are stored in the highest bit of the first three channels,
|
|
for a total of four bytes:
|
|
chan1 & 128: stop at end of pattern
|
|
chan2 & 128: end pattern loop
|
|
chan3 & 128: begin pattern loop
|
|
|
|
SFX:
|
|
The sound effects region consists of 4352 bytes. The .p8
|
|
representation is 64 lines of 168 hexadecimal digits (84 bytes).
|
|
Each line represents one sound effect/music pattern. The values are as follows:
|
|
0 The editor mode: 0 for pitch mode, 1 for note entry mode.
|
|
1 The note duration, in multiples of 1/128 second.
|
|
2 Loop range start, as a note number (0-63).
|
|
3 Loop range end, as a note number (0-63).
|
|
4-84 32 notes:
|
|
0: pitch (0-63): c-0 to d#-5, chromatic scale
|
|
1-high: waveform (0-F):
|
|
0 sine, 1 triangle, 2 sawtooth, 3 long square, 4 short square,
|
|
5 ringing, 6 noise, 7 ringing sine; 8-F are the custom instruments
|
|
corresponding to sfx 0-7
|
|
1-low: volume (0-7)
|
|
2-high: effect (0-7):
|
|
0 none, 1 slide, 2 vibrato, 3 drop, 4 fade_in, 5 fade_out,
|
|
6 arp fast, 7 arp slow; arpeggio commands loop over groups of
|
|
four notes at speed 2 (fast) and 4 (slow)
|
|
One note uses five nibbles, so two notes use five bytes.
|
|
The RAM representation is different. Each pattern is 68 bytes, with
|
|
two bytes for each of 32 notes, one byte for the editor mode, one byte
|
|
for the speed, and two bytes for the loop range (start, end). Each
|
|
note is encoded in 16 bits, LSB first, like so:
|
|
w2-w1-pppppp c-eee-vvv-w3
|
|
eee: effect (0-7)
|
|
vvv: volume (0-7)
|
|
w3w2w1: waveform (0-7)
|
|
pppppp: pitch (0-63)
|
|
c: if 1, waveform is a custom instrument corresponding to sfx 0-7;
|
|
otherwise it's one of the eight built-in waveforms
|
|
(Considering waveform as a value from 0-15, c is w4.)
|
|
|
|
*/
|
|
//todo: make these memory compatible later, but for now, this representation
|
|
//is easier for me to wrap my mind araound
|
|
|
|
//this is also defined in audio? should probably consolidate
|
|
|
|
enum
|
|
{
|
|
FX_NO_EFFECT = 0,
|
|
FX_SLIDE = 1,
|
|
FX_VIBRATO = 2,
|
|
FX_DROP = 3,
|
|
FX_FADE_IN = 4,
|
|
FX_FADE_OUT = 5,
|
|
FX_ARP_FAST = 6,
|
|
FX_ARP_SLOW = 7,
|
|
};
|
|
|
|
|
|
class Audio {
|
|
PicoRam* _memory;
|
|
audioState_t _audioState;
|
|
bool _paused;
|
|
|
|
void set_music_pattern(int pattern);
|
|
void update_sfx_state(sfx_state& cur_sfx, z8::synth_param& new_synth,
|
|
float freq_factor, float length, bool is_music,
|
|
bool can_loop, bool half_rate, double inv_frames_per_second);
|
|
float get_synth_sample(z8::synth_param& params);
|
|
void launch_sfx(int16_t sfx, int16_t chan, float offset, float length, bool is_music);
|
|
|
|
public:
|
|
Audio(PicoRam* memory);
|
|
|
|
void resetAudioState();
|
|
audioState_t* getAudioState();
|
|
|
|
int api_sfx(int sfx, int channel, int offset, int length);
|
|
void api_music(int pattern, int16_t fade_len, int16_t mask);
|
|
|
|
int16_t getCurrentSfxId(int channel);
|
|
int getCurrentNoteNumber(int channel);
|
|
int16_t getCurrentMusic();
|
|
int16_t getMusicPatternCount();
|
|
int16_t getMusicTickCount();
|
|
|
|
void FillAudioBuffer(void *audioBuffer,size_t offset, size_t size);
|
|
void FillMonoAudioBuffer(void *audioBuffer,size_t offset, size_t size);
|
|
|
|
void setPaused(bool paused);
|
|
};
|