1 /* ASNDLIB -> accelerated sound lib using the DSP
3 Copyright (c) 2008 Hermes <www.entuwii.net>
6 Redistribution and use in source and binary forms, with or without modification, are
7 permitted provided that the following conditions are met:
9 - Redistributions of source code must retain the above copyright notice, this list of
10 conditions and the following disclaimer.
11 - Redistributions in binary form must reproduce the above copyright notice, this list
12 of conditions and the following disclaimer in the documentation and/or other
13 materials provided with the distribution.
14 - The names of the contributors may not be used to endorse or promote products derived
15 from this software without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
25 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #define ASND_LIB 0x100
36 #define SND_LIB (ASND_LIB+2)
47 #define SND_INVALID -1
48 #define SND_ISNOTASONGVOICE -2
51 // SND_IsActiveVoice additional return values
53 #define SND_UNUSED 0 // you can use this voice
54 #define SND_WORKING 1 // this voice is in progress
55 #define SND_WAITING 2 // this voice is in progress and waiting to one SND_AddVoice function (the voice handler is called continuously)
57 // SND_SetVoice format
58 #define VOICE_MONO_8BIT 0
59 #define VOICE_MONO_16BIT 1
60 #define VOICE_STEREO_8BIT 2
61 #define VOICE_STEREO_16BIT 3
67 #define MID_VOLUME 127
68 #define MAX_VOLUME 255
72 #define MIN_PITCH 1 // 1 Hz
74 #define F44100HZ_PITCH 44100 // 44100Hz
76 #define MAX_PITCH 144000 // 144000Hz (more process time for pitch>48000)
78 #define INIT_RATE_48000
124 #define NOTE(note,octave) (note+(octave<<3)+(octave<<2)) // final note codification. Used in Note2Freq()
126 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
128 // compat with SNDLIB
130 #define Note2Freq ANote2Freq
131 #define SND_Init ASND_Init
132 #define SND_End ASND_End
133 #define SND_Pause ASND_Pause
134 #define SND_Is_Paused ASND_Is_Paused
135 #define SND_GetTime ASND_GetTime
136 #define SND_GetSampleCounter ASND_GetSampleCounter
137 #define SND_GetSamplesPerTick ASND_GetSamplesPerTick
138 #define SND_SetTime ASND_SetTime
139 #define SND_SetCallback ASND_SetCallback
140 #define SND_GetAudioRate ASND_GetAudioRate
141 #define SND_SetVoice ASND_SetVoice
142 #define SND_AddVoice ASND_AddVoice
143 #define SND_StopVoice ASND_StopVoice
144 #define SND_PauseVoice ASND_PauseVoice
145 #define SND_StatusVoice ASND_StatusVoice
146 #define SND_GetFirstUnusedVoice ASND_GetFirstUnusedVoice
147 #define SND_ChangePitchVoice ASND_ChangePitchVoice
148 #define SND_ChangeVolumeVoice ASND_ChangeVolumeVoice
149 #define SND_ChangeVolumeVoice ASND_ChangeVolumeVoice
150 #define SND_GetTickCounterVoice ASND_GetTickCounterVoice
151 #define SND_GetTimerVoice ASND_GetTimerVoice
152 #define SND_TestPointer ASND_TestPointer
154 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
156 typedef void (*ASNDVoiceCallback
)(s32 voice
);
158 /* int ANote2Freq(int note, int freq_base,int note_base);
160 Initializes the SND lib and fix the hardware sample rate.
164 note: Note codified to play. For example: NOTE(C,4) for note C and octave 4
166 freq_base: Frequency base of the sample. For example 8000Hz
168 note_base: Note codified of the sample. For example: NOTE(L,3) for note L and octave 3 (LA 3)
170 return: frequency (in Hz)
174 int ANote2Freq(int note
, int freq_base
,int note_base
);
176 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
177 /* General Sound Functions */
178 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
182 Initializes the ASND lib and fix the hardware sample rate to 48000.
193 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
197 De-initializes the ASND lib.
205 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
207 /* void ASND_Pause(s32 paused);
209 Used to pause (or not) the sound. When you call to the ASND_Init() function, the sound is paused.
214 paused: use 0 to run or 1 to pause
220 void ASND_Pause(s32 paused
);
222 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
224 /* s32 ASND_Is_Paused();
226 Return if the sound is paused or not
230 return: 0-> running 1-> paused
235 s32
ASND_Is_Paused();
237 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
239 /* u32 ASND_GetTime();
241 Get the global time (in milliseconds). This time is updated from the IRQ
246 return: current time (in ms)
252 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
254 /* u32 ASND_GetSampleCounter();
256 Get the global sample counter. This counter is updated from the IRQ in steps of ASND_GetSamplesPerTick()
258 NOTE: you can use this to implement one timer with high precision
263 return: current sample
268 u32
ASND_GetSampleCounter();
270 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
272 /* u32 ASND_GetSamplesPerTick();
274 Get the samples sended from the IRQ in one tick
279 return: samples per tick
284 u32
ASND_GetSamplesPerTick();
286 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
288 /* void ASND_SetTime(u32 time);
290 Set the global time (in milliseconds). This time is updated from the IRQ
294 time: fix the current time (in ms)
300 void ASND_SetTime(u32 time
);
302 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
304 /* void ASND_SetCallback(void (*callback)());
306 Set a global callback for general pourpose. This callback is called from the IRQ
310 callback: function callback
316 void ASND_SetCallback(void (*callback
)());
318 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
320 /* s32 ASND_GetAudioRate();
322 return: Audio rate (48000)
324 Note: for compatibility with SND_lib
328 s32
ASND_GetAudioRate();
330 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
331 /* Voice Functions */
332 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
334 /* s32 ASND_SetVoice(s32 voice, s32 format, s32 pitch,s32 delay, void *snd, s32 size_snd, s32 volume_l, s32 volume_r, void (*callback) (s32 voice));
336 Set a PCM voice to play. This function stops one previously voice. Use the ASND_StatusVoice() to test the status condition
338 NOTE: The voices are played in stereo and 16 bits independently of the source format.
342 voice: use one from 0 to (MAX_SND_VOICES-1)
344 format: PCM format from VOICE_MONO_8BIT to VOICE_STEREO_16BIT
346 pitch: pitch frequency (in Hz)
348 delay: delay time in milliseconds (ms). Time to wait before to play the voice
350 snd: buffer containing the samples (aligned and padded to 32 bytes!!!)
352 size_snd: size (in bytes) of the buffer samples
354 volume_l: volume to the left channel from 0 to 255
356 volume_r: volume to the right channel from 0 to 255
358 callback: can be NULL or one callback function is used to implement a double buffer use. When the second buffer is empty, the callback is called sending
359 the voice number as parameter. You can use "void callback(s32 voice)" function to call ASND_AddVoice() and add one voice to the second buffer.
360 NOTE: When callback is fixed the voice never stops and it turn in SND_WAITING status if success one timeout condition.
362 return: SND_OK or SND_INVALID
366 s32
ASND_SetVoice(s32 voice
, s32 format
, s32 pitch
,s32 delay
, void *snd
, s32 size_snd
, s32 volume_l
, s32 volume_r
, ASNDVoiceCallback callback
);
367 s32
ASND_SetInfiniteVoice(s32 voice
, s32 format
, s32 pitch
,s32 delay
, void *snd
, s32 size_snd
, s32 volume_l
, s32 volume_r
);
369 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
371 /* s32 ASND_AddVoice(s32 voice, void *snd, s32 size_snd);
373 Add a PCM voice in the second buffer to play. This function requires one previously call to ASND_SetVoice() and one condition status different
378 voice: use one from 0 to (MAX_SND_VOICES-1)
380 snd: buffer containing the samples (aligned and padded to 32 bytes!) in the same format of the previously ASND_SetVoice() use
382 size_snd: size (in bytes) of the buffer samples
384 return: SND_OK, SND_INVALID or SND_BUSY if the second buffer is not empty and de voice cannot be add
388 s32
ASND_AddVoice(s32 voice
, void *snd
, s32 size_snd
);
391 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
393 /* s32 ASND_StopVoice(s32 voice);
395 Stops the voice selected.
397 If the voice is used in song mode, you need to assign the samples with ASND_SetSongSampleVoice() again. Use ASND_PauseSongVoice() in this case to stops
398 the voice without lose the samples.
402 voice: use one from 0 to (MAX_SND_VOICES-1)
404 return: SND_OK, SND_INVALID
408 s32
ASND_StopVoice(s32 voice
);
410 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
412 /* s32 ASND_PauseVoice(s32 voice, s32 pause);
414 Pause the voice selected.
420 voice: use one from 0 to (MAX_SND_VOICES-1)
422 return: SND_OK, SND_INVALID
426 s32
ASND_PauseVoice(s32 voice
, s32 pause
);
428 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
430 /* s32 ASND_StatusVoice(s32 voice);
432 Return the status of the voice selected
436 voice: use one from 0 to (MAX_SND_VOICES-1)
439 SND_UNUSED you can use this voice
440 SND_WORKING this voice is in progress
441 SND_WAITING this voice is in progress and waiting to one SND_AddVoice function (the voice handler is called continuously)
445 s32
ASND_StatusVoice(s32 voice
);
447 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
449 /* s32 ASND_GetFirstUnusedVoice();
451 Get the first unused voice. The voice 0 is tried especially and it is the last possible result. The idea is to reserve that voice for a Mod/Ogg/MP3
452 Player or similar. So if the function return a value <1 you can be sure the rest of the voices are working.
458 return: SND_INVALID or the first free voice (from 0 to (MAX_SND_VOICES-1))
462 s32
ASND_GetFirstUnusedVoice();
464 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
466 /* s32 ASND_ChangePitchVoice(s32 voice, s32 pitch);
468 Use this function to change the voice pitch in real-time. You can use this to create audio effects.
472 voice: use one from 0 to (MAX_SND_VOICES-1)
474 return: SND_OK, SND_INVALID
478 s32
ASND_ChangePitchVoice(s32 voice
, s32 pitch
);
480 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
482 /* s32 SND_ChangeVolumeVoice(s32 voice, s32 volume_l, s32 volume_r);
484 Use this function to change the voice volume in real-time. You can use this to create audio effects.
488 voice: use one from 0 to (MAX_SND_VOICES-1)
490 volume_l: volume to the left channel from 0 to 255
492 volume_r: volume to the right channel from 0 to 255
494 return: SND_OK, SND_INVALID
498 s32
ASND_ChangeVolumeVoice(s32 voice
, s32 volume_l
, s32 volume_r
);
500 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
502 /* u32 SND_GetTickCounterVoice(s32 voice);
504 Get the tick counter from the voice starts to play (without the delay time). This counter uses the same resolution of the internal sound buffer.
505 For example if the lib is initilized with INIT_RATE_48000 a return value of 24000 are equal to 0.5 seconds played
507 USES: you can use this value to synchronize audio & video
512 voice: use one from 0 to (MAX_SND_VOICES-1)
514 return: Number of ticks. No error condition for this function
518 u32
ASND_GetTickCounterVoice(s32 voice
);
520 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
522 /* u32 ASND_GetTimerVoice(s32 voice);
524 Get the time (in milliseconds) from the voice starts to play (without the delay time).
526 USES: you can use this value to synchronize audio & video
530 voice: use one from 0 to (MAX_SND_VOICES-1)
532 return: time (in ms). No error condition for this function
536 u32
ASND_GetTimerVoice(s32 voice
);
538 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
540 /* s32 SND_TestPointer(s32 voice, void *pointer);
542 Test if the pointer is in use by the voice (as buffer).
546 voice: use one from 0 to (MAX_SND_VOICES-1)
548 pointer: address to test It must be the same pointer passed to the ASND_AddVoice() or ASND_SetVoice() functions
550 return: SND_INVALID, 0-> Unused, 1-> Used as buffer
555 s32
ASND_TestPointer(s32 voice
, void *pointer
);
557 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
559 /* s32 ASND_TestVoiceBufferReady(s32 voice);
561 Test if the Voice is Ready to receive a new buffer sample with ASND_AddVoice(). You can use this function to block a reader when you use double buffering
562 as similar form of the ASND_TestPointer() function without passing one address to test
566 voice: use one from 0 to (MAX_SND_VOICES-1)
568 return: SND_INVALID, 0-> not ready to receive a new AddVoice(), 1->ready to receive a new AddVoice()
572 s32
ASND_TestVoiceBufferReady(s32 voice
);
574 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
576 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/
578 /* u32 ASND_GetDSP_PercentUse();
580 Get the Percent use of the DSP
590 u32
ASND_GetDSP_PercentUse();
593 /*------------------------------------------------------------------------------------------------------------------------------------------------------*/