summaryrefslogtreecommitdiff
path: root/Servers
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-11-22 21:44:02 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-11-22 21:44:02 +0100
commit107011f1190004b3a18f395c145ee6211301622c (patch)
treeeecce461dec6dac7bc5206f1a2e4b1be3f0a56b6 /Servers
parent2b9ec2257605335ec43aab01e2b7bd8107850f1b (diff)
downloadserenity-107011f1190004b3a18f395c145ee6211301622c.zip
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.
Diffstat (limited to 'Servers')
-rw-r--r--Servers/AudioServer/ASClientConnection.cpp16
-rw-r--r--Servers/AudioServer/ASClientConnection.h2
-rw-r--r--Servers/AudioServer/ASMixer.cpp37
-rw-r--r--Servers/AudioServer/ASMixer.h6
-rw-r--r--Servers/AudioServer/AudioServer.ipc2
5 files changed, 48 insertions, 15 deletions
diff --git a/Servers/AudioServer/ASClientConnection.cpp b/Servers/AudioServer/ASClientConnection.cpp
index 7bfe1df067..47595c458d 100644
--- a/Servers/AudioServer/ASClientConnection.cpp
+++ b/Servers/AudioServer/ASClientConnection.cpp
@@ -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>();
+}
diff --git a/Servers/AudioServer/ASClientConnection.h b/Servers/AudioServer/ASClientConnection.h
index d3946a834f..b23886dcba 100644
--- a/Servers/AudioServer/ASClientConnection.h
+++ b/Servers/AudioServer/ASClientConnection.h
@@ -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;
diff --git a/Servers/AudioServer/ASMixer.cpp b/Servers/AudioServer/ASMixer.cpp
index 15a317e4a4..2cd71e8bec 100644
--- a/Servers/AudioServer/ASMixer.cpp
+++ b/Servers/AudioServer/ASMixer.cpp
@@ -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));
- BufferStream stream(buffer);
+ auto buffer = ByteBuffer::wrap(muted ? m_zero_filled_buffer : raw_buffer, sizeof(raw_buffer));
- for (int i = 0; i < mixed_buffer_length; ++i) {
- auto& mixed_sample = mixed_buffer[i];
+ BufferStream stream(buffer);
+ if (!muted) {
+ 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())
{
diff --git a/Servers/AudioServer/ASMixer.h b/Servers/AudioServer/ASMixer.h
index e2a823b029..960dce9996 100644
--- a/Servers/AudioServer/ASMixer.h
+++ b/Servers/AudioServer/ASMixer.h
@@ -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();
};
diff --git a/Servers/AudioServer/AudioServer.ipc b/Servers/AudioServer/AudioServer.ipc
index 469e226eef..1bdc7c8091 100644
--- a/Servers/AudioServer/AudioServer.ipc
+++ b/Servers/AudioServer/AudioServer.ipc
@@ -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) => ()