Skip to content

Commit

Permalink
Fixed bug 5080 - SDL_netbsdaudio: Always use the device's preferred f…
Browse files Browse the repository at this point in the history
…requency

Nia Alarie

The NetBSD kernel's audio resampling code is much simpler and lower quality than libsamplerate.

Presumably, if SDL always performs I/O on the audio device in its native frequency, we can avoid resampling audio in the kernel and let SDL do it with libsamplerate instead.
  • Loading branch information
slouken committed Jan 8, 2021
1 parent 2f72535 commit 50ea3b7
Showing 1 changed file with 19 additions and 10 deletions.
29 changes: 19 additions & 10 deletions src/audio/netbsd/SDL_netbsdaudio.c
Expand Up @@ -205,7 +205,7 @@ static int
NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
SDL_AudioFormat format = 0;
audio_info_t info;
audio_info_t info, hwinfo;
struct audio_prinfo *prinfo = iscapture ? &info.record : &info.play;

/* We don't care what the devname is...we'll try to open anything. */
Expand Down Expand Up @@ -233,7 +233,20 @@ NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)

AUDIO_INITINFO(&info);

#ifdef AUDIO_GETFORMAT /* Introduced in NetBSD 9.0 */
if (ioctl(this->hidden->audio_fd, AUDIO_GETFORMAT, &hwinfo) != -1) {
/*
* Use the device's native sample rate so the kernel doesn't have to
* resample.
*/
this->spec.freq = iscapture ?
hwinfo.record.sample_rate : hwinfo.play.sample_rate;
}
#endif

prinfo->encoding = AUDIO_ENCODING_NONE;
prinfo->sample_rate = this->spec.freq;
prinfo->channels = this->spec.channels;

for (format = SDL_FirstAudioFormat(this->spec.format); format;) {
switch (format) {
Expand Down Expand Up @@ -280,23 +293,19 @@ NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
return SDL_SetError("No supported encoding for 0x%x", this->spec.format);
}

this->spec.format = format;

/* Calculate spec parameters based on our chosen format */
SDL_CalculateAudioSpec(&this->spec);

info.mode = iscapture ? AUMODE_RECORD : AUMODE_PLAY;
info.blocksize = this->spec.size;
info.hiwat = 5;
info.lowat = 3;
prinfo->sample_rate = this->spec.freq;
prinfo->channels = this->spec.channels;
(void) ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info);

(void) ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info);

/* Final spec used for the device. */
this->spec.format = format;
this->spec.freq = prinfo->sample_rate;
this->spec.channels = prinfo->channels;

SDL_CalculateAudioSpec(&this->spec);

if (!iscapture) {
/* Allocate mixing buffer */
this->hidden->mixlen = this->spec.size;
Expand Down

0 comments on commit 50ea3b7

Please sign in to comment.