Commit 40d1ad33 authored by sletz's avatar sletz
Browse files

Synchronize ALSA backend with jack one

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1276 0c269be4-1314-0410-8aa9-9f06e86f4224
parent 65b2ddfe
......@@ -2,6 +2,10 @@
Jackdmp changes log
---------------------------
2006-11-08 Stephane Letz <letz@grame.fr>
* Synchronize ALSA backend with jack one.
2006-11-04 Stephane Letz <letz@grame.fr>
* Use -D to setup ADDON_DIR on OSX and Linux.
......
This diff is collapsed.
......@@ -39,7 +39,7 @@ set_control_id (snd_ctl_elem_id_t *ctl, const char *name)
{
snd_ctl_elem_id_set_name (ctl, name);
snd_ctl_elem_id_set_numid (ctl, 0);
snd_ctl_elem_id_set_interface (ctl, SND_CTL_ELEM_IFACE_PCM);
snd_ctl_elem_id_set_interface (ctl, SND_CTL_ELEM_IFACE_MIXER);
snd_ctl_elem_id_set_device (ctl, 0);
snd_ctl_elem_id_set_subdevice (ctl, 0);
snd_ctl_elem_id_set_index (ctl, 0);
......@@ -142,7 +142,7 @@ hammerfall_check_sync (hammerfall_t *h, snd_ctl_elem_value_t *ctl)
static int
hammerfall_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
{
hammerfall_t *h = (hammerfall_t *) hw->private_hw;
hammerfall_t *h = (hammerfall_t *) hw->private;
snd_ctl_elem_value_t *ctl;
snd_ctl_elem_id_t *ctl_id;
int err;
......@@ -170,7 +170,7 @@ hammerfall_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
static int
hammerfall_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode)
{
hammerfall_t *h = (hammerfall_t *) hw->private_hw;
hammerfall_t *h = (hammerfall_t *) hw->private;
snd_ctl_elem_value_t *ctl;
snd_ctl_elem_id_t *ctl_id;
int err;
......@@ -203,7 +203,7 @@ static void
hammerfall_release (jack_hardware_t *hw)
{
hammerfall_t *h = (hammerfall_t *) hw->private_hw;
hammerfall_t *h = (hammerfall_t *) hw->private;
void *status;
if (h == 0) {
......@@ -221,7 +221,7 @@ static void *
hammerfall_monitor_controls (void *arg)
{
jack_hardware_t *hw = (jack_hardware_t *) arg;
hammerfall_t *h = (hammerfall_t *) hw->private_hw;
hammerfall_t *h = (hammerfall_t *) hw->private;
snd_ctl_elem_id_t *switch_id[3];
snd_ctl_elem_value_t *sw[3];
......@@ -279,7 +279,7 @@ jack_alsa_hammerfall_hw_new (alsa_driver_t *driver)
hw->capabilities = Cap_HardwareMonitoring|Cap_AutoSync|Cap_WordClock|Cap_ClockMaster|Cap_ClockLockReporting;
hw->input_monitor_mask = 0;
hw->private_hw = 0;
hw->private = 0;
hw->set_input_monitor_mask = hammerfall_set_input_monitor_mask;
hw->change_sample_clock = hammerfall_change_sample_clock;
......@@ -299,7 +299,7 @@ jack_alsa_hammerfall_hw_new (alsa_driver_t *driver)
h->monitor_interval.tv_sec = 1;
h->monitor_interval.tv_nsec = 0;
hw->private_hw = h;
hw->private = h;
#if 0
if (pthread_create (&h->monitor_thread, 0, hammerfall_monitor_controls, hw)) {
......
......@@ -89,7 +89,7 @@ set_control_id (snd_ctl_elem_id_t *ctl, const char *name)
static int hdsp_set_mixer_gain(jack_hardware_t *hw, int input_channel,
int output_channel, int gain)
{
hdsp_t *h = (hdsp_t *) hw->private_hw;
hdsp_t *h = (hdsp_t *) hw->private;
snd_ctl_elem_value_t *ctl;
snd_ctl_elem_id_t *ctl_id;
int err;
......@@ -194,7 +194,7 @@ static double hdsp_get_hardware_power (jack_port_t *port, jack_nframes_t frame)
static void
hdsp_release (jack_hardware_t *hw)
{
hdsp_t *h = (hdsp_t *) hw->private_hw;
hdsp_t *h = (hdsp_t *) hw->private;
if (h != 0) {
free (h);
......@@ -216,7 +216,7 @@ jack_alsa_hdsp_hw_new (alsa_driver_t *driver)
/* hw->capabilities = Cap_HardwareMonitoring|Cap_AutoSync|Cap_WordClock|Cap_ClockMaster|Cap_ClockLockReporting; */
hw->capabilities = Cap_HardwareMonitoring | Cap_HardwareMetering;
hw->input_monitor_mask = 0;
hw->private_hw = 0;
hw->private = 0;
hw->set_input_monitor_mask = hdsp_set_input_monitor_mask;
hw->change_sample_clock = hdsp_change_sample_clock;
......@@ -226,7 +226,7 @@ jack_alsa_hdsp_hw_new (alsa_driver_t *driver)
h = (hdsp_t *) malloc (sizeof (hdsp_t));
h->driver = driver;
hw->private_hw = h;
hw->private = h;
return hw;
}
......@@ -34,7 +34,7 @@ static int
ice1712_hw_monitor_toggle(jack_hardware_t *hw, int idx, int onoff)
{
ice1712_t *h = (ice1712_t *) hw->private_hw;
ice1712_t *h = (ice1712_t *) hw->private;
snd_ctl_elem_value_t *val;
int err;
......@@ -66,7 +66,7 @@ ice1712_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
{
int idx;
ice1712_t *h = (ice1712_t *) hw->private_hw;
ice1712_t *h = (ice1712_t *) hw->private;
for (idx = 0; idx < 10; idx++) {
if (h->active_channels & (1<<idx)) {
......@@ -88,7 +88,7 @@ ice1712_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode)
static void
ice1712_release (jack_hardware_t *hw)
{
ice1712_t *h = (ice1712_t *) hw->private_hw;
ice1712_t *h = (ice1712_t *) hw->private;
if (h == 0)
return;
......@@ -113,7 +113,7 @@ jack_alsa_ice1712_hw_new (alsa_driver_t *driver)
hw->capabilities = Cap_HardwareMonitoring;
hw->input_monitor_mask = 0;
hw->private_hw = 0;
hw->private = 0;
hw->set_input_monitor_mask = ice1712_set_input_monitor_mask;
hw->change_sample_clock = ice1712_change_sample_clock;
......@@ -155,7 +155,7 @@ jack_alsa_ice1712_hw_new (alsa_driver_t *driver)
h->active_channels |= 0x300U;
}
hw->private_hw = h;
hw->private = h;
return hw;
}
/*
Copyright (C) 2002 Anthony Van Groningen
Copyright (C) 2002 Anthony Van Groningen
Parts based on source code taken from the
"Env24 chipset (ICE1712) control utility" that is
Parts based on source code taken from the
"Env24 chipset (ICE1712) control utility" that is
Copyright (C) 2000 by Jaroslav Kysela <perex@suse.cz>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Copyright (C) 2000 by Jaroslav Kysela <perex@suse.cz>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
......@@ -35,36 +35,31 @@
#define ANALOG_PLAYBACK_ROUTE_NAME "H/W Playback Route"
#define MULTITRACK_PEAK_NAME "Multi Track Peak"
typedef struct
{
unsigned int subvendor; /* PCI[2c-2f] */
unsigned char size; /* size of EEPROM image in bytes */
unsigned char version; /* must be 1 */
unsigned char codec; /* codec configuration PCI[60] */
unsigned char aclink; /* ACLink configuration PCI[61] */
unsigned char i2sID; /* PCI[62] */
unsigned char spdif; /* S/PDIF configuration PCI[63] */
unsigned char gpiomask; /* GPIO initial mask, 0 = write, 1 = don't */
unsigned char gpiostate; /* GPIO initial state */
unsigned char gpiodir; /* GPIO direction state */
unsigned short ac97main;
unsigned short ac97pcm;
unsigned short ac97rec;
unsigned char ac97recsrc;
unsigned char dacID[4]; /* I2S IDs for DACs */
unsigned char adcID[4]; /* I2S IDs for ADCs */
unsigned char extra[4];
}
ice1712_eeprom_t;
typedef struct
{
alsa_driver_t *driver;
ice1712_eeprom_t *eeprom;
unsigned long active_channels;
}
ice1712_t;
typedef struct {
unsigned int subvendor; /* PCI[2c-2f] */
unsigned char size; /* size of EEPROM image in bytes */
unsigned char version; /* must be 1 */
unsigned char codec; /* codec configuration PCI[60] */
unsigned char aclink; /* ACLink configuration PCI[61] */
unsigned char i2sID; /* PCI[62] */
unsigned char spdif; /* S/PDIF configuration PCI[63] */
unsigned char gpiomask; /* GPIO initial mask, 0 = write, 1 = don't */
unsigned char gpiostate; /* GPIO initial state */
unsigned char gpiodir; /* GPIO direction state */
unsigned short ac97main;
unsigned short ac97pcm;
unsigned short ac97rec;
unsigned char ac97recsrc;
unsigned char dacID[4]; /* I2S IDs for DACs */
unsigned char adcID[4]; /* I2S IDs for ADCs */
unsigned char extra[4];
} ice1712_eeprom_t;
typedef struct {
alsa_driver_t *driver;
ice1712_eeprom_t *eeprom;
unsigned long active_channels;
} ice1712_t;
#ifdef __cplusplus
extern "C"
......
......@@ -30,7 +30,7 @@
#include <memory.h>
#include <stdlib.h>
#include <limits.h>
#include <endian.h>
#include "memops.h"
......@@ -50,6 +50,37 @@ inline unsigned int fast_rand() {
return seed;
}
void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
long long y;
int z;
while (nsamples--) {
y = (long long)(*src * SAMPLE_MAX_24BIT) << 8;
if (y > INT_MAX) {
z = INT_MAX;
} else if (y < INT_MIN) {
z = INT_MIN;
} else {
z = (int)y;
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
dst[0]=(char)(z>>24);
dst[1]=(char)(z>>16);
dst[2]=(char)(z>>8);
dst[3]=(char)(z);
#elif __BYTE_ORDER == __BIG_ENDIAN
dst[0]=(char)(z);
dst[1]=(char)(z>>8);
dst[2]=(char)(z>>16);
dst[3]=(char)(z>>24);
#endif
dst += dst_skip;
src++;
}
}
void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
......@@ -69,6 +100,35 @@ void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigne
}
}
void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
/* ALERT: signed sign-extension portability !!! */
while (nsamples--) {
int x;
#if __BYTE_ORDER == __LITTLE_ENDIAN
x = (unsigned char)(src[0]);
x <<= 8;
x |= (unsigned char)(src[1]);
x <<= 8;
x |= (unsigned char)(src[2]);
x <<= 8;
x |= (unsigned char)(src[3]);
#elif __BYTE_ORDER == __BIG_ENDIAN
x = (unsigned char)(src[3]);
x <<= 8;
x |= (unsigned char)(src[2]);
x <<= 8;
x |= (unsigned char)(src[1]);
x <<= 8;
x |= (unsigned char)(src[0]);
#endif
*dst = (x >> 8) / SAMPLE_MAX_24BIT;
dst++;
src += src_skip;
}
}
void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
/* ALERT: signed sign-extension portability !!! */
......@@ -80,6 +140,42 @@ void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigne
}
}
void sample_move_dither_rect_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
/* ALERT: signed sign-extension portability !!! */
jack_default_audio_sample_t x;
long long y;
int z;
while (nsamples--) {
x = *src * SAMPLE_MAX_16BIT;
x -= (float)fast_rand() / (float)INT_MAX;
y = (long long)f_round(x);
y <<= 16;
if (y > INT_MAX) {
z = INT_MAX;
} else if (y < INT_MIN) {
z = INT_MIN;
} else {
z = (int)y;
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
dst[0]=(char)(z>>24);
dst[1]=(char)(z>>16);
dst[2]=(char)(z>>8);
dst[3]=(char)(z);
#elif __BYTE_ORDER == __BIG_ENDIAN
dst[0]=(char)(z);
dst[1]=(char)(z>>8);
dst[2]=(char)(z>>16);
dst[3]=(char)(z>>24);
#endif
dst += dst_skip;
src++;
}
}
void sample_move_dither_rect_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
......@@ -104,6 +200,47 @@ void sample_move_dither_rect_d32u24_sS (char *dst, jack_default_audio_sample_t *
}
}
void sample_move_dither_tri_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
jack_default_audio_sample_t x;
float r;
float rm1 = state->rm1;
long long y;
int z;
while (nsamples--) {
x = *src * (float)SAMPLE_MAX_16BIT;
r = 2.0f * (float)fast_rand() / (float)INT_MAX - 1.0f;
x += r - rm1;
rm1 = r;
y = (long long)f_round(x);
y <<= 16;
if (y > INT_MAX) {
z = INT_MAX;
} else if (y < INT_MIN) {
z = INT_MIN;
} else {
z = (int)y;
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
dst[0]=(char)(z>>24);
dst[1]=(char)(z>>16);
dst[2]=(char)(z>>8);
dst[3]=(char)(z);
#elif __BYTE_ORDER == __BIG_ENDIAN
dst[0]=(char)(z);
dst[1]=(char)(z>>8);
dst[2]=(char)(z>>16);
dst[3]=(char)(z>>24);
#endif
dst += dst_skip;
src++;
}
state->rm1 = rm1;
}
void sample_move_dither_tri_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
......@@ -134,6 +271,66 @@ void sample_move_dither_tri_d32u24_sS (char *dst, jack_default_audio_sample_t *
state->rm1 = rm1;
}
void sample_move_dither_shaped_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
jack_default_audio_sample_t x;
jack_default_audio_sample_t xe; /* the innput sample - filtered error */
jack_default_audio_sample_t xp; /* x' */
float r;
float rm1 = state->rm1;
unsigned int idx = state->idx;
long long y;
int z;
while (nsamples--) {
x = *src * (float)SAMPLE_MAX_16BIT;
r = 2.0f * (float)fast_rand() / (float)INT_MAX - 1.0f;
/* Filter the error with Lipshitz's minimally audible FIR:
[2.033 -2.165 1.959 -1.590 0.6149] */
xe = x
- state->e[idx] * 2.033f
+ state->e[(idx - 1) & DITHER_BUF_MASK] * 2.165f
- state->e[(idx - 2) & DITHER_BUF_MASK] * 1.959f
+ state->e[(idx - 3) & DITHER_BUF_MASK] * 1.590f
- state->e[(idx - 4) & DITHER_BUF_MASK] * 0.6149f;
xp = xe + r - rm1;
rm1 = r;
/* This could be some inline asm on x86 */
y = (long long)f_round(xp);
/* Intrinsic z^-1 delay */
idx = (idx + 1) & DITHER_BUF_MASK;
state->e[idx] = y - xe;
y <<= 16;
if (y > INT_MAX) {
z = INT_MAX;
} else if (y < INT_MIN) {
z = INT_MIN;
} else {
z = (int)y;
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
dst[0]=(char)(z>>24);
dst[1]=(char)(z>>16);
dst[2]=(char)(z>>8);
dst[3]=(char)(z);
#elif __BYTE_ORDER == __BIG_ENDIAN
dst[0]=(char)(z);
dst[1]=(char)(z>>8);
dst[2]=(char)(z>>16);
dst[3]=(char)(z>>24);
#endif
dst += dst_skip;
src++;
}
state->rm1 = rm1;
state->idx = idx;
}
void sample_move_dither_shaped_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
......@@ -182,6 +379,36 @@ void sample_move_dither_shaped_d32u24_sS (char *dst, jack_default_audio_sample_
state->idx = idx;
}
void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
long long y;
int z;
while (nsamples--) {
y = (long long)(*src * SAMPLE_MAX_24BIT);
if (y > (INT_MAX >> 8 )) {
z = (INT_MAX >> 8);
} else if (y < (INT_MIN >> 8 )) {
z = (INT_MIN >> 8 );
} else {
z = (int)y;
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
dst[0]=(char)(z>>16);
dst[1]=(char)(z>>8);
dst[2]=(char)(z);
#elif __BYTE_ORDER == __BIG_ENDIAN
dst[0]=(char)(z);
dst[1]=(char)(z>>8);
dst[2]=(char)(z>>16);
#endif
dst += dst_skip;
src++;
}
}
void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
......@@ -205,6 +432,39 @@ void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned l
}
}
void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
/* ALERT: signed sign-extension portability !!! */
while (nsamples--) {
int x;
#if __BYTE_ORDER == __LITTLE_ENDIAN
x = (unsigned char)(src[0]);
x <<= 8;
x |= (unsigned char)(src[1]);
x <<= 8;
x |= (unsigned char)(src[2]);
/* correct sign bit and the rest of the top byte */
if (src[0] & 0x80) {
x |= 0xff << 24;
}
#elif __BYTE_ORDER == __BIG_ENDIAN
x = (unsigned char)(src[2]);
x <<= 8;
x |= (unsigned char)(src[1]);
x <<= 8;
x |= (unsigned char)(src[0]);
/* correct sign bit and the rest of the top byte */
if (src[0] & 0x80) {
x |= 0xff << 24;
}
#endif
*dst = x / SAMPLE_MAX_24BIT;
dst++;
src += src_skip;
}
}
void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
/* ALERT: signed sign-extension portability !!! */
......@@ -223,6 +483,42 @@ void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned l
}
}
void sample_move_dither_rect_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
/* ALERT: signed sign-extension portability !!! */
jack_default_audio_sample_t x;
long long y;
int z;
while (nsamples--) {
x = *src * SAMPLE_MAX_16BIT;
x -= (float)fast_rand() / (float)INT_MAX;
y = (long long)f_round(x);
y <<= 8;
if (y > (INT_MAX >> 8)) {
z = (INT_MAX >> 8);
} else if (y < (INT_MIN >> 8)) {
z = (INT_MIN >> 8);
} else {
z = (int)y;
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
dst[0]=(char)(z>>16);
dst[1]=(char)(z>>8);
dst[2]=(char)(z);
#elif __BYTE_ORDER == __BIG_ENDIAN
dst[0]=(char)(z);
dst[1]=(char)(z>>8);
dst[2]=(char)(z>>16);
#endif
dst += dst_skip;
src++;
}
}
void sample_move_dither_rect_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
......@@ -253,6 +549,46 @@ void sample_move_dither_rect_d24_sS (char *dst, jack_default_audio_sample_t *src
}
}
void sample_move_dither_tri_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
jack_default_audio_sample_t x;
float r;
float rm1 = state->rm1;
long long y;