diff options
author | Thomas Edvalson | 2016-04-06 02:12:02 -0400 |
---|---|---|
committer | Thomas Edvalson | 2016-04-06 02:12:02 -0400 |
commit | e2b9572a83badb7084f5b54e1a7e108af8e327f6 (patch) | |
tree | da3df5dcf26a03635b5a74ac18ab18ecb7c7fe98 /backends/platform/3ds/osystem-audio.cpp | |
parent | f6c3363cf54af1c01efc12a98ab27a8af52aad3e (diff) | |
download | scummvm-rg350-e2b9572a83badb7084f5b54e1a7e108af8e327f6.tar.gz scummvm-rg350-e2b9572a83badb7084f5b54e1a7e108af8e327f6.tar.bz2 scummvm-rg350-e2b9572a83badb7084f5b54e1a7e108af8e327f6.zip |
3DS: Initial commit
Diffstat (limited to 'backends/platform/3ds/osystem-audio.cpp')
-rw-r--r-- | backends/platform/3ds/osystem-audio.cpp | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/backends/platform/3ds/osystem-audio.cpp b/backends/platform/3ds/osystem-audio.cpp new file mode 100644 index 0000000000..7ff788b430 --- /dev/null +++ b/backends/platform/3ds/osystem-audio.cpp @@ -0,0 +1,107 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "osystem.h" + +static bool exitAudioThread = false; +static bool hasAudio = false; + +static void audioThreadFunc(void* arg) { + Audio::MixerImpl *mixer = (Audio::MixerImpl *) arg; + OSystem_3DS *osys = (OSystem_3DS*)g_system; + + int i; + const int channel = 0; + int bufferIndex = 0; + const int bufferCount = 3; + const int bufferSize = 80000; // Can't be too small, based on delayMillis duration + const int sampleRate = 22050; + int sampleLen = 0; + uint32 lastTime = osys->getMillis(true); + uint32 time = lastTime; + ndspWaveBuf buffers[bufferCount]; + + for(i = 0; i < bufferCount; ++i) { + memset(&buffers[i], 0, sizeof(ndspWaveBuf)); + buffers[i].data_vaddr = linearAlloc(bufferSize); + buffers[i].looping = false; + buffers[i].status = NDSP_WBUF_FREE; + } + + ndspChnReset(channel); + ndspChnSetInterp(channel, NDSP_INTERP_LINEAR); + ndspChnSetRate(channel, sampleRate); + ndspChnSetFormat(channel, NDSP_FORMAT_STEREO_PCM16); + + while(!exitAudioThread) { + bufferIndex++; + bufferIndex %= bufferCount; + ndspWaveBuf* buf = &buffers[bufferIndex]; + + osys->delayMillis(100); // Note: Increasing the delay requires a bigger buffer + + time = osys->getMillis(true); + sampleLen = (time - lastTime) * 22 * 4; // sampleRate / 1000 * channelCount * sizeof(int16); + lastTime = time; + + if (sampleLen > 0) { + buf->nsamples = mixer->mixCallback(buf->data_adpcm, sampleLen); + if (buf->nsamples > 0) { + DSP_FlushDataCache(buf->data_vaddr, bufferSize); + ndspChnWaveBufAdd(channel, buf); + } + } + } + + for(i = 0; i < bufferCount; ++i) + linearFree(buffers[i].data_pcm8); +} + +void OSystem_3DS::initAudio() { + _mixer = new Audio::MixerImpl(this, 22050); + + hasAudio = R_SUCCEEDED(ndspInit()); + _mixer->setReady(false); + + if (hasAudio) { + s32 prio = 0; + svcGetThreadPriority(&prio, CUR_THREAD_HANDLE); + audioThread = threadCreate(&audioThreadFunc, _mixer, 32*1048, prio-1, -2, false); + } +} + +void OSystem_3DS::destroyAudio() { + if (hasAudio) { + exitAudioThread = true; + threadJoin(audioThread, U64_MAX); + threadFree(audioThread); + ndspExit(); + } + + delete _mixer; + _mixer = 0; +} + +Audio::Mixer *OSystem_3DS::getMixer() { + assert(_mixer); + return _mixer; +} |