Beispiel #1
0
// createDspBlock: Create a new block for DSP service
void createDspBlock(ndspWaveBuf* waveBuf, u16 bps, u32 size, bool loop, u32* data){
	waveBuf->data_vaddr = (void*)data;
	waveBuf->nsamples = size / bps;
	waveBuf->looping = loop;
	waveBuf->offset = 0;	
	DSP_FlushDataCache(data, size);
}
Beispiel #2
0
void Sound::play()
{
	if (!m_buffer || m_buffer->getSampleCount() == 0)
		return;
	if (getStatus() == Playing)
		stop();

	m_channel = 0;
	while (m_channel < 24 && ndspChnIsPlaying(m_channel))
		m_channel++;

	if (m_channel == 24) {
		err() << "Sound::play() failed because all channels are in use." << std::endl;
		m_channel = -1;
		return;
	}

	setPlayingOffset(m_pauseOffset);

	if (m_pauseOffset != Time::Zero)
		m_pauseOffset = Time::Zero;

	u32 size = sizeof(Int16) * m_buffer->getSampleCount();

	ndspChnReset(m_channel);
	ndspChnSetInterp(m_channel, NDSP_INTERP_POLYPHASE);
	ndspChnSetRate(m_channel, float(m_buffer->getSampleRate()));
	ndspChnSetFormat(m_channel, (m_buffer->getChannelCount() == 1) ? NDSP_FORMAT_MONO_PCM16 : NDSP_FORMAT_STEREO_PCM16);

	DSP_FlushDataCache((u8*)m_buffer->getSamples(), size);

	ndspChnWaveBufAdd(m_channel, &m_ndspWaveBuf);
}
Beispiel #3
0
// High frequency square wave, PCM16
void fillBuffer(u32 *audio_buffer, size_t size) {
    for (size_t i = 0; i < size; i++) {
        u32 data;
        switch (i % 5) {
        case 0:
            data = 0x1000;
            break;
        case 1:
            data = 0x6000;
            break;
        case 2:
            data = 0x4000;
            break;
        case 3:
            data = 0x2000;
            break;
        case 4:
            data = 0x5000;
            break;
        }
        audio_buffer[i] = (data<<16) | (data&0xFFFF);
    }

    DSP_FlushDataCache(audio_buffer, size);
}
Beispiel #4
0
//----------------------------------------------------------------------------
void fill_buffer(void *audioBuffer, size_t size) {
//----------------------------------------------------------------------------

	u32 *dest = (u32*)audioBuffer;

	stb_vorbis_get_samples_short_interleaved(vorbisFile, 2, (short*)dest, Samples * 2);

	DSP_FlushDataCache(audioBuffer,size);

}
Beispiel #5
0
void playSoundChannels(int startchn, int samples, bool loop, std::vector<sample*>& data, std::vector<ndspWaveBuf>& waveBufs)
{
    for (unsigned int i = 0; i < data.size(); i++)
    {
        int channel = startchn + i;
        waveBufs[i].data_vaddr = data[i];
        waveBufs[i].nsamples = samples / data.size();
        waveBufs[i].looping = loop;
        DSP_FlushDataCache(data[i], samples * sizeof(sample));
        ndspChnWaveBufAdd(channel, &waveBufs[i]);
    }
}
Beispiel #6
0
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 = mixer->getOutputRate();
	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 (!osys->exiting) {
		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 (!osys->sleeping && sampleLen > 0) {
			bufferIndex++;
			bufferIndex %= bufferCount;
			ndspWaveBuf *buf = &buffers[bufferIndex];

			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);
}
Beispiel #7
0
void N3DS_SoundCallback(void* dud)
{
	if (N3DS_audioBuf[N3DS_soundFillBlock].status == NDSP_WBUF_DONE) {
		u32 flen = (N3DS_bufferSize * N3DS_sampleSize);
		u32 ilen = flen >> 2;
		u32* invbuf = (u32*) N3DS_audioBuf[N3DS_soundFillBlock].data_vaddr;

		if (N3DS_sound->sample_size > 1)
		{
			Sound_Callback((u8*) N3DS_audioBuf[N3DS_soundFillBlock].data_pcm8, flen);
		} else
		{
			Sound_Callback((u8*) N3DS_audioBuf[N3DS_soundFillBlock].data_pcm8, flen);
			for(int i = 0; i < ilen; i++)
				invbuf[i] ^= 0x80808080;
		}

		DSP_FlushDataCache(N3DS_audioBuf[N3DS_soundFillBlock].data_pcm8, flen);

		ndspChnWaveBufAdd(0, &N3DS_audioBuf[N3DS_soundFillBlock]);
		N3DS_soundFillBlock = !N3DS_soundFillBlock;
	}