mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +00:00
AudioServer: Allow muting the system audio
This patch adds muting to ASMixer, which works by substituting what we would normally send to the sound card with zero-filled memory instead. We do it this way to ensure that the queued sample buffers keep getting played (silently.) This is obviously not the perfect way of doing this, and in the future we should improve on this, and also find a way to utilize any hardware mixing functions in the sound card.
This commit is contained in:
parent
2b9ec22576
commit
107011f119
Notes:
sideshowbarker
2024-07-19 11:06:56 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/107011f1190
8 changed files with 72 additions and 15 deletions
|
@ -32,6 +32,16 @@ bool AClientConnection::try_enqueue(const ABuffer& buffer)
|
|||
return response->success();
|
||||
}
|
||||
|
||||
bool AClientConnection::get_muted()
|
||||
{
|
||||
return send_sync<AudioServer::GetMuted>()->muted();
|
||||
}
|
||||
|
||||
void AClientConnection::set_muted(bool muted)
|
||||
{
|
||||
send_sync<AudioServer::SetMuted>(muted);
|
||||
}
|
||||
|
||||
int AClientConnection::get_main_mix_volume()
|
||||
{
|
||||
return send_sync<AudioServer::GetMainMixVolume>()->volume();
|
||||
|
|
|
@ -14,6 +14,9 @@ public:
|
|||
void enqueue(const ABuffer&);
|
||||
bool try_enqueue(const ABuffer&);
|
||||
|
||||
bool get_muted();
|
||||
void set_muted(bool);
|
||||
|
||||
int get_main_mix_volume();
|
||||
void set_main_mix_volume(int);
|
||||
|
||||
|
|
|
@ -104,9 +104,21 @@ OwnPtr<AudioServer::ClearBufferResponse> ASClientConnection::handle(const AudioS
|
|||
return make<AudioServer::ClearBufferResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<AudioServer::GetPlayingBufferResponse> ASClientConnection::handle(const AudioServer::GetPlayingBuffer&){
|
||||
OwnPtr<AudioServer::GetPlayingBufferResponse> ASClientConnection::handle(const AudioServer::GetPlayingBuffer&)
|
||||
{
|
||||
int id = -1;
|
||||
if(m_queue)
|
||||
if (m_queue)
|
||||
id = m_queue->get_playing_buffer();
|
||||
return make<AudioServer::GetPlayingBufferResponse>(id);
|
||||
}
|
||||
|
||||
OwnPtr<AudioServer::GetMutedResponse> ASClientConnection::handle(const AudioServer::GetMuted&)
|
||||
{
|
||||
return make<AudioServer::GetMutedResponse>(m_mixer.is_muted());
|
||||
}
|
||||
|
||||
OwnPtr<AudioServer::SetMutedResponse> ASClientConnection::handle(const AudioServer::SetMuted& message)
|
||||
{
|
||||
m_mixer.set_muted(message.muted());
|
||||
return make<AudioServer::SetMutedResponse>();
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ private:
|
|||
virtual OwnPtr<AudioServer::SetPausedResponse> handle(const AudioServer::SetPaused&) override;
|
||||
virtual OwnPtr<AudioServer::ClearBufferResponse> handle(const AudioServer::ClearBuffer&) override;
|
||||
virtual OwnPtr<AudioServer::GetPlayingBufferResponse> handle(const AudioServer::GetPlayingBuffer&) override;
|
||||
virtual OwnPtr<AudioServer::GetMutedResponse> handle(const AudioServer::GetMuted&) override;
|
||||
virtual OwnPtr<AudioServer::SetMutedResponse> handle(const AudioServer::SetMuted&) override;
|
||||
|
||||
ASMixer& m_mixer;
|
||||
RefPtr<ASBufferQueue> m_queue;
|
||||
|
|
|
@ -15,6 +15,8 @@ ASMixer::ASMixer()
|
|||
return;
|
||||
}
|
||||
|
||||
m_zero_filled_buffer = (u8*)malloc(4096);
|
||||
bzero(m_zero_filled_buffer, 4096);
|
||||
m_sound_thread.start();
|
||||
}
|
||||
|
||||
|
@ -66,33 +68,42 @@ void ASMixer::mix()
|
|||
}
|
||||
}
|
||||
|
||||
bool muted = m_muted;
|
||||
|
||||
// output the mixed stuff to the device
|
||||
u8 raw_buffer[4096];
|
||||
auto buffer = ByteBuffer::wrap(raw_buffer, sizeof(raw_buffer));
|
||||
auto buffer = ByteBuffer::wrap(muted ? m_zero_filled_buffer : raw_buffer, sizeof(raw_buffer));
|
||||
|
||||
BufferStream stream(buffer);
|
||||
if (!muted) {
|
||||
for (int i = 0; i < mixed_buffer_length; ++i) {
|
||||
auto& mixed_sample = mixed_buffer[i];
|
||||
|
||||
for (int i = 0; i < mixed_buffer_length; ++i) {
|
||||
auto& mixed_sample = mixed_buffer[i];
|
||||
mixed_sample.scale(m_main_volume);
|
||||
mixed_sample.clip();
|
||||
|
||||
mixed_sample.scale(m_main_volume);
|
||||
mixed_sample.clip();
|
||||
i16 out_sample;
|
||||
out_sample = mixed_sample.left * std::numeric_limits<i16>::max();
|
||||
stream << out_sample;
|
||||
|
||||
i16 out_sample;
|
||||
out_sample = mixed_sample.left * std::numeric_limits<i16>::max();
|
||||
stream << out_sample;
|
||||
|
||||
ASSERT(!stream.at_end()); // we should have enough space for both channels in one buffer!
|
||||
out_sample = mixed_sample.right * std::numeric_limits<i16>::max();
|
||||
stream << out_sample;
|
||||
ASSERT(!stream.at_end()); // we should have enough space for both channels in one buffer!
|
||||
out_sample = mixed_sample.right * std::numeric_limits<i16>::max();
|
||||
stream << out_sample;
|
||||
}
|
||||
}
|
||||
|
||||
if (stream.offset() != 0) {
|
||||
buffer.trim(stream.offset());
|
||||
m_device->write(buffer);
|
||||
}
|
||||
m_device->write(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void ASMixer::set_muted(bool muted)
|
||||
{
|
||||
m_muted = muted;
|
||||
}
|
||||
|
||||
ASBufferQueue::ASBufferQueue(ASClientConnection& client)
|
||||
: m_client(client.make_weak_ptr())
|
||||
{
|
||||
|
|
|
@ -87,6 +87,9 @@ public:
|
|||
int main_volume() const { return m_main_volume; }
|
||||
void set_main_volume(int volume) { m_main_volume = volume; }
|
||||
|
||||
bool is_muted() const { return m_muted; }
|
||||
void set_muted(bool);
|
||||
|
||||
private:
|
||||
Vector<NonnullRefPtr<ASBufferQueue>> m_pending_mixing;
|
||||
|
||||
|
@ -95,7 +98,10 @@ private:
|
|||
|
||||
LibThread::Thread m_sound_thread;
|
||||
|
||||
bool m_muted { false };
|
||||
int m_main_volume { 100 };
|
||||
|
||||
u8* m_zero_filled_buffer { nullptr };
|
||||
|
||||
void mix();
|
||||
};
|
||||
|
|
|
@ -4,6 +4,8 @@ endpoint AudioServer
|
|||
Greet(i32 client_pid) => (i32 server_pid, i32 client_id)
|
||||
|
||||
// Mixer functions
|
||||
SetMuted(bool muted) => ()
|
||||
GetMuted() => (bool muted)
|
||||
GetMainMixVolume() => (i32 volume)
|
||||
SetMainMixVolume(i32 volume) => ()
|
||||
|
||||
|
|
|
@ -9,6 +9,17 @@ int main(int argc, char** argv)
|
|||
audio_client->handshake();
|
||||
|
||||
if (argc > 1) {
|
||||
if (String(argv[1]) == "-m") {
|
||||
audio_client->set_muted(true);
|
||||
printf("Muted.\n");
|
||||
return 0;
|
||||
}
|
||||
if (String(argv[1]) == "-M") {
|
||||
audio_client->set_muted(false);
|
||||
printf("Unmuted.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int new_volume = atoi(argv[1]);
|
||||
audio_client->set_main_mix_volume(new_volume);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue