Commit graph

44 commits

Author SHA1 Message Date
Sergey Bugaev
bd55938985 AudioServer: Port to socket takeover 2019-11-26 19:58:25 +01:00
Andreas Kling
84cb91de38 AudioServer: Broadcast muted state changes to all clients 2019-11-23 17:21:12 +01:00
Andreas Kling
630d5b3ffd LibIPC+AudioServer: Allow unsolicited server-to-client IPC messages
Client-side connection objects must now provide both client and server
endpoint types. When a message is received from the server side, we try
to decode it using both endpoint types and then send it to the right
place for handling.

This now makes it possible for AudioServer to send unsolicited messages
to its clients. This opens up a ton of possibilities :^)
2019-11-23 16:50:21 +01:00
Andreas Kling
107011f119 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.
2019-11-22 21:44:02 +01:00
Till Mayer
ac9907ee61 SoundPlayer: Changed some small cosmetic things
Renamed "Position" to "Elapsed". "channel/channels" automatically
changes now when more than one channel exist. The current file name
is now displayed in the window title.
2019-11-05 19:50:11 +01:00
Till Mayer
94a9649945 AWavLoader: Fixed incorrect computation of m_loaded_samples
m_loaded_samples was incremented with the value of the processed
buffer. This causes m_loaded_samples to be bigger at some point
than m_total_samples when downsampling, as the buffer would contain
more samples than actually loaded.
2019-11-05 19:50:11 +01:00
Till Mayer
2f13517a1a LibAudio: Added playback control features to audio server
LibAudio now supports pausing playback, clearing the buffer queue,
retrieving the played samples since the last clear and retrieving
the currently playing shared buffer id
2019-11-04 20:55:46 +01:00
Till Mayer
406aabff23 AudioServer: Added ability to get count of samples in the buffer queue
Now the AClientConnection can get the count of samples still in the
buffer queue.
2019-10-19 20:05:13 +02:00
Till Mayer
4c8341d080 LibAudio: Fixed stuttery playback of audio
When playing an ABuffer, the count of samples were determined by the
size of the SharedBuffer. This caused small pauses of up to 512
samples during the playback, when the size of the shared buffer was
rounded up to a multiple of 4096. This problem was amplified by the
fact that the AResampleHelper was created every time a new chunk of
audio was to be processed, causing inconsistencies in the playback of
wav files.
2019-10-16 16:25:38 +02:00
Andreas Kling
d6abfbdc5a LibCore: Remove ObjectPtr in favor of RefPtr
Now that CObject is fully ref-counted, just use RefPtr everywhere! :^)
2019-09-22 00:31:54 +02:00
Andreas Kling
8d550c174e LibCore: Convert CFile to ObjectPtr 2019-09-21 20:50:06 +02:00
Andreas Kling
73fdbba59c AK: Rename <AK/AKString.h> to <AK/String.h>
This was a workaround to be able to build on case-insensitive file
systems where it might get confused about <string.h> vs <String.h>.

Let's just not support building that way, so String.h can have an
objectively nicer name. :^)
2019-09-06 15:36:54 +02:00
Andreas Kling
6693e56603 LibAudio: Allow tweaking how much get_more_samples() reads from file 2019-09-04 20:13:32 +02:00
Andreas Kling
a98de0b6ee LibAudio: Add AClientConnetion::try_enqueue() API
This is a variant of the enqueue() API that returns immediately and
may fail. It's useful when you don't want to block until the audio
server can receive your sample buffer.
2019-09-04 20:12:24 +02:00
Andreas Kling
8e684f0959 AudioServer: Port to the new generated IPC mechanism
Fork the IPC Connection classes into Server:: and Client::ConnectionNG.
The new IPC messages are serialized very snugly instead of using the
same generic data structure for all messages.

Remove ASAPI.h since we now generate all of it from AudioServer.ipc :^)
2019-08-03 19:49:19 +02:00
Andreas Kling
33b0c4cfaf LibAudio: Explicitly ignore IPC postprocessing requests
We don't need to do any IPC postprocessing in LibAudio (yet.)
This is the mechanism used by LibGUI to do repaint coalescing etc.
2019-08-02 19:57:30 +02:00
Andreas Kling
0f3d191a70 LibCore: Rename CFileStreamReader => CIODeviceStreamReader. 2019-07-30 15:16:39 +02:00
Andreas Kling
e6db1b81b8 AudioServer: Begin work on a new IPC API style.
The goal here is to generate most of this code from IPC protocol
descriptions, but for now I've spelled them all out to get started.

Each message gets a wrapper class in the ASAPI_Client or ASAPI_Server
namespace. They are convertible to and from the old message structs.

The real hotness happens when you want to make a synchronous request
to the other side:

    auto response = send_sync<ASAPI_Client::GetMainMixVolume>();

Each request class knows his corresponding response class, so in the
above example, "response" will be an ASAPI_Server::DidGetMainMixVolume
object, and we can get the volume like so:

    int volume = response.volume();

For posting messages that don't expect a response, you can still use
post_message() since the message classes are convertible:

    post_message(ASAPI_Server::DidGetMainMixVolume(volume));

It's not perfect yet, but I already really like it. :^)
2019-07-29 22:39:20 +02:00
Andreas Kling
15afc88ffe AudioServer: Add a "main mix volume" and a simple program to get/set it
Give the mixer a main volume value (percent) that we scale all the
outgoing samples by (before clipping.)

Also add a simple "avol" program for querying and setting the volume:

- "avol" prints the current volume.
- "avol 200" sets the main mix volume to 200%
2019-07-29 19:06:58 +02:00
Andreas Kling
66f8ea92cb LibAudio: Silence some debug spam in the WAV loader. 2019-07-28 21:54:34 +02:00
Andreas Kling
ae4a9e017a LibAudio+aplay: Make the aplay output look a little funner.
Show some information about the file we're playing, and display how many
samples we've played out of how many total.

This might be a bit buggy as I haven't tested it with many different files,
but it's a start. :^)
2019-07-28 21:52:30 +02:00
Andreas Kling
b44d3faa1c LibAudio: WAV: Don't emit the very last sample in each decoded batch.
This is a total hack, because I haven't really looked into why these are
happening. Somehow we're producing one extra sample and it's glitching
up the sound stream ever so slightly.
2019-07-28 21:34:47 +02:00
Andreas Kling
be31e2232c AudioServer+LibAudio: Make mixing queue-based instead of buffer-based.
Each client connection now sets up an ASBufferQueue, which is basically a
queue of ABuffers. This allows us to immediately start streaming the next
pending buffer whenever our current buffer runs out of samples.

This makes the majority of the skippiness go away for me. :^)

Also get rid of the old PlayBuffer API, since we don't need it anymore.
2019-07-28 21:34:47 +02:00
Andreas Kling
7cabe6433e AudioServer: Add a buffer queue so we can buffer some sound.
The idea here is to keep a small number of sample buffers queued in the
AudioServer so we don't get caught without something to play.
2019-07-28 18:27:32 +02:00
Andreas Kling
de3d1f2275 LibAudio: Remove an unnecessary copy of sample buffers before sending them.
I missed this earlier, but *now* we're actually using the same SharedBuffer
all the way from client-side WAV reading to server-side mixing. :^)
2019-07-27 21:28:45 +02:00
Andreas Kling
dbebf10131 LibAudio: Allow WAV files up to 1GB.
We were limiting ourselves to only play WAV files smaller than 42 MB
for no particular reason. This patch increases the limit to 1 GB.
Perhaps there should not be any limit at all, but 1GB seems like a
reasonable sanity check at the moment. :^)
2019-07-27 20:49:15 +02:00
Andreas Kling
68c20e50da LibAudio: WAV reading should stop when we run out of file. :^) 2019-07-27 18:54:03 +02:00
Andreas Kling
5e01dde7b1 Audio: Make ABuffer sit on top of a SharedBuffer.
This allows us to carry the same buffer all the way from the WAV loader
to the AudioServer mixer.

This alleviates some of the stutter, but there's still a noticeable
skip when switching buffers. We're gonna need to do better. :^)
2019-07-27 18:17:17 +02:00
Andreas Kling
426248098c Audio: Make basic streaming WAV playback work.
I had to solve a bunch of things simultaneously to make this work.
Refactor AWavLoader to be a streaming loader rather than a one-shot one.
The constructor parses the header, and if everything looks good, you can
repeatedly ask the AWavLoader for sample buffers until it runs out.

Also send a message from AudioServer when a buffer has finished playing.
That allows us to implement a blocking variant of play().

Use all of this in aplay to play WAV files chunk-at-a-time.
This is definitely not perfect and it's a little glitchy and skippy,
but I think it's a step in the right direction.
2019-07-27 17:27:05 +02:00
Andreas Kling
be1025c03f LibAudio: Use ByteBuffer::slice_view() to avoid double memory usage.
We only need a temporary copy for passing to ABuffer::from_pcm_data().
2019-07-27 15:29:12 +02:00
Andreas Kling
c7a4c8f93b LibAudio: Run clang-format on all of it to make editing easier. 2019-07-27 14:36:32 +02:00
Andreas Kling
c7ea94697e Libraries: Remove unused "install" targets.
We've been using a per-directory "install.sh" for some time, so let's get
rid of the old way of doing things.
2019-07-21 21:28:48 +02:00
Robin Burchell
d19136ce07 AWavLoader: Share code between 24/16/8 bit reading
The only part of this that actually differs between all of them is the
stream -> sample reading, so turn that into a function that the channel
reader can call as it wants.
2019-07-18 13:45:10 +02:00
Robin Burchell
a2fbfb6cef AWavLoader: Support 24 bit wav files (mono & stereo) 2019-07-18 13:45:10 +02:00
Robin Burchell
b907608e46 SharedBuffer: Split the creation and share steps
This allows us to seal a buffer *before* anyone else has access to it
(well, ok, the creating process still does, but you can't win them all).

It also means that a SharedBuffer can be shared with multiple clients:
all you need is to have access to it to share it on again.
2019-07-18 10:06:20 +02:00
Robin Burchell
9c8dd836fc Rename new IPC headers & classes
Sticking these in a namespace allows us to use a more generic
("Connection") term without clashing, which is way easier to understand
than to try to come up with unique names for both.
2019-07-17 20:16:44 +02:00
Robin Burchell
2177594c96 Port LibGUI to use CIPCClientSideConnection
As a consequence, move to use an explicit handshake() method rather than
calling virtuals from the constructor. This seemed to not bother
AClientConnection, but LibGUI crashes (rightfully) because of it.
2019-07-17 20:16:44 +02:00
Robin Burchell
41bece0682 Make AClientConnection generic 2019-07-17 20:16:44 +02:00
Robin Burchell
ac4f8fe350 AClientConnection: Fix double exit 2019-07-17 09:47:52 +02:00
Robin Burchell
fd6cafaa84 ABuffer: clamp -> clip
More natural term when talking about audio :)
2019-07-17 09:47:52 +02:00
Robin Burchell
ed25d524f2 ABuffer: move it and groove it 2019-07-17 09:47:52 +02:00
Robin Burchell
2df6f0e87f Work on AudioServer
The center of this is now an ABuffer class in LibAudio.
ABuffer contains ASample, which has two channels (left/right) in
floating point for mixing purposes, in 44100hz.

This means that the loaders (AWavLoader in this case) needs to do some
manipulation to get things in the right format, but that we don't need
to care after format loading is done.

While we're at it, do some correctness fixes. PCM data is unsigned if
it's 8 bit, but 16 bit is signed. And /dev/audio also wants signed 16
bit audio, so give it what it wants.

On top of this, AudioServer now accepts requests to play a buffer.
The IPC mechanism here is pretty much a 1:1 copy-paste from
LibGUI/WindowServer. It can be generalized more in the future, but for
now I want to get AudioServer working decently first :)

Additionally, add a little "aplay" tool to load and play a WAV file. It
will break with large WAVs (run out of memory, heh...) but it's a start.

Future work needs to make AudioServer block buffer submission from
clients until it has played the buffer they are requesting to play.
2019-07-17 09:39:31 +02:00
Robin Burchell
7b75632e5c AK/LibAudio: Add stream read operators to AK::BufferStream, and use it in AWavLoader
At the same time, we allow chaining of streaming operators, and add a
way to check for partial reads (also used in WAV parsing).
2019-07-14 15:29:59 +02:00
Robin Burchell
ffa8cb668f AudioServer: Assorted infrastructure work
* Add a LibAudio, and move WAV file parsing there (via AWavFile and AWavLoader)
* Add CLocalSocket, and CSocket::connect() variant for local address types.
  We make some small use of this in WindowServer (as that's where we
  modelled it from), but don't get too invasive as this PR is already
  quite large, and the WS I/O is a bit carefully done
* Add an AClientConnection which will eventually be used to talk to
  AudioServer (and make use of it in Piano, though right now it really
  doesn't do anything except connect, using our new CLocalSocket...)
2019-07-13 22:57:24 +02:00