all repos — mgba @ 2f2e5398719f9d6a78ae84fc241945b46839b01c

mGBA Game Boy Advance Emulator

src/platform/qt/AudioDevice.cpp (view raw)

 1/* Copyright (c) 2013-2015 Jeffrey Pfau
 2 *
 3 * This Source Code Form is subject to the terms of the Mozilla Public
 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 6#include "AudioDevice.h"
 7
 8extern "C" {
 9#include "gba/gba.h"
10#include "gba/audio.h"
11#include "gba/supervisor/thread.h"
12}
13
14using namespace QGBA;
15
16AudioDevice::AudioDevice(QObject* parent)
17	: QIODevice(parent)
18	, m_context(nullptr)
19	, m_drift(0)
20	, m_ratio(1.f)
21{
22	setOpenMode(ReadOnly);
23}
24
25void AudioDevice::setFormat(const QAudioFormat& format) {
26	if (!m_context || !GBAThreadIsActive(m_context)) {
27		return;
28	}
29#if RESAMPLE_LIBRARY == RESAMPLE_NN
30	GBAThreadInterrupt(m_context);
31	m_ratio = GBAAudioCalculateRatio(m_context->gba->audio.sampleRate, m_context->fpsTarget, format.sampleRate());
32	GBAThreadContinue(m_context);
33#elif RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
34	double fauxClock = GBAAudioCalculateRatio(1, m_context->fpsTarget, 1);
35	GBASyncLockAudio(&m_context->sync);
36	blip_set_rates(m_context->gba->audio.left, GBA_ARM7TDMI_FREQUENCY, format.sampleRate() * fauxClock);
37	blip_set_rates(m_context->gba->audio.right, GBA_ARM7TDMI_FREQUENCY, format.sampleRate() * fauxClock);
38	GBASyncUnlockAudio(&m_context->sync);
39#endif
40}
41
42void AudioDevice::setInput(GBAThread* input) {
43	m_context = input;
44}
45
46qint64 AudioDevice::readData(char* data, qint64 maxSize) {
47	if (maxSize > 0xFFFFFFFF) {
48		maxSize = 0xFFFFFFFF;
49	}
50
51	if (!m_context->gba) {
52		return 0;
53	}
54
55#if RESAMPLE_LIBRARY == RESAMPLE_NN
56	return GBAAudioResampleNN(&m_context->gba->audio, m_ratio, &m_drift, reinterpret_cast<GBAStereoSample*>(data), maxSize / sizeof(GBAStereoSample)) * sizeof(GBAStereoSample);
57#elif RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
58	GBASyncLockAudio(&m_context->sync);
59	int available = blip_samples_avail(m_context->gba->audio.left);
60	if (available > maxSize / sizeof(GBAStereoSample)) {
61		available = maxSize / sizeof(GBAStereoSample);
62	}
63	blip_read_samples(m_context->gba->audio.left, &reinterpret_cast<GBAStereoSample*>(data)->left, available, true);
64	blip_read_samples(m_context->gba->audio.right, &reinterpret_cast<GBAStereoSample*>(data)->right, available, true);
65	GBASyncConsumeAudio(&m_context->sync);
66	return available * sizeof(GBAStereoSample);
67#endif
68}
69
70qint64 AudioDevice::writeData(const char*, qint64) {
71	return 0;
72}