summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/audio_core/sink/oboe_sink.cpp47
1 files changed, 35 insertions, 12 deletions
diff --git a/src/audio_core/sink/oboe_sink.cpp b/src/audio_core/sink/oboe_sink.cpp
index fc62faaee..c502205e1 100644
--- a/src/audio_core/sink/oboe_sink.cpp
+++ b/src/audio_core/sink/oboe_sink.cpp
@@ -20,11 +20,10 @@ class OboeSinkStream final : public SinkStream,
20 public oboe::AudioStreamErrorCallback { 20 public oboe::AudioStreamErrorCallback {
21public: 21public:
22 explicit OboeSinkStream(Core::System& system_, StreamType type_, const std::string& name_, 22 explicit OboeSinkStream(Core::System& system_, StreamType type_, const std::string& name_,
23 u32 device_channels_, u32 system_channels_) 23 u32 system_channels_)
24 : SinkStream(system_, type_) { 24 : SinkStream(system_, type_) {
25 name = name_; 25 name = name_;
26 system_channels = system_channels_; 26 system_channels = system_channels_;
27 device_channels = device_channels_;
28 27
29 this->OpenStream(); 28 this->OpenStream();
30 } 29 }
@@ -62,6 +61,21 @@ public:
62 } 61 }
63 } 62 }
64 63
64public:
65 static s32 QueryChannelCount(oboe::Direction direction) {
66 std::shared_ptr<oboe::AudioStream> temp_stream;
67 oboe::AudioStreamBuilder builder;
68
69 const auto result = builder.setDirection(direction)
70 ->setSampleRate(TargetSampleRate)
71 ->setFormat(oboe::AudioFormat::I16)
72 ->setFormatConversionAllowed(true)
73 ->openStream(temp_stream);
74 ASSERT(result == oboe::Result::OK);
75
76 return temp_stream->getChannelCount() >= 6 ? 6 : 2;
77 }
78
65protected: 79protected:
66 oboe::DataCallbackResult onAudioReady(oboe::AudioStream*, void* audio_data, 80 oboe::DataCallbackResult onAudioReady(oboe::AudioStream*, void* audio_data,
67 s32 num_buffer_frames) override { 81 s32 num_buffer_frames) override {
@@ -105,8 +119,9 @@ private:
105 } 119 }
106 }(); 120 }();
107 121
108 const auto channel_mask = [&]() { 122 const auto expected_channels = QueryChannelCount(direction);
109 switch (device_channels) { 123 const auto expected_mask = [&]() {
124 switch (expected_channels) {
110 case 1: 125 case 1:
111 return oboe::ChannelMask::Mono; 126 return oboe::ChannelMask::Mono;
112 case 2: 127 case 2:
@@ -122,25 +137,33 @@ private:
122 oboe::AudioStreamBuilder builder; 137 oboe::AudioStreamBuilder builder;
123 const auto result = builder.setDirection(direction) 138 const auto result = builder.setDirection(direction)
124 ->setSampleRate(TargetSampleRate) 139 ->setSampleRate(TargetSampleRate)
125 ->setChannelCount(device_channels) 140 ->setChannelCount(expected_channels)
126 ->setChannelMask(channel_mask) 141 ->setChannelMask(expected_mask)
127 ->setFormat(oboe::AudioFormat::I16) 142 ->setFormat(oboe::AudioFormat::I16)
128 ->setFormatConversionAllowed(true) 143 ->setFormatConversionAllowed(true)
129 ->setDataCallback(this) 144 ->setDataCallback(this)
130 ->setErrorCallback(this) 145 ->setErrorCallback(this)
131 ->openStream(m_stream); 146 ->openStream(m_stream);
132
133 ASSERT(result == oboe::Result::OK); 147 ASSERT(result == oboe::Result::OK);
134 return result == oboe::Result::OK; 148 return result == oboe::Result::OK && this->SetStreamProperties();
149 }
150
151 bool SetStreamProperties() {
152 ASSERT(m_stream);
153
154 device_channels = m_stream->getChannelCount();
155 LOG_INFO(Audio_Sink, "Opened Oboe stream with {} channels", device_channels);
156
157 return true;
135 } 158 }
136 159
137 std::shared_ptr<oboe::AudioStream> m_stream{}; 160 std::shared_ptr<oboe::AudioStream> m_stream{};
138}; 161};
139 162
140OboeSink::OboeSink() { 163OboeSink::OboeSink() {
141 // TODO: how do we get the number of channels, or device list? 164 // TODO: This is not generally knowable
142 // This seems to be missing from NDK. 165 // The channel count is distinct based on direction and can change
143 device_channels = 2; 166 device_channels = OboeSinkStream::QueryChannelCount(oboe::Direction::Output);
144} 167}
145 168
146OboeSink::~OboeSink() = default; 169OboeSink::~OboeSink() = default;
@@ -148,7 +171,7 @@ OboeSink::~OboeSink() = default;
148SinkStream* OboeSink::AcquireSinkStream(Core::System& system, u32 system_channels, 171SinkStream* OboeSink::AcquireSinkStream(Core::System& system, u32 system_channels,
149 const std::string& name, StreamType type) { 172 const std::string& name, StreamType type) {
150 SinkStreamPtr& stream = sink_streams.emplace_back( 173 SinkStreamPtr& stream = sink_streams.emplace_back(
151 std::make_unique<OboeSinkStream>(system, type, name, device_channels, system_channels)); 174 std::make_unique<OboeSinkStream>(system, type, name, system_channels));
152 175
153 return stream.get(); 176 return stream.get();
154} 177}