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{
21 setOpenMode(ReadOnly);
22}
23
24void AudioDevice::setFormat(const QAudioFormat& format) {
25 if (!GBAThreadIsActive(m_context)) {
26 return;
27 }
28#if RESAMPLE_LIBRARY == RESAMPLE_NN
29 GBAThreadInterrupt(m_context);
30 m_ratio = GBAAudioCalculateRatio(m_context->gba->audio.sampleRate, m_context->fpsTarget, format.sampleRate());
31 GBAThreadContinue(m_context);
32#elif RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
33 double fauxClock = GBAAudioCalculateRatio(1, m_context->fpsTarget, 1);
34 GBASyncLockAudio(&m_context->sync);
35 blip_set_rates(m_context->gba->audio.left, GBA_ARM7TDMI_FREQUENCY, format.sampleRate() * fauxClock);
36 blip_set_rates(m_context->gba->audio.right, GBA_ARM7TDMI_FREQUENCY, format.sampleRate() * fauxClock);
37 GBASyncUnlockAudio(&m_context->sync);
38#endif
39}
40
41void AudioDevice::setInput(GBAThread* input) {
42 m_context = input;
43}
44
45qint64 AudioDevice::readData(char* data, qint64 maxSize) {
46 if (maxSize > 0xFFFFFFFF) {
47 maxSize = 0xFFFFFFFF;
48 }
49
50 if (!m_context->gba) {
51 return 0;
52 }
53
54#if RESAMPLE_LIBRARY == RESAMPLE_NN
55 return GBAAudioResampleNN(&m_context->gba->audio, m_ratio, &m_drift, reinterpret_cast<GBAStereoSample*>(data), maxSize / sizeof(GBAStereoSample)) * sizeof(GBAStereoSample);
56#elif RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
57 GBASyncLockAudio(&m_context->sync);
58 int available = blip_samples_avail(m_context->gba->audio.left);
59 if (available > maxSize / sizeof(GBAStereoSample)) {
60 available = maxSize / sizeof(GBAStereoSample);
61 }
62 blip_read_samples(m_context->gba->audio.left, &reinterpret_cast<GBAStereoSample*>(data)->left, available, true);
63 blip_read_samples(m_context->gba->audio.right, &reinterpret_cast<GBAStereoSample*>(data)->right, available, true);
64 GBASyncConsumeAudio(&m_context->sync);
65 return available * sizeof(GBAStereoSample);
66#endif
67}
68
69qint64 AudioDevice::writeData(const char*, qint64) {
70 return 0;
71}