summaryrefslogtreecommitdiff
path: root/www/seamonkey/files
diff options
context:
space:
mode:
authornia <nia@pkgsrc.org>2020-05-07 19:36:52 +0000
committernia <nia@pkgsrc.org>2020-05-07 19:36:52 +0000
commitab52bf2440d922d4d7fdb12c92e59ce0b53721dd (patch)
tree41052a8f59b1ec7971909ef21d96b70e5fbbe5e2 /www/seamonkey/files
parent8ecadc33b106a495d534bebcb0fec85e7a5a9d0d (diff)
downloadpkgsrc-ab52bf2440d922d4d7fdb12c92e59ce0b53721dd.tar.gz
seamonkey: Restore lost sun audio patches.
Diffstat (limited to 'www/seamonkey/files')
-rw-r--r--www/seamonkey/files/cubeb_sun.c280
1 files changed, 123 insertions, 157 deletions
diff --git a/www/seamonkey/files/cubeb_sun.c b/www/seamonkey/files/cubeb_sun.c
index 8c845e3d682..34b464f84e2 100644
--- a/www/seamonkey/files/cubeb_sun.c
+++ b/www/seamonkey/files/cubeb_sun.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2019 Nia Alarie
+ * Copyright © 2019-2020 Nia Alarie <nia@NetBSD.org>
*
* This program is made available under an ISC-style license. See the
* accompanying file LICENSE for details.
@@ -9,21 +9,14 @@
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <math.h>
+#include <limits.h>
#include "cubeb/cubeb.h"
#include "cubeb-internal.h"
-#define CUBEB_OLD_API /* seamonkey and older firefox */
-
-#define BYTES_TO_FRAMES(bytes, channels) \
- (bytes / (channels * sizeof(int16_t)))
-
-#define FRAMES_TO_BYTES(frames, channels) \
- (frames * (channels * sizeof(int16_t)))
-
/* Default to 4 + 1 for the default device. */
#ifndef SUN_DEVICE_COUNT
#define SUN_DEVICE_COUNT (5)
@@ -43,10 +36,6 @@
#define SUN_DEFAULT_DEVICE "/dev/audio"
#endif
-#ifndef SUN_POLL_TIMEOUT
-#define SUN_POLL_TIMEOUT (1000)
-#endif
-
#ifndef SUN_BUFFER_FRAMES
#define SUN_BUFFER_FRAMES (32)
#endif
@@ -77,26 +66,26 @@ struct cubeb {
struct cubeb_ops const * ops;
};
+struct sun_stream {
+ char name[32];
+ int fd;
+ void * buf;
+ struct audio_info info;
+ unsigned frame_size; /* precision in bytes * channels */
+ bool floating;
+};
+
struct cubeb_stream {
struct cubeb * context;
void * user_ptr;
pthread_t thread;
pthread_mutex_t mutex; /* protects running, volume, frames_written */
- int floating;
- int running;
- int play_fd;
- int record_fd;
+ bool running;
float volume;
- struct audio_info p_info; /* info for the play fd */
- struct audio_info r_info; /* info for the record fd */
+ struct sun_stream play;
+ struct sun_stream record;
cubeb_data_callback data_cb;
cubeb_state_callback state_cb;
- int16_t * play_buf;
- int16_t * record_buf;
- float * f_play_buf;
- float * f_record_buf;
- char input_name[32];
- char output_name[32];
uint64_t frames_written;
uint64_t blocks_written;
};
@@ -197,7 +186,6 @@ sun_prinfo_verify_sanity(struct audio_prinfo * prinfo)
prinfo->sample_rate < SUN_MAX_RATE && prinfo->sample_rate > SUN_MIN_RATE;
}
-#ifndef CUBEB_OLD_API
static int
sun_enumerate_devices(cubeb * context, cubeb_device_type type,
cubeb_device_collection * collection)
@@ -292,9 +280,7 @@ sun_enumerate_devices(cubeb * context, cubeb_device_type type,
}
return CUBEB_OK;
}
-#endif
-#ifndef CUBEB_OLD_API
static int
sun_device_collection_destroy(cubeb * context,
cubeb_device_collection * collection)
@@ -310,7 +296,6 @@ sun_device_collection_destroy(cubeb * context,
free(collection->device);
return CUBEB_OK;
}
-#endif
static int
sun_copy_params(int fd, cubeb_stream * stream, cubeb_stream_params * params,
@@ -318,18 +303,19 @@ sun_copy_params(int fd, cubeb_stream * stream, cubeb_stream_params * params,
{
prinfo->channels = params->channels;
prinfo->sample_rate = params->rate;
- prinfo->precision = 16;
#ifdef AUDIO_ENCODING_SLINEAR_LE
switch (params->format) {
case CUBEB_SAMPLE_S16LE:
prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE;
+ prinfo->precision = 16;
break;
case CUBEB_SAMPLE_S16BE:
prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE;
+ prinfo->precision = 16;
break;
case CUBEB_SAMPLE_FLOAT32NE:
- stream->floating = 1;
prinfo->encoding = AUDIO_ENCODING_SLINEAR;
+ prinfo->precision = 32;
break;
default:
LOG("Unsupported format");
@@ -339,10 +325,11 @@ sun_copy_params(int fd, cubeb_stream * stream, cubeb_stream_params * params,
switch (params->format) {
case CUBEB_SAMPLE_S16NE:
prinfo->encoding = AUDIO_ENCODING_LINEAR;
+ prinfo->precision = 16;
break;
case CUBEB_SAMPLE_FLOAT32NE:
- stream->floating = 1;
prinfo->encoding = AUDIO_ENCODING_LINEAR;
+ prinfo->precision = 32;
break;
default:
LOG("Unsupported format");
@@ -363,7 +350,7 @@ sun_stream_stop(cubeb_stream * s)
{
pthread_mutex_lock(&s->mutex);
if (s->running) {
- s->running = 0;
+ s->running = false;
pthread_mutex_unlock(&s->mutex);
pthread_join(s->thread, NULL);
} else {
@@ -377,53 +364,50 @@ sun_stream_destroy(cubeb_stream * s)
{
pthread_mutex_destroy(&s->mutex);
sun_stream_stop(s);
- if (s->play_fd != -1) {
- close(s->play_fd);
+ if (s->play.fd != -1) {
+ close(s->play.fd);
}
- if (s->record_fd != -1) {
- close(s->record_fd);
+ if (s->record.fd != -1) {
+ close(s->record.fd);
}
- free(s->f_play_buf);
- free(s->f_record_buf);
- free(s->play_buf);
- free(s->record_buf);
+ free(s->play.buf);
+ free(s->record.buf);
free(s);
}
static void
-sun_float_to_linear(float * in, int16_t * out,
- unsigned channels, long frames, float vol)
+sun_float_to_linear32(void * buf, unsigned sample_count, float vol)
{
- unsigned i, sample_count = frames * channels;
- float multiplier = vol * 0x8000;
-
- for (i = 0; i < sample_count; ++i) {
- int32_t sample = lrintf(in[i] * multiplier);
- if (sample < -0x8000) {
- out[i] = -0x8000;
- } else if (sample > 0x7fff) {
- out[i] = 0x7fff;
- } else {
- out[i] = sample;
- }
+ float * in = buf;
+ int32_t * out = buf;
+ int32_t * tail = out + sample_count;
+
+ while (out < tail) {
+ float f = *(in++) * vol;
+ if (f < -1.0)
+ f = -1.0;
+ else if (f > 1.0)
+ f = 1.0;
+ *(out++) = f * (float)INT32_MAX;
}
}
static void
-sun_linear_to_float(int16_t * in, float * out,
- unsigned channels, long frames)
+sun_linear32_to_float(void * buf, unsigned sample_count)
{
- unsigned i, sample_count = frames * channels;
+ int32_t * in = buf;
+ float * out = buf;
+ float * tail = out + sample_count;
- for (i = 0; i < sample_count; ++i) {
- out[i] = (1.0 / 0x8000) * in[i];
+ while (out < tail) {
+ *(out++) = (1.0 / 0x80000000) * *(in++);
}
}
static void
-sun_linear_set_vol(int16_t * buf, unsigned channels, long frames, float vol)
+sun_linear16_set_vol(int16_t * buf, unsigned sample_count, float vol)
{
- unsigned i, sample_count = frames * channels;
+ unsigned i;
int32_t multiplier = vol * 0x8000;
for (i = 0; i < sample_count; ++i) {
@@ -451,41 +435,36 @@ sun_io_routine(void * arg)
break;
}
pthread_mutex_unlock(&s->mutex);
- if (s->floating) {
- if (s->record_fd != -1) {
- sun_linear_to_float(s->record_buf, s->f_record_buf,
- s->r_info.record.channels, SUN_BUFFER_FRAMES);
- }
- to_write = s->data_cb(s, s->user_ptr,
- s->f_record_buf, s->f_play_buf, SUN_BUFFER_FRAMES);
- if (to_write == CUBEB_ERROR) {
- state = CUBEB_STATE_ERROR;
- break;
- }
- if (s->play_fd != -1) {
- pthread_mutex_lock(&s->mutex);
- sun_float_to_linear(s->f_play_buf, s->play_buf,
- s->p_info.play.channels, to_write, s->volume);
- pthread_mutex_unlock(&s->mutex);
- }
- } else {
- to_write = s->data_cb(s, s->user_ptr,
- s->record_buf, s->play_buf, SUN_BUFFER_FRAMES);
- if (to_write == CUBEB_ERROR) {
- state = CUBEB_STATE_ERROR;
- break;
- }
- if (s->play_fd != -1) {
- pthread_mutex_lock(&s->mutex);
- sun_linear_set_vol(s->play_buf, s->p_info.play.channels, to_write, s->volume);
- pthread_mutex_unlock(&s->mutex);
+ if (s->record.fd != -1 && s->record.floating) {
+ sun_linear32_to_float(s->record.buf,
+ s->record.info.record.channels * SUN_BUFFER_FRAMES);
+ }
+ to_write = s->data_cb(s, s->user_ptr,
+ s->record.buf, s->play.buf, SUN_BUFFER_FRAMES);
+ if (to_write == CUBEB_ERROR) {
+ state = CUBEB_STATE_ERROR;
+ break;
+ }
+ if (s->play.fd != -1) {
+ float vol;
+
+ pthread_mutex_lock(&s->mutex);
+ vol = s->volume;
+ pthread_mutex_unlock(&s->mutex);
+
+ if (s->play.floating) {
+ sun_float_to_linear32(s->play.buf,
+ s->play.info.play.channels * to_write, vol);
+ } else {
+ sun_linear16_set_vol(s->play.buf,
+ s->play.info.play.channels * to_write, vol);
}
}
if (to_write < SUN_BUFFER_FRAMES) {
drain = 1;
}
- to_write = s->play_fd != -1 ? to_write : 0;
- to_read = s->record_fd != -1 ? SUN_BUFFER_FRAMES : 0;
+ to_write = s->play.fd != -1 ? to_write : 0;
+ to_read = s->record.fd != -1 ? SUN_BUFFER_FRAMES : 0;
write_ofs = 0;
read_ofs = 0;
while (to_write > 0 || to_read > 0) {
@@ -493,27 +472,27 @@ sun_io_routine(void * arg)
ssize_t n, frames;
if (to_write > 0) {
- bytes = FRAMES_TO_BYTES(to_write, s->p_info.play.channels);
- if ((n = write(s->play_fd, s->play_buf + write_ofs, bytes)) < 0) {
+ bytes = to_write * s->play.frame_size;
+ if ((n = write(s->play.fd, (uint8_t *)s->play.buf + write_ofs, bytes)) < 0) {
state = CUBEB_STATE_ERROR;
break;
}
- frames = BYTES_TO_FRAMES(n, s->p_info.play.channels);
+ frames = n / s->play.frame_size;
pthread_mutex_lock(&s->mutex);
s->frames_written += frames;
pthread_mutex_unlock(&s->mutex);
to_write -= frames;
- write_ofs += frames;
+ write_ofs += n;
}
if (to_read > 0) {
- bytes = FRAMES_TO_BYTES(to_read, s->r_info.record.channels);
- if ((n = read(s->record_fd, s->record_buf + read_ofs, bytes)) < 0) {
+ bytes = to_read * s->record.frame_size;
+ if ((n = read(s->record.fd, (uint8_t *)s->record.buf + read_ofs, bytes)) < 0) {
state = CUBEB_STATE_ERROR;
break;
}
- frames = BYTES_TO_FRAMES(n, s->r_info.record.channels);
+ frames = n / s->record.frame_size;
to_read -= frames;
- read_ofs += frames;
+ read_ofs += n;
}
}
if (drain && state != CUBEB_STATE_ERROR) {
@@ -547,69 +526,71 @@ sun_stream_init(cubeb * context,
ret = CUBEB_ERROR;
goto error;
}
- s->record_fd = -1;
- s->play_fd = -1;
+ s->record.fd = -1;
+ s->play.fd = -1;
if (input_device != 0) {
- snprintf(s->input_name, sizeof(s->input_name),
+ snprintf(s->record.name, sizeof(s->record.name),
"/dev/audio%zu", (uintptr_t)input_device - 1);
} else {
- snprintf(s->input_name, sizeof(s->input_name), "%s", SUN_DEFAULT_DEVICE);
+ snprintf(s->record.name, sizeof(s->record.name), "%s", SUN_DEFAULT_DEVICE);
}
if (output_device != 0) {
- snprintf(s->output_name, sizeof(s->output_name),
+ snprintf(s->play.name, sizeof(s->play.name),
"/dev/audio%zu", (uintptr_t)output_device - 1);
} else {
- snprintf(s->output_name, sizeof(s->output_name), "%s", SUN_DEFAULT_DEVICE);
+ snprintf(s->play.name, sizeof(s->play.name), "%s", SUN_DEFAULT_DEVICE);
}
if (input_stream_params != NULL) {
-#ifndef CUBEB_OLD_API
+#ifdef CUBEB_STREAM_PREF_LOOPBACK
if (input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
LOG("Loopback not supported");
ret = CUBEB_ERROR_NOT_SUPPORTED;
goto error;
}
#endif
- if (s->record_fd == -1) {
- if ((s->record_fd = open(s->input_name, O_RDONLY)) == -1) {
- LOG("Audio device cannot be opened as read-only");
+ if (s->record.fd == -1) {
+ if ((s->record.fd = open(s->record.name, O_RDONLY)) == -1) {
+ LOG("Audio device could not be opened as read-only");
ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
goto error;
}
}
- AUDIO_INITINFO(&s->r_info);
+ AUDIO_INITINFO(&s->record.info);
#ifdef AUMODE_RECORD
- s->r_info.mode = AUMODE_RECORD;
+ s->record.info.mode = AUMODE_RECORD;
#endif
- if ((ret = sun_copy_params(s->record_fd, s, input_stream_params,
- &s->r_info, &s->r_info.record)) != CUBEB_OK) {
+ if ((ret = sun_copy_params(s->record.fd, s, input_stream_params,
+ &s->record.info, &s->record.info.record)) != CUBEB_OK) {
LOG("Setting record params failed");
goto error;
}
+ s->record.floating = (input_stream_params->format == CUBEB_SAMPLE_FLOAT32NE);
}
if (output_stream_params != NULL) {
-#ifndef CUBEB_OLD_API
+#ifdef CUBEB_STREAM_PREF_LOOPBACK
if (output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
LOG("Loopback not supported");
ret = CUBEB_ERROR_NOT_SUPPORTED;
goto error;
}
#endif
- if (s->play_fd == -1) {
- if ((s->play_fd = open(s->output_name, O_WRONLY)) == -1) {
- LOG("Audio device cannot be opened as write-only");
+ if (s->play.fd == -1) {
+ if ((s->play.fd = open(s->play.name, O_WRONLY)) == -1) {
+ LOG("Audio device could not be opened as write-only");
ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
goto error;
}
}
- AUDIO_INITINFO(&s->p_info);
+ AUDIO_INITINFO(&s->play.info);
#ifdef AUMODE_PLAY
- s->p_info.mode = AUMODE_PLAY;
+ s->play.info.mode = AUMODE_PLAY;
#endif
- if ((ret = sun_copy_params(s->play_fd, s, output_stream_params,
- &s->p_info, &s->p_info.play)) != CUBEB_OK) {
+ if ((ret = sun_copy_params(s->play.fd, s, output_stream_params,
+ &s->play.info, &s->play.info.play)) != CUBEB_OK) {
LOG("Setting play params failed");
goto error;
}
+ s->play.floating = (output_stream_params->format == CUBEB_SAMPLE_FLOAT32NE);
}
s->context = context;
s->volume = 1.0;
@@ -620,28 +601,20 @@ sun_stream_init(cubeb * context,
LOG("Failed to create mutex");
goto error;
}
- if (s->play_fd != -1 && (s->play_buf = calloc(SUN_BUFFER_FRAMES,
- s->p_info.play.channels * sizeof(int16_t))) == NULL) {
+ s->play.frame_size = s->play.info.play.channels *
+ (s->play.info.play.precision / 8);
+ if (s->play.fd != -1 &&
+ (s->play.buf = calloc(SUN_BUFFER_FRAMES, s->play.frame_size)) == NULL) {
ret = CUBEB_ERROR;
goto error;
}
- if (s->record_fd != -1 && (s->record_buf = calloc(SUN_BUFFER_FRAMES,
- s->r_info.record.channels * sizeof(int16_t))) == NULL) {
+ s->record.frame_size = s->record.info.record.channels *
+ (s->record.info.record.precision / 8);
+ if (s->record.fd != -1 &&
+ (s->record.buf = calloc(SUN_BUFFER_FRAMES, s->record.frame_size)) == NULL) {
ret = CUBEB_ERROR;
goto error;
}
- if (s->floating) {
- if (s->play_fd != -1 && (s->f_play_buf = calloc(SUN_BUFFER_FRAMES,
- s->p_info.play.channels * sizeof(float))) == NULL) {
- ret = CUBEB_ERROR;
- goto error;
- }
- if (s->record_fd != -1 && (s->f_record_buf = calloc(SUN_BUFFER_FRAMES,
- s->r_info.record.channels * sizeof(float))) == NULL) {
- ret = CUBEB_ERROR;
- goto error;
- }
- }
*stream = s;
return CUBEB_OK;
error:
@@ -654,7 +627,7 @@ error:
static int
sun_stream_start(cubeb_stream * s)
{
- s->running = 1;
+ s->running = true;
if (pthread_create(&s->thread, NULL, sun_io_routine, s) != 0) {
LOG("Couldn't create thread");
return CUBEB_ERROR;
@@ -668,12 +641,11 @@ sun_stream_get_position(cubeb_stream * s, uint64_t * position)
#ifdef AUDIO_GETOOFFS
struct audio_offset offset;
- if (ioctl(s->play_fd, AUDIO_GETOOFFS, &offset) == -1) {
+ if (ioctl(s->play.fd, AUDIO_GETOOFFS, &offset) == -1) {
return CUBEB_ERROR;
}
s->blocks_written += offset.deltablks;
- *position = BYTES_TO_FRAMES(s->blocks_written * s->p_info.blocksize,
- s->p_info.play.channels);
+ *position = (s->blocks_written * s->play.info.blocksize) / s->play.frame_size;
return CUBEB_OK;
#else
pthread_mutex_lock(&s->mutex);
@@ -684,22 +656,21 @@ sun_stream_get_position(cubeb_stream * s, uint64_t * position)
}
static int
-sun_stream_get_latency(cubeb_stream * stream, uint32_t * latency)
+sun_stream_get_latency(cubeb_stream * s, uint32_t * latency)
{
#ifdef AUDIO_GETBUFINFO
struct audio_info info;
- if (ioctl(stream->play_fd, AUDIO_GETBUFINFO, &info) == -1) {
+ if (ioctl(s->play.fd, AUDIO_GETBUFINFO, &info) == -1) {
return CUBEB_ERROR;
}
- *latency = BYTES_TO_FRAMES(info.play.seek + info.blocksize,
- info.play.channels);
+ *latency = (info.play.seek + info.blocksize) / s->play.frame_size;
return CUBEB_OK;
#else
cubeb_stream_params params;
- params.rate = stream->p_info.play.sample_rate;
+ params.rate = stream->play.info.play.sample_rate;
return sun_get_min_latency(NULL, params, latency);
#endif
@@ -721,10 +692,10 @@ sun_get_current_device(cubeb_stream * stream, cubeb_device ** const device)
if (*device == NULL) {
return CUBEB_ERROR;
}
- (*device)->input_name = stream->record_fd != -1 ?
- strdup(stream->input_name) : NULL;
- (*device)->output_name = stream->play_fd != -1 ?
- strdup(stream->output_name) : NULL;
+ (*device)->input_name = stream->record.fd != -1 ?
+ strdup(stream->record.name) : NULL;
+ (*device)->output_name = stream->play.fd != -1 ?
+ strdup(stream->play.name) : NULL;
return CUBEB_OK;
}
@@ -744,22 +715,17 @@ static struct cubeb_ops const sun_ops = {
.get_max_channel_count = sun_get_max_channel_count,
.get_min_latency = sun_get_min_latency,
.get_preferred_sample_rate = sun_get_preferred_sample_rate,
-#ifndef CUBEB_OLD_API
.enumerate_devices = sun_enumerate_devices,
.device_collection_destroy = sun_device_collection_destroy,
-#endif
.destroy = sun_destroy,
.stream_init = sun_stream_init,
.stream_destroy = sun_stream_destroy,
.stream_start = sun_stream_start,
.stream_stop = sun_stream_stop,
-#ifndef CUBEB_OLD_API
.stream_reset_default_device = NULL,
-#endif
.stream_get_position = sun_stream_get_position,
.stream_get_latency = sun_stream_get_latency,
.stream_set_volume = sun_stream_set_volume,
- .stream_set_panning = NULL,
.stream_get_current_device = sun_get_current_device,
.stream_device_destroy = sun_stream_device_destroy,
.stream_register_device_changed_callback = NULL,