ref: 027f579f43cdc908bf8d51c27bdf5da8e7773940
parent: 571d3258ef7e0db436c2ad4dbd79244e6d319e8f
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Mar 27 19:47:45 EDT 2024
nusb/audio: pick a different rate if 44.1kHz is not available Try to pick the closest (but higher) rate. If there are none, pick a lower one. Mixfs is able to convert to whichever rate, so this should make plenty of new audio devices work.
--- a/sys/src/cmd/nusb/audio/audio.c
+++ b/sys/src/cmd/nusb/audio/audio.c
@@ -360,12 +360,19 @@
}
Dev*
-setupep(Dev *d, Iface *ac, Ep *e, int speed)
+setupep(Dev *d, Iface *ac, Ep *e, int *speed, int force)
{
int dir = e->dir;
- Aconf *c;
+ Aconf *c, *bestc;
Range *f;
+ Ep *beste;
+ int closest, sp;
+ bestc = nil;
+ beste = nil;
+ closest = 1<<30;
+ sp = *speed;
+
for(;e != nil; e = e->next){
c = e->iface->aux;
if(c == nil || e != c->ep || e->dir != dir)
@@ -372,21 +379,39 @@
continue;
if(c->format != 1 || c->bits != audiores || 8*c->bps != audiores || c->channels != audiochan)
continue;
- for(f = c->freq; f != c->freq+c->nfreq; f++)
- if(speed >= f->min && speed <= f->max)
+ for(f = c->freq; f != c->freq+c->nfreq; f++){
+ if(sp >= f->min && sp <= f->max)
goto Foundaltc;
+ if(force)
+ continue;
+ if(f->min >= sp && closest-sp >= f->min-sp){
+ closest = f->min;
+ bestc = c;
+ beste = e;
+ }else if(bestc == nil || (f->max < sp && closest < sp && sp-closest > sp-f->max)){
+ closest = f->max;
+ bestc = c;
+ beste = e;
+ }
+ }
}
- werrstr("no altc found");
- return nil;
+ if(bestc == nil){
+ werrstr("no altc found");
+ return nil;
+ }
+ e = beste;
+ c = bestc;
+ sp = closest;
Foundaltc:
- if(setalt(d, e->iface) < 0)
+ if(setalt(d, e->iface) < 0){
+ fprint(2, "setalt: %r\n");
return nil;
- if(setclock(d, ac, c, speed) < 0){
+ }
+ if(setclock(d, ac, c, sp) < 0){
werrstr("setclock: %r");
return nil;
}
-
if((d = openep(d, e)) == nil){
werrstr("openep: %r");
return nil;
@@ -393,11 +418,9 @@
}
devctl(d, "samplesz %d", audiochan*audiores/8);
devctl(d, "sampledelay %d", audiodelay);
- devctl(d, "hz %d", speed);
- if(e->dir==Ein)
- devctl(d, "name audioinU%s", audiodev->hname);
- else
- devctl(d, "name audioU%s", audiodev->hname);
+ devctl(d, "hz %d", sp);
+ devctl(d, "name audio%sU%s", e->dir==Ein ? "in" : "", audiodev->hname);
+ *speed = sp;
return d;
}
@@ -430,15 +453,15 @@
speed = atoi(f[1]);
Setup:
- if((d = setupep(audiodev, audiocontrol, audioepout, speed)) == nil){
+ if((d = setupep(audiodev, audiocontrol, audioepout, &speed, 1)) == nil){
responderror(r);
return;
}
+ audiofreq = speed;
closedev(d);
if(audioepin != nil)
- if(d = setupep(audiodev, audiocontrol, audioepin, speed))
+ if(d = setupep(audiodev, audiocontrol, audioepin, &speed, 1))
closedev(d);
- audiofreq = speed;
} else if(strcmp(f[0], "delay") == 0){
audiodelay = atoi(f[1]);
speed = audiofreq;
@@ -534,7 +557,7 @@
audioepout = e;
break;
}
- if((ed = setupep(d, ac, e, audiofreq)) == nil){
+ if((ed = setupep(d, ac, e, &audiofreq, 0)) == nil){
fprint(2, "setupep: %r\n");
if(e == audioepin)