test_music.c
5.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/*************************************************************
test_music.c : Nintendo 64 Music Tools Library Sample
(c) Copyright 1998, Software Creations (Holdings) Ltd.
Version 3.11
CROSSFADE demo music related file. This demo illustrates how
to use the library with samples based in RAM as opposed to
ROM.
**************************************************************/
/* include system header files */
#ifndef F3DEX_GBI
#define F3DEX_GBI
#endif
#include <ultra64.h>
#include <libmus.h>
/* include current header file */
#include "test_rom.h"
#define FADE_VALUE 4 /* volume change value per frame */
/* internal workspace */
unsigned long current_handle=0;
unsigned long last_handle=0;
int current_volume;
int last_volume;
/* internal function prototypes */
static void DmaRomToRam(void *rom, void *ram, int len);
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
[GLOBAL FUNCTION]
InitMusicDriver()
[Explantion]
Download ROM files and initialise the music player.
[Return value]
NONE
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* ROM addresses */
#define WBANK_START _wbankSegmentRomStart
#define PBANK_START _pbankSegmentRomStart
#define PBANK_END _pbankSegmentRomEnd
#define MUSIC1_START _tune1SegmentRomStart
#define MUSIC1_END _tune1SegmentRomEnd
#define MUSIC2_START _tune2SegmentRomStart
#define MUSIC2_END _tune2SegmentRomEnd
extern char WBANK_START[];
extern char PBANK_START[];
extern char PBANK_END[];
extern char MUSIC1_START[];
extern char MUSIC1_END[];
extern char MUSIC2_START[];
extern char MUSIC2_END[];
/* permanent RAM buffers */
#define AUDIO_HEAP_SIZE 300000
#define PBANK_SIZE 50000
#define TUNE_SIZE 10000
unsigned char audio_memory [AUDIO_HEAP_SIZE];
unsigned char pointer_buf [PBANK_SIZE];
/* make sure tune is 32bit aligned */
unsigned int tune_buf1 [TUNE_SIZE/sizeof(int)];
unsigned int tune_buf2 [TUNE_SIZE/sizeof(int)];
void InitMusicDriver(void)
{
musConfig init;
/* download .ptr file and song files to RAM */
DmaRomToRam(PBANK_START, pointer_buf, PBANK_END-PBANK_START);
DmaRomToRam(MUSIC1_START, (unsigned char *)tune_buf1, MUSIC1_END-MUSIC1_START);
DmaRomToRam(MUSIC2_START, (unsigned char *)tune_buf2, MUSIC2_END-MUSIC2_START);
/* setup configuration structure */
init.control_flag = 0;
init.channels = 28; /* lots of channels! */
init.sched = ≻
init.thread_priority = 12;
init.heap = audio_memory;
init.heap_length = AUDIO_HEAP_SIZE;
init.fifo_length = 64;
init.ptr = pointer_buf;
init.wbk = WBANK_START;
init.default_fxbank = NULL;
init.syn_output_rate = 44100;
init.syn_updates = 256;
init.syn_rsp_cmds = 4096;
init.syn_retraceCount= 1;
init.syn_num_dma_bufs= 36;
init.syn_dma_buf_size= 0x800;
MusInitialize(&init);
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
[GLOBAL FUNCTION]
FadeSongStart(song)
[Explantion]
Start a song, fading the old one down if one exists.
[Parameters]
song address of song to start
[Return value]
NONE
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
void FadeSongStart(void *song)
{
if (current_handle)
{
if (last_handle)
{
MusHandleStop(last_handle, 0);
while (MusHandleAsk(last_handle));
}
last_handle = current_handle;
last_volume = current_volume;
}
current_handle = MusStartSong(song);
current_volume = 0;
MusHandleSetVolume(current_handle, current_volume);
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
[GLOBAL FUNCTION]
FadeSongProcess()
[Explantion]
Process the fading of songs volume levels.
[Return value]
NONE
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
void FadeSongProcess(void)
{
if (last_handle)
{
last_volume-=FADE_VALUE;
if (last_volume<=0)
{
last_volume = 0;
MusHandleStop(last_handle, 0);
}
else
{
MusHandleSetVolume(last_handle, last_volume);
}
}
if (current_handle)
{
if (current_volume<0x80)
{
current_volume+=FADE_VALUE;
if (current_volume>0x80)
current_volume=0x80;
MusHandleSetVolume(current_handle, current_volume);
}
}
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
[INTERNAL FUNCTION]
DmaRomToRam(rom, ram, len)
[Parameters]
rom address of ROM source
ram address of RAM destination
len number of bytes to transfer
[Explantion]
Download an area of ROM to RAM. Note this function limits the size of any DMA
generated to 16k so as to cause clashes with audio DMAs.
[Return value]
NONE
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* avoid DMA clashes */
#define DMA_LEN 16384
static void DmaRomToRam(void *rom, void *ram, int len)
{
OSIoMesg io_mesg;
OSMesg dummyMesg;
int length;
u32 src;
unsigned char *dest;
src = (u32)rom;
dest = ram;
while (len)
{
if (len>DMA_LEN)
length = DMA_LEN;
else
length = len;
osInvalDCache(dest, length);
osPiStartDma(&io_mesg, OS_MESG_PRI_NORMAL, OS_READ, src, dest, length, &dma_queue);
osRecvMesg(&dma_queue, &dummyMesg, OS_MESG_BLOCK);
src+=length;
dest+=length;
len-=length;
}
}
/* end of file */