mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-01-02 22:55:23 +00:00
Ladybird: Detect changes to the default audio device
When the default audio device changes on the host, it's convenient to automatically switch to that device rather than needing to reload the page to update.
This commit is contained in:
committed by
Andreas Kling
parent
8f927eaa68
commit
33dbfa3281
@@ -27,6 +27,7 @@ struct AudioTask {
|
||||
Pause,
|
||||
Seek,
|
||||
Volume,
|
||||
RecreateAudioDevice,
|
||||
};
|
||||
|
||||
Type type;
|
||||
@@ -82,20 +83,64 @@ private:
|
||||
No,
|
||||
};
|
||||
|
||||
struct AudioDevice {
|
||||
static AudioDevice create()
|
||||
{
|
||||
auto const& device_info = QMediaDevices::defaultAudioOutput();
|
||||
|
||||
auto format = device_info.preferredFormat();
|
||||
format.setChannelCount(2);
|
||||
|
||||
auto audio_output = make<QAudioSink>(device_info, format);
|
||||
return AudioDevice { move(audio_output) };
|
||||
}
|
||||
|
||||
AudioDevice(AudioDevice&&) = default;
|
||||
|
||||
AudioDevice& operator=(AudioDevice&& device)
|
||||
{
|
||||
if (audio_output) {
|
||||
audio_output->stop();
|
||||
io_device = nullptr;
|
||||
}
|
||||
|
||||
swap(audio_output, device.audio_output);
|
||||
swap(io_device, device.io_device);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~AudioDevice()
|
||||
{
|
||||
if (audio_output)
|
||||
audio_output->stop();
|
||||
}
|
||||
|
||||
OwnPtr<QAudioSink> audio_output;
|
||||
QIODevice* io_device { nullptr };
|
||||
|
||||
private:
|
||||
explicit AudioDevice(NonnullOwnPtr<QAudioSink> output)
|
||||
: audio_output(move(output))
|
||||
{
|
||||
io_device = audio_output->start();
|
||||
}
|
||||
};
|
||||
|
||||
void run() override
|
||||
{
|
||||
auto devices = make<QMediaDevices>();
|
||||
auto const& device_info = devices->defaultAudioOutput();
|
||||
auto audio_device = AudioDevice::create();
|
||||
|
||||
auto format = device_info.preferredFormat();
|
||||
format.setChannelCount(2);
|
||||
|
||||
auto audio_output = make<QAudioSink>(device_info, format);
|
||||
auto* io_device = audio_output->start();
|
||||
connect(devices, &QMediaDevices::audioOutputsChanged, this, [this]() {
|
||||
queue_task({ AudioTask::Type::RecreateAudioDevice }).release_value_but_fixme_should_propagate_errors();
|
||||
});
|
||||
|
||||
auto paused = Paused::Yes;
|
||||
|
||||
while (true) {
|
||||
auto& audio_output = audio_device.audio_output;
|
||||
auto* io_device = audio_device.io_device;
|
||||
|
||||
if (auto result = m_task_queue.dequeue(); result.is_error()) {
|
||||
VERIFY(result.error() == AudioTaskQueue::QueueStatus::Empty);
|
||||
} else {
|
||||
@@ -136,6 +181,10 @@ private:
|
||||
VERIFY(task.data.has_value());
|
||||
audio_output->setVolume(*task.data);
|
||||
break;
|
||||
|
||||
case AudioTask::Type::RecreateAudioDevice:
|
||||
audio_device = AudioDevice::create();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user