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
8#include "LogController.h"
9
10extern "C" {
11#include "core/thread.h"
12#include "gba/gba.h"
13#include "gba/audio.h"
14}
15
16using namespace QGBA;
17
18AudioDevice::AudioDevice(QObject* parent)
19 : QIODevice(parent)
20 , m_context(nullptr)
21 , m_drift(0)
22 , m_ratio(1.f)
23{
24 setOpenMode(ReadOnly);
25}
26
27void AudioDevice::setFormat(const QAudioFormat& format) {
28 if (!m_context || !mCoreThreadIsActive(m_context)) {
29 LOG(INFO) << tr("Can't set format of context-less audio device");
30 return;
31 }
32 double fauxClock = GBAAudioCalculateRatio(1, 60, 1); // TODO: Put back fpsTarget
33 mCoreSyncLockAudio(&m_context->sync);
34 blip_set_rates(m_context->core->getAudioChannel(m_context->core, 0), GBA_ARM7TDMI_FREQUENCY, format.sampleRate() * fauxClock);
35 blip_set_rates(m_context->core->getAudioChannel(m_context->core, 1), GBA_ARM7TDMI_FREQUENCY, format.sampleRate() * fauxClock);
36 mCoreSyncUnlockAudio(&m_context->sync);
37}
38
39void AudioDevice::setInput(mCoreThread* input) {
40 m_context = input;
41}
42
43qint64 AudioDevice::readData(char* data, qint64 maxSize) {
44 if (maxSize > 0xFFFFFFFF) {
45 maxSize = 0xFFFFFFFF;
46 }
47
48 if (!m_context->core) {
49 LOG(WARN) << tr("Audio device is missing its core");
50 return 0;
51 }
52
53 mCoreSyncLockAudio(&m_context->sync);
54 int available = blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0));
55 if (available > maxSize / sizeof(GBAStereoSample)) {
56 available = maxSize / sizeof(GBAStereoSample);
57 }
58 blip_read_samples(m_context->core->getAudioChannel(m_context->core, 0), &reinterpret_cast<GBAStereoSample*>(data)->left, available, true);
59 blip_read_samples(m_context->core->getAudioChannel(m_context->core, 1), &reinterpret_cast<GBAStereoSample*>(data)->right, available, true);
60 mCoreSyncConsumeAudio(&m_context->sync);
61 return available * sizeof(GBAStereoSample);
62}
63
64qint64 AudioDevice::writeData(const char*, qint64) {
65 LOG(WARN) << tr("Writing data to read-only audio device");
66 return 0;
67}