S32 PCMAudioManager::loadSound(const char *assetName) { Property *prop = btGetContext()->appProperties->get("debug_sounds"); BOOL32 debugSounds = FALSE; if (prop) { debugSounds = prop->getBoolValue(); } if (isSoundLoaded(assetName)) { return getSoundId(assetName); } int assetSize = 0; unsigned char *fileData = _platform_load_asset(assetName, &assetSize); S32 sndId = -1; if (fileData) { signed short *decoded; int channels, len; unsigned int sampleRate = 0; len = stb_vorbis_decode_memory(fileData, assetSize, &channels, &sampleRate, &decoded); if (debugSounds) { char buf[1024]; sprintf(buf, "Loaded %s: (%i enc bytes) length=%i channels=%i rate=%i", assetName, assetSize, len, channels, sampleRate); logmsg(buf); } sndId = loadSound(decoded, len * channels, sampleRate, channels, assetName); } _platform_free_asset(fileData); return sndId; }
void PCMAudioManager::stopSound(const char *assetName) { S32 soundId = getSoundId(assetName); for (S32 i = 0; i < streamCount; i++) { PCMStream *stream = &pcmStreams[i]; if (stream->isPlaying && stream->soundId == soundId) { stream->isPlaying = FALSE; stream->bufferPosition = 0; stream->overallPosition = 0; stream->loopsRemaining = 0; } } }
bool XMLToSndManifest(const wchar_t* cFilename) { wstring sXMLFile = cFilename; sXMLFile += TEXT(".xml"); XMLDocument* doc = new XMLDocument; int iErr = doc->LoadFile(ws2s(sXMLFile).c_str()); if(iErr != XML_NO_ERROR) { cout << "Error parsing XML file " << ws2s(sXMLFile) << ": Error " << iErr << endl; delete doc; return false; } //Grab root element XMLElement* root = doc->RootElement(); if(root == NULL) { cout << "Error: Root element NULL in XML file " << ws2s(sXMLFile) << endl; delete doc; return false; } //Roll through child elements list<soundTakeGroup> lSoundTakeGroups; vector<takeRecord> vSoundTakes; XMLElement* elem = root->FirstChildElement("sound"); i32 iCurTake = 0; while(elem != NULL) { soundTakeGroup stg; const char* id = elem->Attribute("id"); if(id == NULL) { cout << "Error: Unable to get id of XML element in file " << ws2s(sXMLFile) << endl; delete doc; return false; } stg.logicalId = getSoundId(s2ws(id).c_str()); //TODO: Hash this? stg.firstTakeIdx = vSoundTakes.size(); stg.numTakes = 0; //Get the takes for this sound XMLElement* elem2 = elem->FirstChildElement("take"); while(elem2 != NULL) { iCurTake++; takeRecord tr; const char* cName = elem2->Attribute("filename"); if(cName == NULL) { cout << "Error: Unable to get filename of take record in file " << ws2s(sXMLFile) << endl; delete doc; return false; } if(elem2->QueryIntAttribute("channels", &tr.channels) != XML_NO_ERROR) { cout << "Error: Unable to get channels from take " << iCurTake << " from file " << ws2s(sXMLFile) << endl; delete doc; return false; } if(elem2->QueryIntAttribute("samplespersec", &tr.samplesPerSec) != XML_NO_ERROR) { cout << "Error: Unable to get samplesPerSec from take " << iCurTake << " from file " << ws2s(sXMLFile) << endl; delete doc; return false; } if(elem2->QueryIntAttribute("samplecountperchannel", &tr.sampleCountPerChannel) != XML_NO_ERROR) { cout << "Error: Unable to get sampleCountPerChannel from take " << iCurTake << " from file " << ws2s(sXMLFile) << endl; delete doc; return false; } if(elem2->QueryIntAttribute("vorbisworkingsetsizebytes", &tr.vorbisWorkingSetSizeBytes) != XML_NO_ERROR) { cout << "Error: Unable to get vorbisWorkingSetSizeBytes from take " << iCurTake << " from file " << ws2s(sXMLFile) << endl; delete doc; return false; } if(elem2->QueryIntAttribute("vorbismarkerssizebytes", &tr.vorbisMarkersSizeBytes) != XML_NO_ERROR) { cout << "Error: Unable to get vorbisMarkersSizeBytes from take " << iCurTake << " from file " << ws2s(sXMLFile) << endl; delete doc; return false; } if(elem2->QueryIntAttribute("vorbispacketssizebytes", &tr.vorbisPacketsSizeBytes) != XML_NO_ERROR) { cout << "Error: Unable to get vorbisPacketsSizeBytes from take " << iCurTake << " from file " << ws2s(sXMLFile) << endl; delete doc; return false; } wstring sName = s2ws(cName); sName.erase(sName.size()-4); //Delete the ".ogg" ending from the wstring tr.resId = getResID(sName); //Get the resource ID from this filename vSoundTakes.push_back(tr); elem2 = elem2->NextSiblingElement("take"); stg.numTakes++; } lSoundTakeGroups.push_back(stg); //Hang onto this elem = elem->NextSiblingElement("sound"); //Next item } delete doc; //We're done with this //Repack FILE* f = _wfopen(cFilename, TEXT("wb")); //Open file for writing if(f == NULL) { cout << "Unable to open file " << cFilename << " for writing." << endl; return false; } //Write the soundManifestHeader i32 curOffset = sizeof(soundManifestHeader); soundManifestHeader smh; smh.sounds.count = lSoundTakeGroups.size(); smh.sounds.offset = curOffset; smh.takes.count = vSoundTakes.size(); curOffset += lSoundTakeGroups.size() * sizeof(soundTakeGroup); smh.takes.offset = curOffset; fwrite(&smh, 1, sizeof(soundManifestHeader), f); //Write out sounds for(list<soundTakeGroup>:: iterator i = lSoundTakeGroups.begin(); i != lSoundTakeGroups.end(); i++) fwrite(&(*i), 1, sizeof(soundTakeGroup), f); //Write out sound takes for(unsigned int i = 0; i < vSoundTakes.size(); i++) fwrite(&vSoundTakes[i], 1, sizeof(takeRecord), f); //Done fclose(f); return true; }
void PCMAudioManager::unloadSound(const char *assetName) { S32 soundId = getSoundId(assetName); unloadSound(soundId); }
S32 PCMAudioManager::playSound(const char *assetName, S16 loops, F32 leftVol, F32 rightVol, F32 rate) { //logmsg("Playsound"); //logmsg(assetName); return playSound(getSoundId(assetName), loops, leftVol, rightVol, rate); }