2021-08-10 18:44:19 +02:00
|
|
|
#include "../include/sound.h"
|
|
|
|
#include "../include/space.h"
|
|
|
|
|
2021-08-15 19:12:03 +02:00
|
|
|
// VAG playback
|
|
|
|
void initSnd(SpuCommonAttr * spuSettings, char * spu_malloc_rec){
|
|
|
|
|
|
|
|
SpuInitMalloc(MALLOC_MAX, spu_malloc_rec); // Maximum number of blocks, mem. management table address.
|
|
|
|
spuSettings->mask = (SPU_COMMON_MVOLL | SPU_COMMON_MVOLR | SPU_COMMON_CDVOLL | SPU_COMMON_CDVOLR | SPU_COMMON_CDMIX ); // Mask which attributes to set
|
|
|
|
spuSettings->mvol.left = MVOL_L; // Master volume left
|
|
|
|
spuSettings->mvol.right = MVOL_R; // see libref47.pdf, p.1058
|
|
|
|
spuSettings->cd.volume.left = CDVOL_L;
|
|
|
|
spuSettings->cd.volume.right = CDVOL_R;
|
2021-08-10 18:44:19 +02:00
|
|
|
// Enable CD input ON
|
|
|
|
spuSettings->cd.mix = SPU_ON;
|
2021-08-15 19:12:03 +02:00
|
|
|
|
|
|
|
SpuSetCommonAttr(spuSettings);
|
2021-08-10 18:44:19 +02:00
|
|
|
// Set transfer mode
|
|
|
|
SpuSetTransferMode(SPU_TRANSFER_BY_DMA);
|
2021-08-15 19:12:03 +02:00
|
|
|
SpuSetIRQ(SPU_OFF);
|
|
|
|
// Mute all voices
|
|
|
|
SpuSetKey(SpuOff, SPU_ALLCH);
|
2021-08-10 18:44:19 +02:00
|
|
|
}
|
2021-08-15 19:12:03 +02:00
|
|
|
u_long sendVAGtoSPU(unsigned int VAG_data_size, u_char *VAG_data){
|
|
|
|
u_long transferred;
|
|
|
|
SpuSetTransferMode(SpuTransByDMA); // DMA transfer; can do other processing during transfer
|
|
|
|
transferred = SpuWrite (VAG_data + sizeof(VAGhdr), VAG_data_size); // transfer VAG_data_size bytes from VAG_data address to sound buffer
|
|
|
|
SpuIsTransferCompleted (SPU_TRANSFER_WAIT); // Checks whether transfer is completed and waits for completion
|
|
|
|
return transferred;
|
2021-08-10 18:44:19 +02:00
|
|
|
}
|
2021-08-15 19:12:03 +02:00
|
|
|
void setVoiceAttr(SpuVoiceAttr * voiceAttributes, u_int pitch, long channel, u_long soundAddr ){
|
|
|
|
voiceAttributes->mask= //~ Attributes (bit string, 1 bit per attribute)
|
|
|
|
(
|
|
|
|
SPU_VOICE_VOLL |
|
|
|
|
SPU_VOICE_VOLR |
|
|
|
|
SPU_VOICE_PITCH |
|
|
|
|
SPU_VOICE_WDSA |
|
|
|
|
SPU_VOICE_ADSR_AMODE |
|
|
|
|
SPU_VOICE_ADSR_SMODE |
|
|
|
|
SPU_VOICE_ADSR_RMODE |
|
|
|
|
SPU_VOICE_ADSR_AR |
|
|
|
|
SPU_VOICE_ADSR_DR |
|
|
|
|
SPU_VOICE_ADSR_SR |
|
|
|
|
SPU_VOICE_ADSR_RR |
|
|
|
|
SPU_VOICE_ADSR_SL
|
|
|
|
);
|
|
|
|
voiceAttributes->voice = channel; //~ Voice (low 24 bits are a bit string, 1 bit per voice )
|
|
|
|
voiceAttributes->volume.left = 0x0; //~ Volume
|
|
|
|
voiceAttributes->volume.right = 0x0; //~ Volume
|
|
|
|
voiceAttributes->pitch = pitch; //~ Interval (set pitch)
|
|
|
|
voiceAttributes->addr = soundAddr; //~ Waveform data start address
|
|
|
|
voiceAttributes->a_mode = SPU_VOICE_LINEARIncN; //~ Attack rate mode = Linear Increase - see libref47.pdf p.1091
|
|
|
|
voiceAttributes->s_mode = SPU_VOICE_LINEARIncN; //~ Sustain rate mode = Linear Increase
|
|
|
|
voiceAttributes->r_mode = SPU_VOICE_LINEARDecN; //~ Release rate mode = Linear Decrease
|
|
|
|
voiceAttributes->ar = 0x0; //~ Attack rate
|
|
|
|
voiceAttributes->dr = 0x0; //~ Decay rate
|
|
|
|
voiceAttributes->rr = 0x0; //~ Release rate
|
|
|
|
voiceAttributes->sr = 0x0; //~ Sustain rate
|
|
|
|
voiceAttributes->sl = 0xf; //~ Sustain level
|
|
|
|
SpuSetVoiceAttr(voiceAttributes); // set attributes
|
2021-08-10 18:44:19 +02:00
|
|
|
}
|
2021-08-15 19:12:03 +02:00
|
|
|
u_long setSPUtransfer(SpuVoiceAttr * voiceAttributes, VAGsound * sound){
|
|
|
|
// Return spu_address
|
|
|
|
u_long transferred, spu_address;
|
|
|
|
u_int pitch;
|
|
|
|
const VAGhdr * VAGheader = (VAGhdr *) sound->VAGfile;
|
|
|
|
pitch = (SWAP_ENDIAN32(VAGheader->samplingFrequency) << 12) / 44100L;
|
|
|
|
spu_address = SpuMalloc(SWAP_ENDIAN32(VAGheader->dataSize)); // Allocate an area of dataSize bytes in the sound buffer.
|
|
|
|
SpuSetTransferStartAddr(spu_address); // Sets a starting address in the sound buffer
|
|
|
|
transferred = sendVAGtoSPU(SWAP_ENDIAN32(VAGheader->dataSize), sound->VAGfile);
|
|
|
|
setVoiceAttr(voiceAttributes, pitch, sound->spu_channel, spu_address);
|
|
|
|
// Return 1 if ok, size transferred else.
|
|
|
|
//~ if (transferred == SWAP_ENDIAN32(VAGheader->dataSize)){
|
|
|
|
//~ return 1;
|
|
|
|
//~ }
|
|
|
|
//~ return transferred;
|
2021-08-16 14:42:07 +02:00
|
|
|
FntPrint("Tr: %", transferred);
|
2021-08-15 19:12:03 +02:00
|
|
|
return spu_address;
|
2021-08-10 18:44:19 +02:00
|
|
|
}
|
2021-08-15 19:12:03 +02:00
|
|
|
void playSFX(SpuVoiceAttr * voiceAttributes, VAGsound * sound){
|
|
|
|
// Set voice volume to max
|
|
|
|
voiceAttributes->mask= ( SPU_VOICE_VOLL | SPU_VOICE_VOLR );
|
|
|
|
voiceAttributes->voice = sound->spu_channel;
|
|
|
|
// Range 0 - 3fff
|
|
|
|
voiceAttributes->volume.left = VOICEVOL_L;
|
|
|
|
voiceAttributes->volume.right = VOICEVOL_R;
|
|
|
|
SpuSetVoiceAttr(voiceAttributes);
|
|
|
|
// Play voice
|
|
|
|
SpuSetKey(SpuOn, sound->spu_channel);
|
2021-08-10 18:44:19 +02:00
|
|
|
}
|
2021-08-15 19:12:03 +02:00
|
|
|
void XAsetup(void){
|
|
|
|
u_char param[4];
|
|
|
|
// ORing the parameters we need to set ; drive speed, ADPCM play, Subheader filter, sector size
|
|
|
|
// If using CdlModeSpeed(Double speed), you need to load an XA file that has 8 channels.
|
|
|
|
// In single speed, a 4 channels XA is to be used.
|
|
|
|
param[0] = CdlModeSpeed|CdlModeRT|CdlModeSF|CdlModeSize1;
|
|
|
|
// Issue primitive command to CD-ROM system (Blocking-type)
|
|
|
|
// Set the parameters above
|
|
|
|
CdControlB(CdlSetmode, param, 0);
|
|
|
|
// Pause at current pos
|
|
|
|
CdControlF(CdlPause,0);
|
2021-08-10 18:44:19 +02:00
|
|
|
}
|
2021-08-15 19:12:03 +02:00
|
|
|
void setXAsample(XAsound * sound, CdlFILTER * filter){
|
|
|
|
filter->chan = sound->channel;
|
|
|
|
filter->file = sound->file;
|
2021-08-10 18:44:19 +02:00
|
|
|
// Set filter
|
2021-08-15 19:12:03 +02:00
|
|
|
CdControlF(CdlSetfilter, (u_char *)filter);
|
|
|
|
// Reset sample's cursor
|
|
|
|
sound->cursor = 0;
|
2021-08-10 18:44:19 +02:00
|
|
|
}
|