mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 06:04:57 +00:00
AudioServer+Userland: Separate audio IPC into normal client and manager
This is a sensible separation of concerns that mirrors the WindowServer IPC split. On the one hand, there is the "normal" audio interface, used for clients that play audio, which is the primary service of AudioServer. On the other hand, there is the management interface, which, like the WindowManager endpoint, provides higher-level control over clients and the server itself. The reasoning for this split are manifold, as mentioned we are mirroring the WindowServer split. Another indication to the sensibility of the split is that no single audio client used the APIs of both interfaces. Also, useless audio queues are no longer created for managing clients (since those don't even exist, just like there's no window backing bitmap for window managing clients), eliminating any bugs that may occur there as they have in the past. Implementation-wise, we just move all the APIs and implementations from the old AudioServer into the AudioManagerServer (and respective clients, of course). There is one point of duplication, namely the hardware sample rate. This will be fixed in combination with per-client sample rate, eliminating client-side resampling and the related update bugs. For now, we keep one legacy API to simplify the transition. The new AudioManagerServer also gains a hardware sample rate change callback to have exact symmetry on the main server parameters (getter, setter, and callback).
This commit is contained in:
parent
c3f5b514c8
commit
03fac609ee
20 changed files with 250 additions and 87 deletions
|
@ -58,7 +58,7 @@ Priority=low
|
|||
KeepAlive=true
|
||||
|
||||
[AudioServer]
|
||||
Socket=/tmp/session/%sid/portal/audio
|
||||
Socket=/tmp/session/%sid/portal/audio,/tmp/session/%sid/portal/audiomanager
|
||||
Priority=high
|
||||
KeepAlive=true
|
||||
SystemModes=text,graphical
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/Array.h>
|
||||
#include <LibAudio/ConnectionToServer.h>
|
||||
#include <LibAudio/ConnectionToManagerServer.h>
|
||||
#include <LibConfig/Client.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibGUI/Application.h>
|
||||
|
@ -45,14 +45,14 @@ public:
|
|||
{ 0, TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/audio-volume-zero.png"sv)) },
|
||||
{ 0, TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/audio-volume-muted.png"sv)) } }
|
||||
};
|
||||
auto audio_client = TRY(Audio::ConnectionToServer::try_create());
|
||||
auto audio_client = TRY(Audio::ConnectionToManagerServer::try_create());
|
||||
NonnullRefPtr<AudioWidget> audio_widget = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AudioWidget(move(audio_client), move(volume_level_bitmaps))));
|
||||
TRY(audio_widget->try_initialize_graphical_elements());
|
||||
return audio_widget;
|
||||
}
|
||||
|
||||
private:
|
||||
AudioWidget(NonnullRefPtr<Audio::ConnectionToServer> audio_client, Array<VolumeBitmapPair, 5> volume_level_bitmaps)
|
||||
AudioWidget(NonnullRefPtr<Audio::ConnectionToManagerServer> audio_client, Array<VolumeBitmapPair, 5> volume_level_bitmaps)
|
||||
: m_audio_client(move(audio_client))
|
||||
, m_volume_level_bitmaps(move(volume_level_bitmaps))
|
||||
{
|
||||
|
@ -217,7 +217,7 @@ private:
|
|||
height);
|
||||
}
|
||||
|
||||
NonnullRefPtr<Audio::ConnectionToServer> m_audio_client;
|
||||
NonnullRefPtr<Audio::ConnectionToManagerServer> m_audio_client;
|
||||
Array<VolumeBitmapPair, 5> m_volume_level_bitmaps;
|
||||
bool m_show_percent { false };
|
||||
bool m_audio_muted { false };
|
||||
|
@ -236,7 +236,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
|
||||
auto app = TRY(GUI::Application::create(arguments));
|
||||
Config::pledge_domain("AudioApplet");
|
||||
TRY(Core::System::unveil("/tmp/session/%sid/portal/audio", "rw"));
|
||||
TRY(Core::System::unveil("/tmp/session/%sid/portal/audiomanager", "rw"));
|
||||
TRY(Core::System::unveil("/res", "r"));
|
||||
TRY(Core::System::unveil(nullptr, nullptr));
|
||||
|
||||
|
|
|
@ -16,9 +16,12 @@ set(SOURCES
|
|||
|
||||
if (SERENITYOS)
|
||||
list(APPEND SOURCES ConnectionToServer.cpp)
|
||||
list(APPEND SOURCES ConnectionToManagerServer.cpp)
|
||||
set(GENERATED_SOURCES
|
||||
../../Services/AudioServer/AudioClientEndpoint.h
|
||||
../../Services/AudioServer/AudioServerEndpoint.h
|
||||
../../Services/AudioServer/AudioManagerClientEndpoint.h
|
||||
../../Services/AudioServer/AudioManagerServerEndpoint.h
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
41
Userland/Libraries/LibAudio/ConnectionToManagerServer.cpp
Normal file
41
Userland/Libraries/LibAudio/ConnectionToManagerServer.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "ConnectionToManagerServer.h"
|
||||
|
||||
namespace Audio {
|
||||
|
||||
ConnectionToManagerServer::ConnectionToManagerServer(NonnullOwnPtr<Core::LocalSocket> socket)
|
||||
: IPC::ConnectionToServer<AudioManagerClientEndpoint, AudioManagerServerEndpoint>(*this, move(socket))
|
||||
{
|
||||
}
|
||||
|
||||
ConnectionToManagerServer::~ConnectionToManagerServer()
|
||||
{
|
||||
die();
|
||||
}
|
||||
|
||||
void ConnectionToManagerServer::die() { }
|
||||
|
||||
void ConnectionToManagerServer::main_mix_muted_state_changed(bool muted)
|
||||
{
|
||||
if (on_main_mix_muted_state_change)
|
||||
on_main_mix_muted_state_change(muted);
|
||||
}
|
||||
|
||||
void ConnectionToManagerServer::main_mix_volume_changed(double volume)
|
||||
{
|
||||
if (on_main_mix_volume_change)
|
||||
on_main_mix_volume_change(volume);
|
||||
}
|
||||
|
||||
void ConnectionToManagerServer::device_sample_rate_changed(u32 sample_rate)
|
||||
{
|
||||
if (on_device_sample_rate_change)
|
||||
on_device_sample_rate_change(sample_rate);
|
||||
}
|
||||
|
||||
}
|
36
Userland/Libraries/LibAudio/ConnectionToManagerServer.h
Normal file
36
Userland/Libraries/LibAudio/ConnectionToManagerServer.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <LibIPC/ConnectionToServer.h>
|
||||
#include <Userland/Services/AudioServer/AudioManagerClientEndpoint.h>
|
||||
#include <Userland/Services/AudioServer/AudioManagerServerEndpoint.h>
|
||||
|
||||
namespace Audio {
|
||||
|
||||
class ConnectionToManagerServer final
|
||||
: public IPC::ConnectionToServer<AudioManagerClientEndpoint, AudioManagerServerEndpoint>
|
||||
, public AudioManagerClientEndpoint {
|
||||
IPC_CLIENT_CONNECTION(ConnectionToManagerServer, "/tmp/session/%sid/portal/audiomanager"sv)
|
||||
public:
|
||||
virtual ~ConnectionToManagerServer() override;
|
||||
virtual void die() override;
|
||||
|
||||
virtual void main_mix_volume_changed(double volume) override;
|
||||
virtual void main_mix_muted_state_changed(bool muted) override;
|
||||
virtual void device_sample_rate_changed(u32 sample_rate) override;
|
||||
|
||||
Function<void(bool muted)> on_main_mix_muted_state_change;
|
||||
Function<void(double volume)> on_main_mix_volume_change;
|
||||
Function<void(u32 sample_rate)> on_device_sample_rate_change;
|
||||
|
||||
private:
|
||||
ConnectionToManagerServer(NonnullOwnPtr<Core::LocalSocket>);
|
||||
};
|
||||
|
||||
}
|
|
@ -142,18 +142,6 @@ size_t ConnectionToServer::remaining_buffers() const
|
|||
return m_buffer->size() - m_buffer->weak_remaining_capacity();
|
||||
}
|
||||
|
||||
void ConnectionToServer::main_mix_muted_state_changed(bool muted)
|
||||
{
|
||||
if (on_main_mix_muted_state_change)
|
||||
on_main_mix_muted_state_change(muted);
|
||||
}
|
||||
|
||||
void ConnectionToServer::main_mix_volume_changed(double volume)
|
||||
{
|
||||
if (on_main_mix_volume_change)
|
||||
on_main_mix_volume_change(volume);
|
||||
}
|
||||
|
||||
void ConnectionToServer::client_volume_changed(double volume)
|
||||
{
|
||||
if (on_client_volume_change)
|
||||
|
|
|
@ -57,15 +57,11 @@ public:
|
|||
|
||||
virtual void die() override;
|
||||
|
||||
Function<void(bool muted)> on_main_mix_muted_state_change;
|
||||
Function<void(double volume)> on_main_mix_volume_change;
|
||||
Function<void(double volume)> on_client_volume_change;
|
||||
|
||||
private:
|
||||
ConnectionToServer(NonnullOwnPtr<Core::LocalSocket>);
|
||||
|
||||
virtual void main_mix_muted_state_changed(bool) override;
|
||||
virtual void main_mix_volume_changed(double) override;
|
||||
virtual void client_volume_changed(double) override;
|
||||
|
||||
// We use this to perform the audio enqueuing on the background thread's event loop
|
||||
|
|
|
@ -2,7 +2,5 @@
|
|||
|
||||
endpoint AudioClient
|
||||
{
|
||||
main_mix_muted_state_changed(bool muted) =|
|
||||
main_mix_volume_changed(double volume) =|
|
||||
client_volume_changed(double volume) =|
|
||||
}
|
||||
|
|
6
Userland/Services/AudioServer/AudioManagerClient.ipc
Normal file
6
Userland/Services/AudioServer/AudioManagerClient.ipc
Normal file
|
@ -0,0 +1,6 @@
|
|||
endpoint AudioManagerClient
|
||||
{
|
||||
main_mix_muted_state_changed(bool muted) =|
|
||||
main_mix_volume_changed(double volume) =|
|
||||
device_sample_rate_changed(u32 sample_rate) =|
|
||||
}
|
11
Userland/Services/AudioServer/AudioManagerServer.ipc
Normal file
11
Userland/Services/AudioServer/AudioManagerServer.ipc
Normal file
|
@ -0,0 +1,11 @@
|
|||
endpoint AudioManagerServer
|
||||
{
|
||||
set_main_mix_muted(bool muted) => ()
|
||||
is_main_mix_muted() => (bool muted)
|
||||
get_main_mix_volume() => (double volume)
|
||||
set_main_mix_volume(double volume) => ()
|
||||
|
||||
// Audio device
|
||||
set_device_sample_rate(u32 sample_rate) => ()
|
||||
get_device_sample_rate() => (u32 sample_rate)
|
||||
}
|
|
@ -3,18 +3,12 @@
|
|||
|
||||
endpoint AudioServer
|
||||
{
|
||||
// Mixer functions
|
||||
set_main_mix_muted(bool muted) => ()
|
||||
is_main_mix_muted() => (bool muted)
|
||||
set_self_muted(bool muted) => ()
|
||||
is_self_muted() => (bool muted)
|
||||
get_main_mix_volume() => (double volume)
|
||||
set_main_mix_volume(double volume) => ()
|
||||
get_self_volume() => (double volume)
|
||||
set_self_volume(double volume) => ()
|
||||
|
||||
// Audio device
|
||||
set_sample_rate(u32 sample_rate) => ()
|
||||
// FIXME: Decouple client sample rate from device sample rate, then remove this API
|
||||
get_sample_rate() => (u32 sample_rate)
|
||||
|
||||
// Buffer playback
|
||||
|
|
|
@ -6,9 +6,12 @@ serenity_component(
|
|||
|
||||
compile_ipc(AudioServer.ipc AudioServerEndpoint.h)
|
||||
compile_ipc(AudioClient.ipc AudioClientEndpoint.h)
|
||||
compile_ipc(AudioManagerClient.ipc AudioManagerClientEndpoint.h)
|
||||
compile_ipc(AudioManagerServer.ipc AudioManagerServerEndpoint.h)
|
||||
|
||||
set(SOURCES
|
||||
ConnectionFromClient.cpp
|
||||
ConnectionFromManagerClient.cpp
|
||||
Mixer.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
@ -16,6 +19,8 @@ set(SOURCES
|
|||
set(GENERATED_SOURCES
|
||||
AudioServerEndpoint.h
|
||||
AudioClientEndpoint.h
|
||||
AudioManagerClientEndpoint.h
|
||||
AudioManagerServerEndpoint.h
|
||||
)
|
||||
|
||||
serenity_bin(AudioServer)
|
||||
|
|
|
@ -47,41 +47,16 @@ void ConnectionFromClient::set_buffer(Audio::AudioQueue const& buffer)
|
|||
m_queue->set_buffer(make<Audio::AudioQueue>(move(const_cast<Audio::AudioQueue&>(buffer))));
|
||||
}
|
||||
|
||||
void ConnectionFromClient::did_change_main_mix_muted_state(Badge<Mixer>, bool muted)
|
||||
{
|
||||
async_main_mix_muted_state_changed(muted);
|
||||
}
|
||||
|
||||
void ConnectionFromClient::did_change_main_mix_volume(Badge<Mixer>, double volume)
|
||||
{
|
||||
async_main_mix_volume_changed(volume);
|
||||
}
|
||||
|
||||
void ConnectionFromClient::did_change_client_volume(Badge<ClientAudioStream>, double volume)
|
||||
{
|
||||
async_client_volume_changed(volume);
|
||||
}
|
||||
|
||||
Messages::AudioServer::GetMainMixVolumeResponse ConnectionFromClient::get_main_mix_volume()
|
||||
{
|
||||
return m_mixer.main_volume();
|
||||
}
|
||||
|
||||
void ConnectionFromClient::set_main_mix_volume(double volume)
|
||||
{
|
||||
m_mixer.set_main_volume(volume);
|
||||
}
|
||||
|
||||
Messages::AudioServer::GetSampleRateResponse ConnectionFromClient::get_sample_rate()
|
||||
{
|
||||
return { m_mixer.audiodevice_get_sample_rate() };
|
||||
}
|
||||
|
||||
void ConnectionFromClient::set_sample_rate(u32 sample_rate)
|
||||
{
|
||||
m_mixer.audiodevice_set_sample_rate(sample_rate);
|
||||
}
|
||||
|
||||
Messages::AudioServer::GetSelfVolumeResponse ConnectionFromClient::get_self_volume()
|
||||
{
|
||||
return m_queue->volume().target();
|
||||
|
@ -111,16 +86,6 @@ void ConnectionFromClient::clear_buffer()
|
|||
m_queue->clear();
|
||||
}
|
||||
|
||||
Messages::AudioServer::IsMainMixMutedResponse ConnectionFromClient::is_main_mix_muted()
|
||||
{
|
||||
return m_mixer.is_muted();
|
||||
}
|
||||
|
||||
void ConnectionFromClient::set_main_mix_muted(bool muted)
|
||||
{
|
||||
m_mixer.set_muted(muted);
|
||||
}
|
||||
|
||||
Messages::AudioServer::IsSelfMutedResponse ConnectionFromClient::is_self_muted()
|
||||
{
|
||||
if (m_queue)
|
||||
|
|
|
@ -24,8 +24,6 @@ public:
|
|||
~ConnectionFromClient() override = default;
|
||||
|
||||
void did_change_client_volume(Badge<ClientAudioStream>, double volume);
|
||||
void did_change_main_mix_muted_state(Badge<Mixer>, bool muted);
|
||||
void did_change_main_mix_volume(Badge<Mixer>, double volume);
|
||||
|
||||
virtual void die() override;
|
||||
|
||||
|
@ -34,19 +32,15 @@ public:
|
|||
private:
|
||||
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>, int client_id, Mixer& mixer);
|
||||
|
||||
virtual Messages::AudioServer::GetMainMixVolumeResponse get_main_mix_volume() override;
|
||||
virtual void set_main_mix_volume(double) override;
|
||||
virtual Messages::AudioServer::GetSelfVolumeResponse get_self_volume() override;
|
||||
virtual void set_self_volume(double) override;
|
||||
virtual void set_buffer(Audio::AudioQueue const&) override;
|
||||
virtual void clear_buffer() override;
|
||||
virtual void start_playback() override;
|
||||
virtual void pause_playback() override;
|
||||
virtual Messages::AudioServer::IsMainMixMutedResponse is_main_mix_muted() override;
|
||||
virtual void set_main_mix_muted(bool) override;
|
||||
virtual Messages::AudioServer::IsSelfMutedResponse is_self_muted() override;
|
||||
virtual void set_self_muted(bool) override;
|
||||
virtual void set_sample_rate(u32 sample_rate) override;
|
||||
// FIXME: Decouple client sample rate from device sample rate, then remove this endpoint
|
||||
virtual Messages::AudioServer::GetSampleRateResponse get_sample_rate() override;
|
||||
|
||||
Mixer& m_mixer;
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "ConnectionFromManagerClient.h"
|
||||
|
||||
namespace AudioServer {
|
||||
|
||||
static HashMap<int, RefPtr<ConnectionFromManagerClient>> s_connections;
|
||||
|
||||
ConnectionFromManagerClient::ConnectionFromManagerClient(NonnullOwnPtr<Core::LocalSocket> client_socket, int client_id, Mixer& mixer)
|
||||
: IPC::ConnectionFromClient<AudioManagerClientEndpoint, AudioManagerServerEndpoint>(*this, move(client_socket), client_id)
|
||||
, m_mixer(mixer)
|
||||
{
|
||||
s_connections.set(client_id, *this);
|
||||
}
|
||||
|
||||
void ConnectionFromManagerClient::die()
|
||||
{
|
||||
s_connections.remove(client_id());
|
||||
}
|
||||
|
||||
void ConnectionFromManagerClient::for_each(Function<void(ConnectionFromManagerClient&)> callback)
|
||||
{
|
||||
Vector<NonnullRefPtr<ConnectionFromManagerClient>> connections;
|
||||
for (auto& it : s_connections)
|
||||
connections.append(*it.value);
|
||||
for (auto& connection : connections)
|
||||
callback(connection);
|
||||
}
|
||||
|
||||
void ConnectionFromManagerClient::did_change_main_mix_muted_state(Badge<Mixer>, bool muted)
|
||||
{
|
||||
async_main_mix_muted_state_changed(muted);
|
||||
}
|
||||
|
||||
void ConnectionFromManagerClient::did_change_main_mix_volume(Badge<Mixer>, double volume)
|
||||
{
|
||||
async_main_mix_volume_changed(volume);
|
||||
}
|
||||
|
||||
Messages::AudioManagerServer::GetMainMixVolumeResponse ConnectionFromManagerClient::get_main_mix_volume()
|
||||
{
|
||||
return m_mixer.main_volume();
|
||||
}
|
||||
|
||||
void ConnectionFromManagerClient::set_main_mix_volume(double volume)
|
||||
{
|
||||
m_mixer.set_main_volume(volume);
|
||||
}
|
||||
|
||||
Messages::AudioManagerServer::GetDeviceSampleRateResponse ConnectionFromManagerClient::get_device_sample_rate()
|
||||
{
|
||||
return { m_mixer.audiodevice_get_sample_rate() };
|
||||
}
|
||||
|
||||
void ConnectionFromManagerClient::set_device_sample_rate(u32 sample_rate)
|
||||
{
|
||||
m_mixer.audiodevice_set_sample_rate(sample_rate);
|
||||
}
|
||||
|
||||
Messages::AudioManagerServer::IsMainMixMutedResponse ConnectionFromManagerClient::is_main_mix_muted()
|
||||
{
|
||||
return m_mixer.is_muted();
|
||||
}
|
||||
|
||||
void ConnectionFromManagerClient::set_main_mix_muted(bool muted)
|
||||
{
|
||||
m_mixer.set_muted(muted);
|
||||
}
|
||||
|
||||
}
|
43
Userland/Services/AudioServer/ConnectionFromManagerClient.h
Normal file
43
Userland/Services/AudioServer/ConnectionFromManagerClient.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <AudioServer/AudioManagerClientEndpoint.h>
|
||||
#include <AudioServer/AudioManagerServerEndpoint.h>
|
||||
#include <AudioServer/Mixer.h>
|
||||
#include <LibIPC/ConnectionFromClient.h>
|
||||
|
||||
namespace AudioServer {
|
||||
|
||||
class ConnectionFromManagerClient final : public IPC::ConnectionFromClient<AudioManagerClientEndpoint, AudioManagerServerEndpoint> {
|
||||
C_OBJECT(ConnectionFromManagerClient)
|
||||
|
||||
public:
|
||||
~ConnectionFromManagerClient() override = default;
|
||||
|
||||
virtual void die() override;
|
||||
|
||||
static void for_each(Function<void(ConnectionFromManagerClient&)>);
|
||||
|
||||
void did_change_main_mix_muted_state(Badge<Mixer>, bool muted);
|
||||
void did_change_main_mix_volume(Badge<Mixer>, double volume);
|
||||
|
||||
private:
|
||||
ConnectionFromManagerClient(NonnullOwnPtr<Core::LocalSocket> client_socket, int client_id, Mixer& mixer);
|
||||
|
||||
virtual Messages::AudioManagerServer::GetMainMixVolumeResponse get_main_mix_volume() override;
|
||||
virtual void set_main_mix_volume(double) override;
|
||||
virtual Messages::AudioManagerServer::IsMainMixMutedResponse is_main_mix_muted() override;
|
||||
virtual void set_main_mix_muted(bool) override;
|
||||
virtual void set_device_sample_rate(u32 sample_rate) override;
|
||||
virtual Messages::AudioManagerServer::GetDeviceSampleRateResponse get_device_sample_rate() override;
|
||||
|
||||
Mixer& m_mixer;
|
||||
};
|
||||
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
#include <AK/MemoryStream.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <AudioServer/ConnectionFromClient.h>
|
||||
#include <AudioServer/ConnectionFromManagerClient.h>
|
||||
#include <AudioServer/Mixer.h>
|
||||
#include <LibCore/ConfigFile.h>
|
||||
#include <LibCore/Timer.h>
|
||||
|
@ -127,7 +128,7 @@ void Mixer::set_main_volume(double volume)
|
|||
m_config->write_num_entry("Master", "Volume", static_cast<int>(volume * 100));
|
||||
request_setting_sync();
|
||||
|
||||
ConnectionFromClient::for_each([&](ConnectionFromClient& client) {
|
||||
ConnectionFromManagerClient::for_each([&](auto& client) {
|
||||
client.did_change_main_mix_volume({}, main_volume());
|
||||
});
|
||||
}
|
||||
|
@ -141,7 +142,7 @@ void Mixer::set_muted(bool muted)
|
|||
m_config->write_bool_entry("Master", "Mute", m_muted);
|
||||
request_setting_sync();
|
||||
|
||||
ConnectionFromClient::for_each([muted](ConnectionFromClient& client) {
|
||||
ConnectionFromManagerClient::for_each([muted](auto& client) {
|
||||
client.did_change_main_mix_muted_state({}, muted);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -44,6 +44,10 @@ public:
|
|||
|
||||
bool get_next_sample(Audio::Sample& sample)
|
||||
{
|
||||
// Note: Even though we only check client state here, we will probably close the client much earlier.
|
||||
if (!is_connected())
|
||||
return false;
|
||||
|
||||
if (m_paused)
|
||||
return false;
|
||||
|
||||
|
@ -52,11 +56,6 @@ public:
|
|||
if (result.is_error()) {
|
||||
if (result.error() == Audio::AudioQueue::QueueStatus::Empty) {
|
||||
dbgln_if(AUDIO_DEBUG, "Audio client {} can't keep up!", m_client->client_id());
|
||||
// Note: Even though we only check client state here, we will probably close the client much earlier.
|
||||
if (!m_client->is_open()) {
|
||||
dbgln("Client socket {} has closed, closing audio server connection.", m_client->client_id());
|
||||
m_client->shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "ConnectionFromClient.h"
|
||||
#include "ConnectionFromManagerClient.h"
|
||||
#include "Mixer.h"
|
||||
#include <LibCore/ConfigFile.h>
|
||||
#include <LibCore/LocalServer.h>
|
||||
|
@ -23,7 +25,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
|
|||
Core::EventLoop event_loop;
|
||||
auto mixer = TRY(AudioServer::Mixer::try_create(config));
|
||||
auto server = TRY(Core::LocalServer::try_create());
|
||||
TRY(server->take_over_from_system_server());
|
||||
TRY(server->take_over_from_system_server("/tmp/session/%sid/portal/audio"));
|
||||
|
||||
server->on_accept = [&](NonnullOwnPtr<Core::LocalSocket> client_socket) {
|
||||
static int s_next_client_id = 0;
|
||||
|
@ -31,8 +33,16 @@ ErrorOr<int> serenity_main(Main::Arguments)
|
|||
(void)IPC::new_client_connection<AudioServer::ConnectionFromClient>(move(client_socket), client_id, *mixer);
|
||||
};
|
||||
|
||||
auto manager_server = TRY(Core::LocalServer::try_create());
|
||||
TRY(manager_server->take_over_from_system_server("/tmp/session/%sid/portal/audiomanager"));
|
||||
|
||||
manager_server->on_accept = [&](NonnullOwnPtr<Core::LocalSocket> client_socket) {
|
||||
static int s_next_client_id = 0;
|
||||
int client_id = ++s_next_client_id;
|
||||
(void)IPC::new_client_connection<AudioServer::ConnectionFromManagerClient>(move(client_socket), client_id, *mixer);
|
||||
};
|
||||
|
||||
TRY(Core::System::pledge("stdio recvfd thread accept cpath rpath wpath"));
|
||||
TRY(Core::System::unveil(nullptr, nullptr));
|
||||
|
||||
return event_loop.exec();
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <AK/Variant.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibAudio/ConnectionToServer.h>
|
||||
#include <LibAudio/ConnectionToManagerServer.h>
|
||||
#include <LibCore/ArgsParser.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/System.h>
|
||||
|
@ -27,8 +27,7 @@ enum AudioVariable : u32 {
|
|||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
Core::EventLoop loop;
|
||||
auto audio_client = TRY(Audio::ConnectionToServer::try_create());
|
||||
audio_client->async_pause_playback();
|
||||
auto audio_client = TRY(Audio::ConnectionToManagerServer::try_create());
|
||||
|
||||
StringView command;
|
||||
Vector<StringView> command_arguments;
|
||||
|
@ -85,7 +84,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
break;
|
||||
}
|
||||
case AudioVariable::SampleRate: {
|
||||
u32 sample_rate = audio_client->get_sample_rate();
|
||||
u32 sample_rate = audio_client->get_device_sample_rate();
|
||||
if (human_mode)
|
||||
outln("Sample rate: {:5d} Hz", sample_rate);
|
||||
else
|
||||
|
@ -155,7 +154,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
}
|
||||
case AudioVariable::SampleRate: {
|
||||
int& sample_rate = to_set.value.get<int>();
|
||||
audio_client->set_sample_rate(sample_rate);
|
||||
audio_client->set_device_sample_rate(sample_rate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue