ref: 623f5427f2e5d9cbc7540e8e2a72981c973e4cac
parent: 3265f44938f2d6d8e954feac427aaf48a7c31b42
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Thu Mar 18 06:08:47 EDT 2021
sdl2: take audio logic into a separate file
--- /dev/null
+++ b/libnpe_sdl2/audio.c
@@ -1,0 +1,153 @@
+#include <SDL2/SDL.h>
+
+enum {
+ Aout = 2,
+ Arec,
+
+ Audiobufsz = 8192,
+};
+
+typedef struct Audiodev Audiodev;
+
+struct Audiodev {
+ QLock;
+ void (*cb)(void *, Uint8 *, int);
+ void *userdata;
+ char *name;
+ Channel *wait;
+ int paused;
+ int fd;
+ int pid;
+ int mode;
+ Uint8 buf[Audiobufsz];
+};
+
+/* FIXME extra USB audio devices? */
+static Audiodev au[4] = {
+ [0] = {.fd = -1, .mode = -1},
+ [1] = {.fd = -1, .mode = -1},
+ [Aout] = {.name = "/dev/audio", .fd = -1, .pid = -1, .mode = OWRITE},
+ [Arec] = {.name = "/dev/audio", .fd = -1, .pid = -1, .mode = OREAD},
+};
+
+int
+SDL_GetNumAudioDevices(int iscapture)
+{
+ /* FIXME look for extra USB devices? */
+ USED(iscapture);
+ return 1;
+}
+
+char *
+SDL_GetAudioDeviceName(int index, int iscapture)
+{
+ /* FIXME look for extra USB devices? */
+ USED(index);
+ return au[iscapture ? Arec : Aout].name;
+}
+
+void
+SDL_LockAudioDevice(SDL_AudioDeviceID id)
+{
+ qlock(&au[id]);
+}
+
+void
+SDL_UnlockAudioDevice(SDL_AudioDeviceID id)
+{
+ qunlock(&au[id]);
+}
+
+static void
+audiothread(void *p)
+{
+ Audiodev *a;
+
+ a = p;
+ threadsetname("%s (%s)", a->name, a->mode == OREAD ? "out" : "in");
+
+ for(;;){
+ qlock(a);
+ if(a->paused)
+ memset(a->buf, 0, sizeof(a->buf));
+ else
+ a->cb(a->userdata, a->buf, sizeof(a->buf));
+ qunlock(a);
+
+ if(write(a->fd, a->buf, sizeof(a->buf)) != sizeof(a->buf))
+ break;
+ }
+
+ sendul(a->wait, 0);
+
+ threadexits(nil);
+}
+
+void
+SDL_PauseAudioDevice(SDL_AudioDeviceID id, SDL_bool pause)
+{
+ Audiodev *a;
+
+ a = &au[id];
+ if(a->paused && !pause){
+ if(a->pid < 0)
+ a->pid = proccreate(audiothread, a, mainstacksize);
+ a->paused = 0;
+ }else if(!a->paused && pause){
+ a->paused = 1;
+ }
+}
+
+SDL_AudioDeviceID
+SDL_OpenAudioDevice(char *dev, int rec, SDL_AudioSpec *want, SDL_AudioSpec *have, u32int change)
+{
+ Audiodev *a;
+ SDL_AudioDeviceID id;
+
+ /* FIXME look for extra USB devices? */
+ USED(dev);
+
+ if(change != SDL_AUDIO_ALLOW_ANY_CHANGE){ /* FIXME sampling in mono */
+ werrstr("SDL_OpenAudioDevice: changes not implemented");
+ return 0;
+ }
+
+ have->freq = 44100;
+ have->format = AUDIO_S16;
+ have->channels = 2;
+ have->samples = want->samples;
+
+ id = rec ? Arec : Aout;
+ a = &au[id];
+
+ if(a->fd < 0 && (a->fd = open("/dev/audio", a->mode|OCEXEC)) < 0){
+ werrstr("SDL_OpenAudioDevice: %r");
+ return 0;
+ }
+
+ a->userdata = want->userdata;
+ a->cb = want->callback;
+ a->paused = 1;
+ a->wait = chancreate(sizeof(ulong), 0);
+
+ return id;
+}
+
+void
+SDL_CloseAudioDevice(SDL_AudioDeviceID id)
+{
+ Audiodev *a;
+
+ a = &au[id];
+
+ qlock(a);
+ close(a->fd);
+ a->fd = -1;
+ a->pid = -1;
+ a->userdata = nil;
+ a->cb = nil;
+ qunlock(a);
+
+ recvul(a->wait);
+ chanfree(a->wait);
+}
--- a/libnpe_sdl2/mkfile
+++ b/libnpe_sdl2/mkfile
@@ -6,6 +6,7 @@
HFILES=\
OFILES=\
+ audio.$O\
sdl2.$O\
UPDATE=\
--- a/libnpe_sdl2/sdl2.c
+++ b/libnpe_sdl2/sdl2.c
@@ -10,12 +10,7 @@
#include <sys/stat.h>
#include "_npe.h"
-typedef struct Audiodev Audiodev;
-
enum {
- Aout = 2,
- Arec,
-
/* FIXME missing plumber→dropfile */
Ckey = 0,
Ckeytype,
@@ -26,8 +21,6 @@
Rdown = 0,
Rup,
Rrepeat,
-
- Audiobufsz = 16384,
};
struct SDL_Window {
@@ -63,25 +56,6 @@
.format = SDL_PIXELFORMAT_ARGB8888,
};
-struct Audiodev {
- QLock;
- int paused;
- int fd;
- int pid;
- int mode;
- Uint8 buf[Audiobufsz];
- void *userdata;
- void (*cb)(void *, Uint8 *, int);
-};
-
-/* FIXME extra USB audio devices? */
-static Audiodev au[4] = {
- [0] = {.fd = -1, .mode = -1},
- [1] = {.fd = -1, .mode = -1},
- [Aout] = {.fd = -1, .pid = -1, .mode = OWRITE},
- [Arec] = {.fd = -1, .pid = -1, .mode = OREAD},
-};
-
static SDL_Window onewin;
static SDL_Renderer oneren;
static int kmod;
@@ -275,121 +249,6 @@
setcursor(mctl, (cursor == nil && showcursor) ? nil : &nocursor);
return showcursor;
-}
-
-int
-SDL_GetNumAudioDevices(int iscapture)
-{
- /* FIXME look for extra USB devices? */
- USED(iscapture);
- return 1;
-}
-
-char *
-SDL_GetAudioDeviceName(int index, int iscapture)
-{
- /* FIXME look for extra USB devices? */
- USED(index); USED(iscapture);
- return "/dev/audio";
-}
-
-void
-SDL_LockAudioDevice(SDL_AudioDeviceID id)
-{
- qlock(&au[id]);
-}
-
-void
-SDL_UnlockAudioDevice(SDL_AudioDeviceID id)
-{
- qunlock(&au[id]);
-}
-
-static void
-audiothread(void *p)
-{
- Audiodev *d;
-
- d = p;
- threadsetname("audio %s", d == &au[Aout] ? "out" : "in");
-
- for(;;){
- qlock(d);
- if(d->paused)
- memset(d->buf, 0, sizeof(d->buf));
- else
- d->cb(d->userdata, d->buf, sizeof(d->buf));
- qunlock(d);
-
- if(write(d->fd, d->buf, sizeof(d->buf)) != sizeof(d->buf))
- break;
- }
-
- threadexits(nil);
-}
-
-void
-SDL_PauseAudioDevice(SDL_AudioDeviceID id, SDL_bool pause)
-{
- Audiodev *a;
-
- a = &au[id];
- if(a->paused && !pause){
- if(a->pid < 0)
- a->pid = proccreate(audiothread, a, mainstacksize);
- a->paused = 0;
- }else if(!a->paused && pause){
- a->paused = 1;
- }
-}
-
-SDL_AudioDeviceID
-SDL_OpenAudioDevice(char *dev, int rec, SDL_AudioSpec *want, SDL_AudioSpec *have, u32int change)
-{
- Audiodev *a;
- SDL_AudioDeviceID id;
-
- /* FIXME look for extra USB devices? */
- USED(dev);
-
- if(change != SDL_AUDIO_ALLOW_ANY_CHANGE){ /* FIXME sampling in mono */
- werrstr("SDL_OpenAudioDevice: changes not implemented");
- return 0;
- }
-
- have->freq = 44100;
- have->format = AUDIO_S16;
- have->channels = 2;
- have->samples = want->samples;
-
- id = rec ? Arec : Aout;
- a = &au[id];
-
- if(a->fd < 0 && (a->fd = open("/dev/audio", a->mode|OCEXEC)) < 0){
- werrstr("SDL_OpenAudioDevice: %r");
- return 0;
- }
-
- a->userdata = want->userdata;
- a->cb = want->callback;
- a->paused = 1;
-
- return id;
-}
-
-void
-SDL_CloseAudioDevice(SDL_AudioDeviceID id)
-{
- Audiodev *a;
-
- a = &au[id];
- qlock(a);
- close(a->fd);
- a->fd = -1;
- a->pid = -1;
- a->userdata = nil;
- a->cb = nil;
- qunlock(a);
}
u64int