summaryrefslogtreecommitdiff
path: root/Servers
diff options
context:
space:
mode:
authorRobin Burchell <robin+git@viroteck.net>2019-07-13 19:42:03 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-07-13 22:57:24 +0200
commitffa8cb668faffd4c417cc7ff60215d732a088122 (patch)
treeb2b562056ba6bec73b7999335c2e9d9484cb4b2f /Servers
parent983245113afe1961376f5381ea4a77e4364b9d2d (diff)
downloadserenity-ffa8cb668faffd4c417cc7ff60215d732a088122.zip
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...)
Diffstat (limited to 'Servers')
-rw-r--r--Servers/AudioServer/Makefile2
-rw-r--r--Servers/AudioServer/main.cpp208
-rw-r--r--Servers/WindowServer/WSEventLoop.cpp15
-rw-r--r--Servers/WindowServer/WSEventLoop.h5
4 files changed, 75 insertions, 155 deletions
diff --git a/Servers/AudioServer/Makefile b/Servers/AudioServer/Makefile
index 3e36a18acd..74b7b9c22d 100644
--- a/Servers/AudioServer/Makefile
+++ b/Servers/AudioServer/Makefile
@@ -11,7 +11,7 @@ DEFINES += -DUSERLAND
all: $(APP)
$(APP): $(OBJS)
- $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lc -lcore
+ $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lc -lcore -laudio
.cpp.o:
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
diff --git a/Servers/AudioServer/main.cpp b/Servers/AudioServer/main.cpp
index 43cae47a15..915aad33f5 100644
--- a/Servers/AudioServer/main.cpp
+++ b/Servers/AudioServer/main.cpp
@@ -1,171 +1,89 @@
#include <LibCore/CFile.h>
+#include <LibCore/CEventLoop.h>
+#include <LibCore/CLocalSocket.h>
+#include <LibCore/CNotifier.h>
+#include <LibAudio/AWavLoader.h>
+#include <LibAudio/AWavFile.h>
-u32 read_u32(const ByteBuffer& buf, u32& off)
-{
- ASSERT(buf.size() - off >= 4);
- u32 b0 = buf[off + 0];
- u32 b1 = buf[off + 1];
- u32 b2 = buf[off + 2];
- u32 b3 = buf[off + 3];
-
- u32 ret = 0;
- ret |= (u8(b3) << 24);
- ret |= (u8(b2) << 16);
- ret |= (u8(b1) << 8);
- ret |= (u8(b0));
-
- off += 4;
- return ret;
-}
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
-u16 read_u16(const ByteBuffer& buf, u32& off)
+class ASEventLoop
{
- ASSERT(buf.size() - off >= 2);
- u16 b0 = buf[off + 0];
- u16 b1 = buf[off + 1];
+public:
+ ASEventLoop();
+ int exec() { return m_event_loop.exec(); }
+private:
+ CEventLoop m_event_loop;
+ CLocalSocket m_server_sock;
+ OwnPtr<CNotifier> m_server_notifier;
- u16 ret = 0;
- ret |= (u8(b1) << 8);
- ret |= (u8(b0));
+ void drain_server();
+};
- off += 2;
- return ret;
-}
-
-ByteBuffer read_wav_data(const StringView& path)
+void read_and_play_wav()
{
- CFile wav(path);
- if (!wav.open(CIODevice::ReadOnly)) {
- dbgprintf("Can't open wav to dump it to audio: %s", wav.error_string());
- return {};
- }
-
- const auto& contents = wav.read_all();
- u32 off = 0;
-
- if (contents.size() - off < 12) {
- dbgprintf("WAV is too small (no header, %d bytes)\n", contents.size());
- return {};
- }
-
- dbgprintf("Trying to parse %d bytes of wav\n", contents.size());
-
-#define CHECK_OK(msg) \
- do { \
- ASSERT(ok); \
- if (!ok) { \
- dbgprintf("%s failed\n", msg); \
- return {}; \
- } else { \
- dbgprintf("%S is OK!\n", msg); \
- } \
- } while (0);
-
- bool ok = true;
- u32 riff = read_u32(contents, off);
- ok = ok && riff == 0x46464952; // "RIFF"
- CHECK_OK("RIFF header");
-
- u32 sz = read_u32(contents, off);
- ASSERT(sz < 1024 * 1024 * 42);
- ok = ok && sz < 1024 * 1024 * 42; // arbitrary
- CHECK_OK("File size");
-
- u32 wave = read_u32(contents, off);
- ok = ok && wave == 0x45564157; // "WAVE"
- CHECK_OK("WAVE header");
-
- if (contents.size() - off < 8) {
- dbgprintf("WAV is too small (no fmt, %d bytes)\n", contents.size());
- return {};
+ CFile audio("/dev/audio");
+ if (!audio.open(CIODevice::WriteOnly)) {
+ dbgprintf("Can't open audio device: %s\n", audio.error_string());
+ return;
}
- u32 fmt_id = read_u32(contents, off);
- ok = ok && fmt_id == 0x20746D66; // "FMT"
- CHECK_OK("FMT header");
-
- u32 fmt_size = read_u32(contents, off);
- ok = ok && fmt_size == 16;
- ASSERT(fmt_size == 16);
- CHECK_OK("FMT size");
-
- if (contents.size() - off < 16) {
- dbgprintf("WAV is too small (fmt chunk, %d bytes)\n", contents.size());
- return {};
+ AWavLoader loader;
+ const auto& file = loader.load_wav("/home/anon/tmp.wav");
+ if (!file) {
+ dbgprintf("Can't parse WAV: %s\n", loader.error_string());
+ return;
}
- u16 audio_format = read_u16(contents, off);
- ok = ok && audio_format == 1; // WAVE_FORMAT_PCM
- ASSERT(audio_format == 1);
- CHECK_OK("Audio format");
-
- u16 num_channels = read_u16(contents, off);
- ok = ok && num_channels == 1;
- ASSERT(num_channels == 1);
- CHECK_OK("Channel count");
-
- u32 sample_rate = read_u32(contents, off);
- CHECK_OK("Sample rate");
-
- off += 4; // bytes per sec: we don't care.
- off += 2; // block align: we don't care.
+ dbgprintf("Read WAV of format %d with num_channels %d sample rate %d, bits per sample %d\n", (u8)file->format(), file->channel_count(), file->sample_rate_per_second(), file->bits_per_sample());
- u16 bits_per_sample = read_u16(contents, off);
- ok = ok && (bits_per_sample == 8 || bits_per_sample == 16);
- ASSERT(bits_per_sample == 8 || bits_per_sample == 16);
- CHECK_OK("Bits per sample");
-
- dbgprintf("Read WAV of format %d with num_channels %d sample rate %d, bits per sample %d\n", audio_format, num_channels, sample_rate, bits_per_sample);
-
- // Read chunks until we find DATA
- if (off >= u32(contents.size()) - 8) {
- ok = ok && false;
- ASSERT_NOT_REACHED();
- CHECK_OK("Premature EOF without DATA");
+ auto contents = file->sample_data();
+ const int chunk_size = 4096;
+ int i = 0;
+ while (i < contents.size()) {
+ const auto chunk = contents.slice(i, chunk_size);
+ audio.write(chunk);
+ i += chunk_size;
}
+}
- bool found_data = false;
- u32 data_sz = 0;
- while (off < u32(contents.size()) - 8) {
- u32 chunk_id = read_u32(contents, off);
- data_sz = read_u32(contents, off);
- if (chunk_id == 0x61746164) { // DATA
- found_data = true;
- break;
- }
- off += data_sz;
- }
+ASEventLoop::ASEventLoop()
+{
+ read_and_play_wav();
- ok = ok && found_data;
- ASSERT(found_data);
- CHECK_OK("Found no data chunk");
+ unlink("/tmp/asportal");
- ok = ok && data_sz <= (contents.size() - off);
- CHECK_OK("Bad DATA size");
+ sockaddr_un address;
+ address.sun_family = AF_LOCAL;
+ strcpy(address.sun_path, "/tmp/asportal");
+ int rc = bind(m_server_sock.fd(), (const sockaddr*)&address, sizeof(address));
+ ASSERT(rc == 0);
+ rc = listen(m_server_sock.fd(), 5);
+ ASSERT(rc == 0);
- return contents.slice(off, data_sz);
+ m_server_notifier = make<CNotifier>(m_server_sock.fd(), CNotifier::Read);
+ m_server_notifier->on_ready_to_read = [this] { drain_server(); };
}
-void read_and_play_wav()
+void ASEventLoop::drain_server()
{
- CFile audio("/dev/audio");
- if (!audio.open(CIODevice::WriteOnly)) {
- dbgprintf("Can't open audio device: %s", audio.error_string());
- return;
- }
-
- const auto& contents = read_wav_data("/home/anon/tmp.wav");
- const int chunk_size = 4096;
- int i = 0;
- while (i < contents.size()) {
- const auto chunk = contents.slice(i, chunk_size);
- audio.write(chunk);
- i += chunk_size;
+ sockaddr_un address;
+ socklen_t address_size = sizeof(address);
+ int client_fd = accept(m_server_sock.fd(), (sockaddr*)&address, &address_size);
+ if (client_fd < 0) {
+ dbgprintf("WindowServer: accept() failed: %s\n", strerror(errno));
+ } else {
+ dbgprintf("AudioServer: accept()ed client %d\n", client_fd);
+ String s("hello, client!\n");
+ write(client_fd, s.characters(), s.length());
+ close(client_fd);
}
}
int main(int, char**)
{
- read_and_play_wav();
- return 0;
+ ASEventLoop event_loop;
+ return event_loop.exec();
}
diff --git a/Servers/WindowServer/WSEventLoop.cpp b/Servers/WindowServer/WSEventLoop.cpp
index 781695af91..58819829ac 100644
--- a/Servers/WindowServer/WSEventLoop.cpp
+++ b/Servers/WindowServer/WSEventLoop.cpp
@@ -26,18 +26,20 @@ WSEventLoop::WSEventLoop()
unlink("/tmp/wsportal");
- m_server_fd = socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
- ASSERT(m_server_fd >= 0);
sockaddr_un address;
address.sun_family = AF_LOCAL;
strcpy(address.sun_path, "/tmp/wsportal");
- int rc = bind(m_server_fd, (const sockaddr*)&address, sizeof(address));
+ int rc = bind(m_server_sock.fd(), (const sockaddr*)&address, sizeof(address));
ASSERT(rc == 0);
- rc = listen(m_server_fd, 5);
+ rc = listen(m_server_sock.fd(), 5);
ASSERT(rc == 0);
+ ASSERT(m_server_sock.fd() >= 0);
ASSERT(m_keyboard_fd >= 0);
ASSERT(m_mouse_fd >= 0);
+
+ m_server_notifier = make<CNotifier>(m_server_sock.fd(), CNotifier::Read);
+ m_server_notifier->on_ready_to_read = [this] { drain_server(); };
}
WSEventLoop::~WSEventLoop()
@@ -48,7 +50,7 @@ void WSEventLoop::drain_server()
{
sockaddr_un address;
socklen_t address_size = sizeof(address);
- int client_fd = accept(m_server_fd, (sockaddr*)&address, &address_size);
+ int client_fd = accept(m_server_sock.fd(), (sockaddr*)&address, &address_size);
if (client_fd < 0) {
dbgprintf("WindowServer: accept() failed: %s\n", strerror(errno));
} else {
@@ -333,7 +335,6 @@ void WSEventLoop::add_file_descriptors_for_select(fd_set& fds, int& max_fd_added
};
add_fd_to_set(m_keyboard_fd, fds);
add_fd_to_set(m_mouse_fd, fds);
- add_fd_to_set(m_server_fd, fds);
WSClientConnection::for_each_client([&](WSClientConnection& client) {
add_fd_to_set(client.fd(), fds);
});
@@ -341,8 +342,6 @@ void WSEventLoop::add_file_descriptors_for_select(fd_set& fds, int& max_fd_added
void WSEventLoop::process_file_descriptors_after_select(const fd_set& fds)
{
- if (FD_ISSET(m_server_fd, &fds))
- drain_server();
if (FD_ISSET(m_keyboard_fd, &fds))
drain_keyboard();
if (FD_ISSET(m_mouse_fd, &fds))
diff --git a/Servers/WindowServer/WSEventLoop.h b/Servers/WindowServer/WSEventLoop.h
index 8c76a17efb..8935dd0264 100644
--- a/Servers/WindowServer/WSEventLoop.h
+++ b/Servers/WindowServer/WSEventLoop.h
@@ -2,6 +2,8 @@
#include <AK/ByteBuffer.h>
#include <LibCore/CEventLoop.h>
+#include <LibCore/CNotifier.h>
+#include <LibCore/CLocalSocket.h>
class WSClientConnection;
struct WSAPI_ClientMessage;
@@ -25,5 +27,6 @@ private:
int m_keyboard_fd { -1 };
int m_mouse_fd { -1 };
- int m_server_fd { -1 };
+ CLocalSocket m_server_sock;
+ OwnPtr<CNotifier> m_server_notifier;
};