summaryrefslogtreecommitdiff
path: root/src/audio_core
diff options
context:
space:
mode:
authorGravatar bunnei2016-04-30 03:49:11 -0400
committerGravatar bunnei2016-04-30 03:49:11 -0400
commitc1f0044a4b10bdff45464e5957f7950a6059d0c9 (patch)
treed9b4673f92da936ce763148f70b82bc7401dd968 /src/audio_core
parentMerge pull request #1650 from JamePeng/update-the-ndm-code (diff)
parentAudio: Add sink selection to configuration files (diff)
downloadyuzu-c1f0044a4b10bdff45464e5957f7950a6059d0c9.tar.gz
yuzu-c1f0044a4b10bdff45464e5957f7950a6059d0c9.tar.xz
yuzu-c1f0044a4b10bdff45464e5957f7950a6059d0c9.zip
Merge pull request #1729 from MerryMage/null-sink
Audio Config: Implement null sink and implement sink configuration
Diffstat (limited to 'src/audio_core')
-rw-r--r--src/audio_core/CMakeLists.txt3
-rw-r--r--src/audio_core/audio_core.cpp33
-rw-r--r--src/audio_core/audio_core.h5
-rw-r--r--src/audio_core/hle/dsp.cpp9
-rw-r--r--src/audio_core/hle/dsp.h11
-rw-r--r--src/audio_core/null_sink.h29
-rw-r--r--src/audio_core/sink_details.cpp18
-rw-r--r--src/audio_core/sink_details.h27
8 files changed, 131 insertions, 4 deletions
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
index a965af291..5a2747e78 100644
--- a/src/audio_core/CMakeLists.txt
+++ b/src/audio_core/CMakeLists.txt
@@ -5,6 +5,7 @@ set(SRCS
5 hle/filter.cpp 5 hle/filter.cpp
6 hle/pipe.cpp 6 hle/pipe.cpp
7 interpolate.cpp 7 interpolate.cpp
8 sink_details.cpp
8 ) 9 )
9 10
10set(HEADERS 11set(HEADERS
@@ -15,7 +16,9 @@ set(HEADERS
15 hle/filter.h 16 hle/filter.h
16 hle/pipe.h 17 hle/pipe.h
17 interpolate.h 18 interpolate.h
19 null_sink.h
18 sink.h 20 sink.h
21 sink_details.h
19 ) 22 )
20 23
21include_directories(../../externals/soundtouch/include) 24include_directories(../../externals/soundtouch/include)
diff --git a/src/audio_core/audio_core.cpp b/src/audio_core/audio_core.cpp
index cbe869a04..d42249ebd 100644
--- a/src/audio_core/audio_core.cpp
+++ b/src/audio_core/audio_core.cpp
@@ -2,9 +2,15 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <memory>
6#include <string>
7
5#include "audio_core/audio_core.h" 8#include "audio_core/audio_core.h"
6#include "audio_core/hle/dsp.h" 9#include "audio_core/hle/dsp.h"
7#include "audio_core/hle/pipe.h" 10#include "audio_core/hle/pipe.h"
11#include "audio_core/null_sink.h"
12#include "audio_core/sink.h"
13#include "audio_core/sink_details.h"
8 14
9#include "core/core_timing.h" 15#include "core/core_timing.h"
10#include "core/hle/kernel/vm_manager.h" 16#include "core/hle/kernel/vm_manager.h"
@@ -28,7 +34,6 @@ static void AudioTickCallback(u64 /*userdata*/, int cycles_late) {
28 CoreTiming::ScheduleEvent(audio_frame_ticks - cycles_late, tick_event); 34 CoreTiming::ScheduleEvent(audio_frame_ticks - cycles_late, tick_event);
29} 35}
30 36
31/// Initialise Audio
32void Init() { 37void Init() {
33 DSP::HLE::Init(); 38 DSP::HLE::Init();
34 39
@@ -36,7 +41,6 @@ void Init() {
36 CoreTiming::ScheduleEvent(audio_frame_ticks, tick_event); 41 CoreTiming::ScheduleEvent(audio_frame_ticks, tick_event);
37} 42}
38 43
39/// Add DSP address spaces to Process's address space.
40void AddAddressSpace(Kernel::VMManager& address_space) { 44void AddAddressSpace(Kernel::VMManager& address_space) {
41 auto r0_vma = address_space.MapBackingMemory(DSP::HLE::region0_base, reinterpret_cast<u8*>(&DSP::HLE::g_regions[0]), sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO).MoveFrom(); 45 auto r0_vma = address_space.MapBackingMemory(DSP::HLE::region0_base, reinterpret_cast<u8*>(&DSP::HLE::g_regions[0]), sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO).MoveFrom();
42 address_space.Reprotect(r0_vma, Kernel::VMAPermission::ReadWrite); 46 address_space.Reprotect(r0_vma, Kernel::VMAPermission::ReadWrite);
@@ -45,10 +49,31 @@ void AddAddressSpace(Kernel::VMManager& address_space) {
45 address_space.Reprotect(r1_vma, Kernel::VMAPermission::ReadWrite); 49 address_space.Reprotect(r1_vma, Kernel::VMAPermission::ReadWrite);
46} 50}
47 51
48/// Shutdown Audio 52void SelectSink(std::string sink_id) {
53 if (sink_id == "auto") {
54 // Auto-select.
55 // g_sink_details is ordered in terms of desirability, with the best choice at the front.
56 const auto& sink_detail = g_sink_details.front();
57 DSP::HLE::SetSink(sink_detail.factory());
58 return;
59 }
60
61 auto iter = std::find_if(g_sink_details.begin(), g_sink_details.end(), [sink_id](const auto& sink_detail) {
62 return sink_detail.id == sink_id;
63 });
64
65 if (iter == g_sink_details.end()) {
66 LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id");
67 DSP::HLE::SetSink(std::make_unique<NullSink>());
68 return;
69 }
70
71 DSP::HLE::SetSink(iter->factory());
72}
73
49void Shutdown() { 74void Shutdown() {
50 CoreTiming::UnscheduleEvent(tick_event, 0); 75 CoreTiming::UnscheduleEvent(tick_event, 0);
51 DSP::HLE::Shutdown(); 76 DSP::HLE::Shutdown();
52} 77}
53 78
54} //namespace 79} // namespace AudioCore
diff --git a/src/audio_core/audio_core.h b/src/audio_core/audio_core.h
index b349895ea..f618361f3 100644
--- a/src/audio_core/audio_core.h
+++ b/src/audio_core/audio_core.h
@@ -4,6 +4,8 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <string>
8
7namespace Kernel { 9namespace Kernel {
8class VMManager; 10class VMManager;
9} 11}
@@ -18,6 +20,9 @@ void Init();
18/// Add DSP address spaces to a Process. 20/// Add DSP address spaces to a Process.
19void AddAddressSpace(Kernel::VMManager& vm_manager); 21void AddAddressSpace(Kernel::VMManager& vm_manager);
20 22
23/// Select the sink to use based on sink id.
24void SelectSink(std::string sink_id);
25
21/// Shutdown Audio Core 26/// Shutdown Audio Core
22void Shutdown(); 27void Shutdown();
23 28
diff --git a/src/audio_core/hle/dsp.cpp b/src/audio_core/hle/dsp.cpp
index 5759a5b9e..4d44bd2d9 100644
--- a/src/audio_core/hle/dsp.cpp
+++ b/src/audio_core/hle/dsp.cpp
@@ -2,8 +2,11 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <memory>
6
5#include "audio_core/hle/dsp.h" 7#include "audio_core/hle/dsp.h"
6#include "audio_core/hle/pipe.h" 8#include "audio_core/hle/pipe.h"
9#include "audio_core/sink.h"
7 10
8namespace DSP { 11namespace DSP {
9namespace HLE { 12namespace HLE {
@@ -35,6 +38,8 @@ static SharedMemory& WriteRegion() {
35 return g_regions[1 - CurrentRegionIndex()]; 38 return g_regions[1 - CurrentRegionIndex()];
36} 39}
37 40
41static std::unique_ptr<AudioCore::Sink> sink;
42
38void Init() { 43void Init() {
39 DSP::HLE::ResetPipes(); 44 DSP::HLE::ResetPipes();
40} 45}
@@ -46,5 +51,9 @@ bool Tick() {
46 return true; 51 return true;
47} 52}
48 53
54void SetSink(std::unique_ptr<AudioCore::Sink> sink_) {
55 sink = std::move(sink_);
56}
57
49} // namespace HLE 58} // namespace HLE
50} // namespace DSP 59} // namespace DSP
diff --git a/src/audio_core/hle/dsp.h b/src/audio_core/hle/dsp.h
index f0f125284..4f2410c27 100644
--- a/src/audio_core/hle/dsp.h
+++ b/src/audio_core/hle/dsp.h
@@ -6,6 +6,7 @@
6 6
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include <memory>
9#include <type_traits> 10#include <type_traits>
10 11
11#include "audio_core/hle/common.h" 12#include "audio_core/hle/common.h"
@@ -15,6 +16,10 @@
15#include "common/common_types.h" 16#include "common/common_types.h"
16#include "common/swap.h" 17#include "common/swap.h"
17 18
19namespace AudioCore {
20class Sink;
21}
22
18namespace DSP { 23namespace DSP {
19namespace HLE { 24namespace HLE {
20 25
@@ -535,5 +540,11 @@ void Shutdown();
535 */ 540 */
536bool Tick(); 541bool Tick();
537 542
543/**
544 * Set the output sink. This must be called before calling Tick().
545 * @param sink The sink to which audio will be output to.
546 */
547void SetSink(std::unique_ptr<AudioCore::Sink> sink);
548
538} // namespace HLE 549} // namespace HLE
539} // namespace DSP 550} // namespace DSP
diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h
new file mode 100644
index 000000000..faf0ee4e1
--- /dev/null
+++ b/src/audio_core/null_sink.h
@@ -0,0 +1,29 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <cstddef>
8
9#include "audio_core/audio_core.h"
10#include "audio_core/sink.h"
11
12namespace AudioCore {
13
14class NullSink final : public Sink {
15public:
16 ~NullSink() override = default;
17
18 unsigned int GetNativeSampleRate() const override {
19 return native_sample_rate;
20 }
21
22 void EnqueueSamples(const std::vector<s16>&) override {}
23
24 size_t SamplesInQueue() const override {
25 return 0;
26 }
27};
28
29} // namespace AudioCore
diff --git a/src/audio_core/sink_details.cpp b/src/audio_core/sink_details.cpp
new file mode 100644
index 000000000..d2cc74103
--- /dev/null
+++ b/src/audio_core/sink_details.cpp
@@ -0,0 +1,18 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6#include <vector>
7
8#include "audio_core/null_sink.h"
9#include "audio_core/sink_details.h"
10
11namespace AudioCore {
12
13// g_sink_details is ordered in terms of desirability, with the best choice at the top.
14const std::vector<SinkDetails> g_sink_details = {
15 { "null", []() { return std::make_unique<NullSink>(); } },
16};
17
18} // namespace AudioCore
diff --git a/src/audio_core/sink_details.h b/src/audio_core/sink_details.h
new file mode 100644
index 000000000..4b30cf835
--- /dev/null
+++ b/src/audio_core/sink_details.h
@@ -0,0 +1,27 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <functional>
8#include <memory>
9#include <vector>
10
11namespace AudioCore {
12
13class Sink;
14
15struct SinkDetails {
16 SinkDetails(const char* id_, std::function<std::unique_ptr<Sink>()> factory_)
17 : id(id_), factory(factory_) {}
18
19 /// Name for this sink.
20 const char* id;
21 /// A method to call to construct an instance of this type of sink.
22 std::function<std::unique_ptr<Sink>()> factory;
23};
24
25extern const std::vector<SinkDetails> g_sink_details;
26
27} // namespace AudioCore