void CtrAudio::SE_Play(std::string const& file, int volume, int /* pitch */) {
// Select an available audio channel
int i = 0;
while (i < num_channels){
if (!isPlayingCallback(i)) break;
i++;
if (i >= num_channels){
Output::Warning("Cannot execute %s sound: audio-device is busy.\n",file.c_str());
return;
}
}
if (audiobuffers[i] != NULL){
#ifndef USE_CACHE
linearFree(audiobuffers[i]);
audiobuffers[i] = NULL;
#endif
if (isDSP) free(dspSounds[i]);
}
// Init needed vars
bool isStereo = false;
int audiobuf_size;
int codec;
DecodedSound myFile;
#ifdef USE_CACHE
// Looking if the sound is in sounds cache
int cacheIdx = lookCache(file.c_str());
if (cacheIdx < 0){
#endif
// Searching for the file
std::string const path = FileFinder::FindSound(file);
if (path.empty()) {
Output::Debug("Sound not found: %s", file.c_str());
return;
}
// Opening and decoding the file
int res = DecodeSound(path, &myFile);
if (res < 0) return;
#ifdef USE_CACHE
else sprintf(soundtable[res],"%s",file.c_str());
#endif
#ifdef USE_CACHE
}else myFile = decodedtable[cacheIdx];
#endif
// Processing sound info
audiobuffers[i] = myFile.audiobuf;
int samplerate = myFile.samplerate;
audiobuf_size = myFile.audiobuf_size;
if (isDSP) codec = NDSP_CHANNELS(isStereo + 1) | NDSP_ENCODING(myFile.format);
else codec = SOUND_FORMAT(myFile.format);
isStereo = myFile.isStereo;
#ifndef NO_DEBUG
Output::Debug("Playing sound %s:",file.c_str());
Output::Debug("Samplerate: %i",samplerate);
Output::Debug("Buffer Size: %i bytes",audiobuf_size);
#endif
// Playing the sound
float vol = volume / 100.0;
if (isStereo && (!isDSP)){
// We need a second channel where to execute right audiochannel since csnd supports only mono sounds natively
int z = i+1;
while (z < num_channels){
if (!isPlayingCallback(z+0x08)) break;
z++;
if (z >= num_channels){
Output::Warning("Cannot execute %s sound: audio-device is busy.\n",file.c_str());
return;
}
}
#ifndef USE_CACHE
if (audiobuffers[z] != NULL) linearFree(audiobuffers[z]);
// To not waste CPU clocks, we use a single audiobuffer for both channels so we put just a stubbed audiobuffer on right channel
audiobuffers[z] = (u8*)linearAlloc(1);
#endif
int chnbuf_size = audiobuf_size>>1;
csndPlaySound(i+0x08, SOUND_LINEAR_INTERP | codec, samplerate, vol, -1.0, (u32*)audiobuffers[i], (u32*)audiobuffers[i], chnbuf_size); // Left
csndPlaySound(z+0x08, SOUND_LINEAR_INTERP | codec, samplerate, vol, 1.0, (u32*)(audiobuffers[i] + chnbuf_size), (u32*)(audiobuffers[i] + chnbuf_size), chnbuf_size); // Right
}else{
if (isDSP){
ndspChnReset(i+0x08);
ndspChnWaveBufClear(i+0x08);
ndspChnSetInterp(i+0x08, NDSP_INTERP_LINEAR);
ndspChnSetRate(i+0x08, float(samplerate));
ndspChnSetFormat(i+0x08, codec);
dspSounds[i] = (ndspWaveBuf*)calloc(1,sizeof(ndspWaveBuf));
createDspBlock(dspSounds[i], myFile.bytepersample, audiobuf_size, false, (u32*)audiobuffers[i]);
ndspChnWaveBufAdd(i+0x08, dspSounds[i]);
}else csndPlaySound(i+0x08, SOUND_LINEAR_INTERP | codec, samplerate, vol, 0.0, (u32*)audiobuffers[i], (u32*)audiobuffers[i], audiobuf_size);
}
}