1 Star 1 Fork 0

羽名/agb_music_xm

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
agbmusic.h 16.06 KB
一键复制 编辑 原始数据 按行查看 历史
羽名 提交于 2021-03-25 21:20 . 用来生成agb的音乐到xm(fastTracker)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
#ifndef AGBMUSIC_H__
#define AGBMUSIC_H__
#include <stdint.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef struct {
u8 d[80];
} MusicPlayerTrack;
typedef struct {
u16 type; //Type
//这些数据表明一个类型。这是目前使用的需要。
//总是0x0000
u16 stat; //Status
//目前,非循环(1)的波形是0x0000和正向循环0x40000
//如果循环波形0x4000,如果1次波形值0x0000
u32 freq; //Frequency Calculation Value
//这个值是用来计算频率,他是由以下公式计算 sampling rate * 2^((180 - (midi键<基础键,默认为60>))/12)
u32 loop; //Loop Start Point
//循环的指针(循环开始)
//循环的位置计算从采样数据的开始
u32 size; //Sampling Number
//样本数(结束位置)
s8 data[1]; //Sampling Data Order
//实际波形数据,以(样本数+1)字节的8bit有符号线性非压缩的数据,最后一个字节是非循环波形的0,和相同的值作为一个循环波形指针数据
//
} WaveData;
typedef struct {
//0x0
/*
typ:
0 乐器采样频率会随着mid而改变
8 不会随着mid键而改变采样频率
att:默认(0xff)
dec:衰减值(0)
sus:持续值(ff)
rel:释放值(e2)
att会被设置为 ch[9]
ch 为SoundChannel 结构体
但按下note的时候,会把Nxx设置到ch[0x10]中
ch[0x10]为释放tick时间 (这个时间跟Wxx的时间是一样的)
持续一段时间后,当ch[0x10]==0时,
ch[0]被设置为释放(relese)状态
每帧执行一次
ch[9] = (ch[9] * rel)>>8
ch[9] 为音量
也就是说,但Note抬起时(Nxx时间后),执行处理
ch[9] = (ch[9] * rel)>>8
att,dec,sus三者关系
当按下att时,会进行一个dec过程,直到音量维持在sus,抬起时,再处理rel
*/
u8 typ; //Type 类型
u8 key; //Original Key 原始的键
//
u8 len; //Sound Length (Compatible Sound) 声音的长度(兼容的声音)
u8 p_s; //Pan or Sweep (Compatible Sound 1)
WaveData *wav; //Wave Data Address wave地址
u8 att; //Attack 打击
u8 dec; //Decay 衰变
u8 sus; //Sustain 维持
u8 rel; //Release 释放
} ToneData;
typedef struct {
struct SongHeader *song; //Current Song Pointer 当前歌曲指针
u32 stat; //Status 状态
u8 mtrk; //Track Number 磁道数
u8 prio; //Current Priority 当前优先权
u8 d1[2];
u32 clock; //Calculation Clock from Performance Start 时钟开始计算性能
u8 d2[48]; //:0x10+32 = 0x42
} MusicPlayerArea;
typedef struct {
MusicPlayerArea *ma;
MusicPlayerTrack *ta;
u32 tn;
} MPlayTable;
typedef struct{
/*
0x80的时候,会从
data(ToneDataArr)那查找音色,并且不会改变声音频率
*/
u8 type; //0x80;
u8 z1,z2,z3;
ToneData *data;
u32 base_note;
}_0x80;
typedef struct {
/*
0x40会随着mid而更改采样频率
*/
u32 typ /*0x40*/;
//ToneData *ta; //应该是ToneDataArr
union ToneDataArr *ta;
/*键对应的音色索引,
[0]=0
[1]=0
表示 C1, C#1 对应第0个音色
[2]=1
[3]=1
表示 D1, D#1 对应第1个音色
*/
u8 *st;
} SplitTone;
typedef union ToneDataArr{ ToneData t; SplitTone s; _0x80 ref; } ToneDataArr;
typedef struct SongHeader{
u8 trks; //Track Number 磁道数
u8 blks; //Block Number 块编号
u8 prio; //Priority 优先权
u8 rvrb; //Reverb 混响
//ToneData *tone; //Tone Table 音表
ToneDataArr *tone;
u8 *part[1];
} SongHeader;
typedef struct {
SongHeader *so;
/*ms表示使用播放器索引*/
u16 ms, me;
} SongTable;
/*
类型,
0x00:表示采样文件
0x40:表示slpt
0x08:固定间隔(Interval fixed),不会根据key更改频率
0x80:节奏设置(Rhythm set) ,引用其他ToneData*
; type : A(0x00) Direct sound
; F(0x01) Direct sound (Interval fixed)
; P() CGB compatible sound (Interval preferred)
; Q(0x10) CGB compatible sound (Tone color preferred)
; R(0x80) Rhythm set
; S(0x40) Key split tone color
*/
#define TONEDATA_TYP_RHY 0x80
#define TONEDATA_TYP_SPL 0x40
#define TONEDATA_TYP_FIX 0x08
#define TONEDATA_TYP_CGB 0x07
/*
定义
*/
#define W00 0x80 /*WAIT */
#define W01 (W00+1)
#define W02 (W00+2)
#define W03 (W00+3)
#define W04 (W00+4)
#define W05 (W00+5)
#define W06 (W00+6)
#define W07 (W00+7)
#define W08 (W00+8)
#define W09 (W00+9)
#define W10 (W00+10)
#define W11 (W00+11)
#define W12 (W00+12)
#define W13 (W00+13)
#define W14 (W00+14)
#define W15 (W00+15)
#define W16 (W00+16)
#define W17 (W00+17)
#define W18 (W00+18)
#define W19 (W00+19)
#define W20 (W00+20)
#define W21 (W00+21)
#define W22 (W00+22)
#define W23 (W00+23)
#define W24 (W00+24)
#define W28 (W00+25)
#define W30 (W00+26)
#define W32 (W00+27)
#define W36 (W00+28)
#define W40 (W00+29)
#define W42 (W00+30)
#define W44 (W00+31)
#define W48 (W00+32)
#define W52 (W00+33)
#define W54 (W00+34)
#define W56 (W00+35)
#define W60 (W00+36)
#define W64 (W00+37)
#define W66 (W00+38)
#define W68 (W00+39)
#define W72 (W00+40)
#define W76 (W00+41)
#define W78 (W00+42)
#define W80 (W00+43)
#define W84 (W00+44)
#define W88 (W00+45)
#define W90 (W00+46)
#define W92 (W00+47)
#define W96 (W00+48)
//fine
#define FINE 0xb1
//goto 跳转
#define GOTO 0xb2
//pattern play 格局播放
#define PATT 0xb3
//pattern end 格局结束
#define PEND 0xb4
//repeat 重复
#define REPT 0xb5
//memacc op adr dat ***lib
#define MEMACC 0xb9
//priority 优先级
#define PRIO 0xba
//tempo (BPM/2) 节奏 (BPM/2)
#define TEMPO 0xbb
//key shift 键变化
#define KEYSH 0xbc
// voice # 声音
#define VOICE 0xbd
// volume 音量
#define VOL 0xbe
// panpot (c_v+??)
#define PAN 0xbf
// pitch bend (c_v+??) 音高
#define BEND 0xc0
// bend range 弯曲范围
/*
滑音范围,可以用(xm)
Portamento up
1xx 替代
8000A9C: [R5+9] 会作为MidiKey2fr的第3个参数
MusicPlayerTrack->d[0xf] = BENDR
*/
#define BENDR 0xc1
// LFO speed 低频振荡速度
#define LFOS 0xc2
// LFO delay 低频振荡衰减
#define LFODL 0xc3
// modulation depth 调制深度
#define MOD 0xc4
// modulation type 调制类型
#define MODT 0xc5
// micro tuning (c_v+??) 微调
#define TUNE 0xc8
#define _PORT 0xcc
// extend command ***lib 扩展指令,库
#define XCMD 0xcd
// imi.echo vol ***lib
#define xIECV 0x08
// imi.echo len ***lib
#define xIECL 0x09
// End of Tie
#define EOT 0xce
#define TIE 0xcf //
// NOTE
#define N01 (TIE+1)
#define N02 (N01+1) //
#define N03 (N01+2) //
#define N04 (N01+3) //
#define N05 (N01+4) //
#define N06 (N01+5) //
#define N07 (N01+6) //
#define N08 (N01+7) //
#define N09 (N01+8) //
#define N10 (N01+9) //
#define N11 (N01+10) //
#define N12 (N01+11) //
#define N13 (N01+12) //
#define N14 (N01+13) //
#define N15 (N01+14) //
#define N16 (N01+15) //
#define N17 (N01+16) //
#define N18 (N01+17) //
#define N19 (N01+18) //
#define N20 (N01+19) //
#define N21 (N01+20) //
#define N22 (N01+21) //
#define N23 (N01+22) //
#define N24 (N01+23) //
#define N28 (N01+24) //
#define N30 (N01+25) //
#define N32 (N01+26) //
#define N36 (N01+27) //
#define N40 (N01+28) //
#define N42 (N01+29) //
#define N44 (N01+30) //
#define N48 (N01+31) //
#define N52 (N01+32) //
#define N54 (N01+33) //
#define N56 (N01+34) //
#define N60 (N01+35) //
#define N64 (N01+36) //
#define N66 (N01+37) //
#define N68 (N01+38) //
#define N72 (N01+39) //
#define N76 (N01+40) //
#define N78 (N01+41) //
#define N80 (N01+42) //
#define N84 (N01+43) //
#define N88 (N01+44) //
#define N90 (N01+45) //
#define N92 (N01+46) //
#define N96 (N01+47) //
static const char* note_w_name[] = {
"N01","N02", //
"N03", //
"N04", //
"N05", //
"N06", //
"N07", //
"N08", //
"N09", //
"N10", //
"N11", //
"N12", //
"N13", //
"N14", //
"N15", //
"N16", //
"N17", //
"N18", //
"N19", //
"N20", //
"N21", //
"N22", //
"N23", //
"N24", //
"N28", //
"N30", //
"N32", //
"N36", //
"N40", //
"N42", //
"N44", //
"N48", //
"N52", //
"N54", //
"N56", //
"N60", //
"N64", //
"N66", //
"N68", //
"N72", //
"N76", //
"N78", //
"N80", //
"N84", //
"N88", //
"N90", //
"N92", //
"N96", //
};
//Max value of operators 运算最大值
#define mxv 0x7F
//center value of PAN, BEND, TUNE
#define c_v 0x40
#define CnM2 0
#define CsM2 1
#define DnM2 2
#define DsM2 3
#define EnM2 4
#define FnM2 5
#define FsM2 6
#define GnM2 7
#define GsM2 8
#define AnM2 9
#define AsM2 10
#define BnM2 11
#define CnM1 12
#define CsM1 13
#define DnM1 14
#define DsM1 15
#define EnM1 16
#define FnM1 17
#define FsM1 18
#define GnM1 19
#define GsM1 20
#define AnM1 21
#define AsM1 22
#define BnM1 23
#define Cn0 24
#define Cs0 25
#define Dn0 26
#define Ds0 27
#define En0 28
#define Fn0 29
#define Fs0 30
#define Gn0 31
#define Gs0 32
#define An0 33
#define As0 34
#define Bn0 35
#define Cn1 36
#define Cs1 37
#define Dn1 38
#define Ds1 39
#define En1 40
#define Fn1 41
#define Fs1 42
#define Gn1 43
#define Gs1 44
#define An1 45
#define As1 46
#define Bn1 47
#define Cn2 48
#define Cs2 49
#define Dn2 50
#define Ds2 51
#define En2 52
#define Fn2 53
#define Fs2 54
#define Gn2 55
#define Gs2 56
#define An2 57
#define As2 58
#define Bn2 59
//默认的声音频率
#define Cn3 60
#define Cs3 61
#define Dn3 62
#define Ds3 63
#define En3 64
#define Fn3 65
#define Fs3 66
#define Gn3 67
#define Gs3 68
//440Hz
#define An3 69
#define As3 70
#define Bn3 71
#define Cn4 72
#define Cs4 73
#define Dn4 74
#define Ds4 75
#define En4 76
#define Fn4 77
#define Fs4 78
#define Gn4 79
#define Gs4 80
#define An4 81
#define As4 82
#define Bn4 83
#define Cn5 84
#define Cs5 85
#define Dn5 86
#define Ds5 87
#define En5 88
#define Fn5 89
#define Fs5 90
#define Gn5 91
#define Gs5 92
#define An5 93
#define As5 94
#define Bn5 95
#define Cn6 96
#define Cs6 97
#define Dn6 98
#define Ds6 99
#define En6 100
#define Fn6 101
#define Fs6 102
#define Gn6 103
#define Gs6 104
#define An6 105
#define As6 106
#define Bn6 107
#define Cn7 108
#define Cs7 109
#define Dn7 110
#define Ds7 111
#define En7 112
#define Fn7 113
#define Fs7 114
#define Gn7 115
#define Gs7 116
#define An7 117
#define As7 118
#define Bn7 119
#define Cn8 120
#define Cs8 121
#define Dn8 122
#define Ds8 123
#define En8 124
#define Fn8 125
#define Fs8 126
#define Gn8 127
static const char* note_name[] = {
"CnM2",
"CsM2",
"DnM2",
"DsM2",
"EnM2",
"FnM2",
"FsM2",
"GnM2",
"GsM2",
"AnM2",
"AsM2",
"BnM2",
"CnM1",
"CsM1",
"DnM1",
"DsM1",
"EnM1",
"FnM1",
"FsM1",
"GnM1",
"GsM1",
"AnM1",
"AsM1",
"BnM1",
"Cn0",
"Cs0",
"Dn0",
"Ds0",
"En0",
"Fn0",
"Fs0",
"Gn0",
"Gs0",
"An0",
"As0",
"Bn0",
"Cn1",
"Cs1",
"Dn1",
"Ds1",
"En1",
"Fn1",
"Fs1",
"Gn1",
"Gs1",
"An1",
"As1",
"Bn1",
"Cn2",
"Cs2",
"Dn2",
"Ds2",
"En2",
"Fn2",
"Fs2",
"Gn2",
"Gs2",
"An2",
"As2",
"Bn2",
"Cn3",
"Cs3",
"Dn3",
"Ds3",
"En3",
"Fn3",
"Fs3",
"Gn3",
"Gs3",
"An3",
"As3",
"Bn3",
"Cn4",
"Cs4",
"Dn4",
"Ds4",
"En4",
"Fn4",
"Fs4",
"Gn4",
"Gs4",
"An4",
"As4",
"Bn4",
"Cn5",
"Cs5",
"Dn5",
"Ds5",
"En5",
"Fn5",
"Fs5",
"Gn5",
"Gs5",
"An5",
"As5",
"Bn5",
"Cn6",
"Cs6",
"Dn6",
"Ds6",
"En6",
"Fn6",
"Fs6",
"Gn6",
"Gs6",
"An6",
"As6",
"Bn6",
"Cn7",
"Cs7",
"Dn7",
"Ds7",
"En7",
"Fn7",
"Fs7",
"Gn7",
"Gs7",
"An7",
"As7",
"Bn7",
"Cn8",
"Cs8",
"Dn8",
"Ds8",
"En8",
"Fn8",
"Fs8",
"Gn8",
};
//Virtual Channel Structure
typedef struct {
u8 sf; //Status //状态
/*声道状态的指示
* 当声音是停止时,是0
* 启动声音,设置其他参数,写入0x80到这里
* 停止声音,逻辑或0x40 释放按下(key-off),或者写一个零暂停,使用其他位是禁止的
*/
u8 ty; //Type //类型
/*一个正常的声音,是0x00
* 如果音乐间隔是不计算和声音在高速计算则设置0x08
*
*/
u8 rv; //Right Volume //右声量
u8 lv; //Left Volume //左声量
u8 at; //Attack //按下的信号,声音开始,在0和1/60s 当它是255,一个过程的动作下一个衰减值
//敲击声音的时间 (255/x)*(1/60s),设置范围0-255
u8 de; //Decay //一个衰减值的信号,他由一个 value/256 每个1/60s,当到达过程是维持值,维持动作的状态
//衰减 (当前音量)*(x/256)每1/60s,如果小于或等于维持量,将维持现状
u8 su; //Sustain //维持值的信号,这声音是由(实际 rv/256,lv/256 和输出左右)
//维持量设置
u8 re; //Release //释放值的信号,key-off(逻辑或0x40在sf中)在state中,这个值是由 value/256 每 1/60s,这声道是完全停止
//释放 (当前音量)*(x/256)每1/60s,如果小于或等于伪回声的音量,它转移到伪回声状态。
u8 r1[24]; // (reserved) : //(u32)r1[0x10]为数据大小
/*r[4] 伪回声的音量([ 4 ]不是数量的元素,这是件#)
*r[5] 伪回声长度([ 5 ]不是数量的元素,这是件#)
*
*
**r[0x10],波形大小?
*
* }
* 伪回声是一个可靠的固定量是一个固定的时间释放结束后剩余的。设置音量0-255和长度之间的0-127。时间的声音保持量长度乘以1 / 60秒。此外,如果您要使用的伪回声(体积!= 0),长度为计算下来,所以你需要再次设置它为每一个声音。
*/
u32 fr; //Frequency Calculation Value :0x20 //产生的频率的声音,写入midikey2freq的值在这里
//
WaveData *wp; //Wave Pointer
//指针到声音的波形数据。生成的波形数据可以自动从使用工具(aif2agb.exe AIFF文件),所以用户通常不需要自己创建它。
//这个设置指针的波形数据结构描述
u32 r3[6]; // (reserved) r3[0]当前声音数据偏移
} SoundChannel;
enum{
soundchannel_stat_release = 0x40, //当释放时
};
//parameter of gate+
#define gtp1 1
#define gtp2 2
#define gtp3 3
//parameter of MODT, BRET
// vibrate
#define mod_vib 0
// tremolo
#define mod_tre 1
// auto-panpot
#define mod_pan 2
//***
// parameter of MEMACC
//******************************************************@
#define mem_set 0
#define mem_add 1
#define mem_sub 2
#define mem_mem_set 3
#define mem_mem_add 4
#define mem_mem_sub 5
#define mem_beq 6
#define mem_bne 7
#define mem_bhi 8
#define mem_bhs 9
#define mem_bls 10
#define mem_blo 11
#define mem_mem_beq 12
#define mem_mem_bne 13
#define mem_mem_bhi 14
#define mem_mem_bhs 15
#define mem_mem_bls 16
#define mem_mem_blo 17
//@ SOUND_MODE_REVERB_SET
//声音模式混响设置
#define reverb_set 0x80
#endif
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/uyami/agb_music_xm.git
git@gitee.com:uyami/agb_music_xm.git
uyami
agb_music_xm
agb_music_xm
master

搜索帮助