ref: 571d3258ef7e0db436c2ad4dbd79244e6d319e8f
parent: 2d1f4327f1f81cfdc57c491f3f3bdc2a325dfe60
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Mar 27 19:44:25 EDT 2024
audio/mixfs: convert pcm for devices that are not 44.1kHz
--- a/sys/src/cmd/audio/mixfs/mixfs.c
+++ b/sys/src/cmd/audio/mixfs/mixfs.c
@@ -3,6 +3,7 @@
#include <fcall.h>
#include <thread.h>
#include <9p.h>
+#include <pcm.h>
enum {
NBUF = 8*1024,
@@ -9,7 +10,7 @@
NDELAY = 512, /* ~11.6ms */
NQUANTA = 64, /* ~1.45ms */
NCHAN = 2,
- FREQ = 44100,
+ ABUF = NBUF*NCHAN*2,
};
#define MIN(a,b) ((a)<(b)?(a):(b))
@@ -44,6 +45,7 @@
int volume[2] = {100, 100};
int vol64k[2] = {65536, 65536};
+int newrate;
int
s16(uchar *p)
@@ -76,6 +78,23 @@
qunlock(&devlock);
}
+void
+updrate(void)
+{
+ static char svol[4*1024];
+ int n, rate;
+ char *s;
+
+ rate = pcmdescdef.rate;
+ if(volfd >= 0 && (n = pread(volfd, svol+1, sizeof(svol)-2, 0)) > 8){
+ svol[0] = '\n';
+ svol[1+n] = 0;
+ if((s = strstr(svol, "\nspeed ")) != nil && (n = strtol(s+6, &s, 10)) > 0)
+ rate = n;
+ }
+ newrate = rate;
+}
+
int
reopendevs(char *name)
{
@@ -145,6 +164,7 @@
name = smprint("%.*svolume%s", (int)(p - name), name, p+5);
volfd = open(name, ORDWR);
free(name);
+ updrate();
}
return 0;
}
@@ -205,15 +225,20 @@
void
audioproc(void *)
{
- static uchar buf[NBUF*NCHAN*2];
+ static uchar buf[ABUF];
+ static Pcmdesc desc;
int sweep, i, j, n, m, v;
ulong rp;
Stream *s;
- uchar *p;
+ uchar *p, *bufconv;
+ Pcmconv *conv;
threadsetname("audioproc");
-
+ desc = pcmdescdef;
+ conv = nil;
+ bufconv = nil;
sweep = 0;
+
for(;;){
m = NBUF;
for(s = streams; s < streams+nelem(streams); s++){
@@ -244,13 +269,13 @@
ms = 100;
if(audiofd >= 0){
- if(sweep)
+ if(sweep){
closeaudiodev();
- else {
+ } else {
/* attempt to sleep just shortly before buffer underrun */
ms = seek(audiofd, 0, 2);
ms *= 800;
- ms /= FREQ*NCHAN*2;
+ ms /= desc.rate*NCHAN*2;
}
sweep = 1;
}
@@ -285,8 +310,27 @@
mixrp = rp;
unlock(&rplock);
+ if(desc.rate != newrate){
+ desc.rate = newrate;
+ free(bufconv);
+ bufconv = nil;
+ freepcmconv(conv);
+ if((conv = allocpcmconv(&pcmdescdef, &desc)) == nil ||
+ (n = pcmratio(conv, ABUF)) < 0 ||
+ (bufconv = malloc(n)) == nil){
+ fprint(2, "%s: %r\n", devaudio);
+ freepcmconv(conv);
+ conv = nil;
+ }
+ }
+
n = p - buf;
- if(write(audiofd, buf, n) != n)
+ p = buf;
+ if(conv != nil){
+ n = pcmconv(conv, buf, bufconv, n);
+ p = bufconv;
+ }
+ if(write(audiofd, p, n) != n)
closeaudiodev();
}
}
@@ -530,6 +574,7 @@
if(argc > 1)
usage();
+ newrate = pcmdescdef.rate;
reopendevs(argv[0]);
closeaudiodev();