Browse Source

Synchronize ALSA backend with jack one

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1276 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.59
sletz 18 years ago
parent
commit
40d1ad3315
11 changed files with 2201 additions and 1640 deletions
  1. +4
    -0
      ChangeLog
  2. +1356
    -1349
      linux/alsa/JackAlsaDriver.cpp
  3. +7
    -7
      linux/alsa/hammerfall.c
  4. +4
    -4
      linux/alsa/hdsp.c
  5. +5
    -5
      linux/alsa/ice1712.c
  6. +40
    -45
      linux/alsa/ice1712.h
  7. +554
    -1
      linux/alsa/memops.c
  8. +69
    -55
      linux/alsa/memops.h
  9. +96
    -120
      linux/alsa/usx2y.c
  10. +42
    -47
      linux/alsa/usx2y.h
  11. +24
    -7
      macosx/Jackdmp.xcode/project.pbxproj

+ 4
- 0
ChangeLog View File

@@ -2,6 +2,10 @@
Jackdmp changes log 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> 2006-11-04 Stephane Letz <letz@grame.fr>
* Use -D to setup ADDON_DIR on OSX and Linux. * Use -D to setup ADDON_DIR on OSX and Linux.


+ 1356
- 1349
linux/alsa/JackAlsaDriver.cpp
File diff suppressed because it is too large
View File


+ 7
- 7
linux/alsa/hammerfall.c View File

@@ -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_name (ctl, name);
snd_ctl_elem_id_set_numid (ctl, 0); 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_device (ctl, 0);
snd_ctl_elem_id_set_subdevice (ctl, 0); snd_ctl_elem_id_set_subdevice (ctl, 0);
snd_ctl_elem_id_set_index (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 static int
hammerfall_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) 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_value_t *ctl;
snd_ctl_elem_id_t *ctl_id; snd_ctl_elem_id_t *ctl_id;
int err; int err;
@@ -170,7 +170,7 @@ hammerfall_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
static int static int
hammerfall_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) 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_value_t *ctl;
snd_ctl_elem_id_t *ctl_id; snd_ctl_elem_id_t *ctl_id;
int err; int err;
@@ -203,7 +203,7 @@ static void
hammerfall_release (jack_hardware_t *hw) hammerfall_release (jack_hardware_t *hw)


{ {
hammerfall_t *h = (hammerfall_t *) hw->private_hw;
hammerfall_t *h = (hammerfall_t *) hw->private;
void *status; void *status;


if (h == 0) { if (h == 0) {
@@ -221,7 +221,7 @@ static void *
hammerfall_monitor_controls (void *arg) hammerfall_monitor_controls (void *arg)
{ {
jack_hardware_t *hw = (jack_hardware_t *) 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_id_t *switch_id[3];
snd_ctl_elem_value_t *sw[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->capabilities = Cap_HardwareMonitoring|Cap_AutoSync|Cap_WordClock|Cap_ClockMaster|Cap_ClockLockReporting;
hw->input_monitor_mask = 0; hw->input_monitor_mask = 0;
hw->private_hw = 0;
hw->private = 0;


hw->set_input_monitor_mask = hammerfall_set_input_monitor_mask; hw->set_input_monitor_mask = hammerfall_set_input_monitor_mask;
hw->change_sample_clock = hammerfall_change_sample_clock; 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_sec = 1;
h->monitor_interval.tv_nsec = 0; h->monitor_interval.tv_nsec = 0;


hw->private_hw = h;
hw->private = h;


#if 0 #if 0
if (pthread_create (&h->monitor_thread, 0, hammerfall_monitor_controls, hw)) { if (pthread_create (&h->monitor_thread, 0, hammerfall_monitor_controls, hw)) {


+ 4
- 4
linux/alsa/hdsp.c View File

@@ -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, static int hdsp_set_mixer_gain(jack_hardware_t *hw, int input_channel,
int output_channel, int gain) 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_value_t *ctl;
snd_ctl_elem_id_t *ctl_id; snd_ctl_elem_id_t *ctl_id;
int err; int err;
@@ -194,7 +194,7 @@ static double hdsp_get_hardware_power (jack_port_t *port, jack_nframes_t frame)
static void static void
hdsp_release (jack_hardware_t *hw) hdsp_release (jack_hardware_t *hw)
{ {
hdsp_t *h = (hdsp_t *) hw->private_hw;
hdsp_t *h = (hdsp_t *) hw->private;


if (h != 0) { if (h != 0) {
free (h); 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_AutoSync|Cap_WordClock|Cap_ClockMaster|Cap_ClockLockReporting; */
hw->capabilities = Cap_HardwareMonitoring | Cap_HardwareMetering; hw->capabilities = Cap_HardwareMonitoring | Cap_HardwareMetering;
hw->input_monitor_mask = 0; hw->input_monitor_mask = 0;
hw->private_hw = 0;
hw->private = 0;


hw->set_input_monitor_mask = hdsp_set_input_monitor_mask; hw->set_input_monitor_mask = hdsp_set_input_monitor_mask;
hw->change_sample_clock = hdsp_change_sample_clock; 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 = (hdsp_t *) malloc (sizeof (hdsp_t));
h->driver = driver; h->driver = driver;
hw->private_hw = h;
hw->private = h;


return hw; return hw;
} }

+ 5
- 5
linux/alsa/ice1712.c View File

@@ -34,7 +34,7 @@ static int
ice1712_hw_monitor_toggle(jack_hardware_t *hw, int idx, int onoff) 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; snd_ctl_elem_value_t *val;
int err; int err;
@@ -66,7 +66,7 @@ ice1712_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
{ {
int idx; int idx;
ice1712_t *h = (ice1712_t *) hw->private_hw;
ice1712_t *h = (ice1712_t *) hw->private;
for (idx = 0; idx < 10; idx++) { for (idx = 0; idx < 10; idx++) {
if (h->active_channels & (1<<idx)) { if (h->active_channels & (1<<idx)) {
@@ -88,7 +88,7 @@ ice1712_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode)
static void static void
ice1712_release (jack_hardware_t *hw) ice1712_release (jack_hardware_t *hw)
{ {
ice1712_t *h = (ice1712_t *) hw->private_hw;
ice1712_t *h = (ice1712_t *) hw->private;
if (h == 0) if (h == 0)
return; return;
@@ -113,7 +113,7 @@ jack_alsa_ice1712_hw_new (alsa_driver_t *driver)


hw->capabilities = Cap_HardwareMonitoring; hw->capabilities = Cap_HardwareMonitoring;
hw->input_monitor_mask = 0; hw->input_monitor_mask = 0;
hw->private_hw = 0;
hw->private = 0;


hw->set_input_monitor_mask = ice1712_set_input_monitor_mask; hw->set_input_monitor_mask = ice1712_set_input_monitor_mask;
hw->change_sample_clock = ice1712_change_sample_clock; 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; h->active_channels |= 0x300U;
} }
hw->private_hw = h;
hw->private = h;


return hw; return hw;
} }

+ 40
- 45
linux/alsa/ice1712.h View File

@@ -1,24 +1,24 @@
/* /*
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 ANALOG_PLAYBACK_ROUTE_NAME "H/W Playback Route"
#define MULTITRACK_PEAK_NAME "Multi Track Peak" #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 #ifdef __cplusplus
extern "C" extern "C"


+ 554
- 1
linux/alsa/memops.c View File

@@ -30,7 +30,7 @@
#include <memory.h> #include <memory.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h> #include <limits.h>
#include <endian.h>
#include "memops.h" #include "memops.h"




@@ -50,6 +50,37 @@ inline unsigned int fast_rand() {
return seed; 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) 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) 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 !!! */ /* 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) 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) 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; 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) 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; 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) 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) 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 !!! */ /* 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) 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;
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 <<= 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++;
}
state->rm1 = rm1;
}

void sample_move_dither_tri_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) void sample_move_dither_tri_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{ {
@@ -287,6 +623,64 @@ void sample_move_dither_tri_d24_sS (char *dst, jack_default_audio_sample_t *src
state->rm1 = rm1; state->rm1 = rm1;
} }


void sample_move_dither_shaped_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;
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 <<= 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++;
}
state->rm1 = rm1;
state->idx = idx;
}

void sample_move_dither_shaped_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) void sample_move_dither_shaped_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{ {
@@ -339,6 +733,32 @@ void sample_move_dither_shaped_d24_sS (char *dst, jack_default_audio_sample_t *
state->idx = idx; state->idx = idx;
} }


void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{
int tmp;

/* ALERT: signed sign-extension portability !!! */

while (nsamples--) {
tmp = f_round(*src * SAMPLE_MAX_16BIT);
if (tmp > SHRT_MAX) {
tmp = SHRT_MAX;
} else if (tmp < SHRT_MIN) {
tmp = SHRT_MIN;
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
dst[0]=(char)(tmp>>8);
dst[1]=(char)(tmp);
#elif __BYTE_ORDER == __BIG_ENDIAN
dst[0]=(char)(tmp);
dst[1]=(char)(tmp>>8);
#endif
dst += dst_skip;
src++;
}
}

void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{ {
@@ -360,6 +780,33 @@ void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned
} }
} }


void sample_move_dither_rect_d16_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 val;
int tmp;

while (nsamples--) {
val = *src * (float)SAMPLE_MAX_16BIT;
val -= (float)fast_rand() / (float)INT_MAX;
tmp = f_round(val);
if (tmp > SHRT_MAX) {
tmp = SHRT_MAX;
} else if (tmp < SHRT_MIN) {
tmp = SHRT_MIN;
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
dst[0]=(char)(tmp>>8);
dst[1]=(char)(tmp);
#elif __BYTE_ORDER == __BIG_ENDIAN
dst[0]=(char)(tmp);
dst[1]=(char)(tmp>>8);
#endif
dst += dst_skip;
src++;
}
}

void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{ {
@@ -382,6 +829,39 @@ void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *sr
} }
} }


void sample_move_dither_tri_d16_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;
int y;

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 = f_round(x);

if (y > SHRT_MAX) {
y = SHRT_MAX;
} else if (y < SHRT_MIN) {
y = SHRT_MIN;
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
dst[0]=(char)(y>>8);
dst[1]=(char)(y);
#elif __BYTE_ORDER == __BIG_ENDIAN
dst[0]=(char)(y);
dst[1]=(char)(y>>8);
#endif
dst += dst_skip;
src++;
}
state->rm1 = rm1;
}

void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{ {
@@ -411,6 +891,57 @@ void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src
state->rm1 = rm1; state->rm1 = rm1;
} }


void sample_move_dither_shaped_d16_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;
int y;

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 = f_round(xp);

/* Intrinsic z^-1 delay */
idx = (idx + 1) & DITHER_BUF_MASK;
state->e[idx] = y - xe;

if (y > SHRT_MAX) {
y = SHRT_MAX;
} else if (y < SHRT_MIN) {
y = SHRT_MIN;
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
dst[0]=(char)(y>>8);
dst[1]=(char)(y);
#elif __BYTE_ORDER == __BIG_ENDIAN
dst[0]=(char)(y);
dst[1]=(char)(y>>8);
#endif
dst += dst_skip;
src++;
}
state->rm1 = rm1;
state->idx = idx;
}

void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
{ {
@@ -457,6 +988,28 @@ void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *
state->idx = idx; state->idx = idx;
} }


void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{
short z;

/* ALERT: signed sign-extension portability !!! */
while (nsamples--) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
z = (unsigned char)(src[0]);
z <<= 8;
z |= (unsigned char)(src[1]);
#elif __BYTE_ORDER == __BIG_ENDIAN
z = (unsigned char)(src[1]);
z <<= 8;
z |= (unsigned char)(src[0]);
#endif
*dst = z / SAMPLE_MAX_16BIT;
dst++;
src += src_skip;
}
}

void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
{ {


+ 69
- 55
linux/alsa/memops.h View File

@@ -33,74 +33,88 @@ typedef enum {
#define DITHER_BUF_SIZE 8 #define DITHER_BUF_SIZE 8
#define DITHER_BUF_MASK 7 #define DITHER_BUF_MASK 7


typedef struct
{
typedef struct {
unsigned int depth; unsigned int depth;
float rm1; float rm1;
unsigned int idx; unsigned int idx;
float e[DITHER_BUF_SIZE]; float e[DITHER_BUF_SIZE];
} }
dither_state_t;
} dither_state_t;


#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
{ {
#endif #endif


void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);

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);
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);
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);
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);
void sample_move_dither_tri_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_shaped_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);

void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);

void sample_merge_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_merge_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);

static __inline__ void
sample_merge (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt)
{
while (cnt--) {
*dst += *src;
dst++;
src++;
}
}

static __inline__ void
sample_memcpy (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt)
{
memcpy (dst, src, cnt * sizeof (jack_default_audio_sample_t));
}

void memset_interleave (char *dst, char val, unsigned long bytes, unsigned long unit_bytes, unsigned long skip_bytes);
void memcpy_fake (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar);

void memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);
void memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);
void memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);

void merge_memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);
void merge_memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);
void merge_memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);

void merge_memcpy_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar);
void merge_memcpy_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar);
void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);

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);
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);
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);
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);
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);
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);
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);
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);
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);
void sample_move_dither_tri_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_shaped_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_shaped_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_rect_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_tri_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_shaped_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);

void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);
void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip);

void sample_merge_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
void sample_merge_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);

static __inline__ void
sample_merge (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt)


#ifdef __cplusplus
{
while (cnt--) {
*dst += *src;
dst++;
src++;
}
} }
#endif


static __inline__ void
sample_memcpy (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt)

{
memcpy (dst, src, cnt * sizeof (jack_default_audio_sample_t));
}

void memset_interleave (char *dst, char val, unsigned long bytes, unsigned long unit_bytes, unsigned long skip_bytes);
void memcpy_fake (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar);

void memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);
void memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);
void memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);

void merge_memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);
void merge_memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);
void merge_memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes);

void merge_memcpy_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar);
void merge_memcpy_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar);


#ifdef __cplusplus
}
#endif
#endif /* __jack_memops_h__ */ #endif /* __jack_memops_h__ */

+ 96
- 120
linux/alsa/usx2y.c View File

@@ -33,7 +33,12 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif #endif


//#define DBGHWDEP


#ifdef DBGHWDEP
int dbg_offset;
char dbg_buffer[8096];
#endif
static static
int usx2y_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) int usx2y_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask)
{ {
@@ -120,7 +125,7 @@ usx2y_driver_get_channel_addresses_playback (alsa_driver_t *driver,
if (dbg_offset < (sizeof(dbg_buffer) - 256)) if (dbg_offset < (sizeof(dbg_buffer) - 256))
dbg_offset += sprintf(dbg_buffer + dbg_offset, "avail %li@%p\n", *playback_avail, driver->playback_addr[0]); dbg_offset += sprintf(dbg_buffer + dbg_offset, "avail %li@%p\n", *playback_avail, driver->playback_addr[0]);
else { else {
jack_error(dbg_buffer);
printf(dbg_buffer);
return -1; return -1;
} }
#endif #endif
@@ -145,7 +150,7 @@ usx2y_driver_get_channel_addresses_capture (alsa_driver_t *driver,
return 0; /* FIXME: return -1; */ return 0; /* FIXME: return -1; */
h->capture_iso_bytes_done = 0; h->capture_iso_bytes_done = 0;
#ifdef DBGHWDEP #ifdef DBGHWDEP
dbg_offset = sprintf(dbg_buffer, "first iso = %i %i@%p:%i\n",
dbg_offset = sprintf(dbg_buffer, "cfirst iso = %i %i@%p:%i\n",
iso, h->hwdep_pcm_shm->captured_iso[iso].length, iso, h->hwdep_pcm_shm->captured_iso[iso].length,
h->hwdep_pcm_shm->capture0x8, h->hwdep_pcm_shm->capture0x8,
h->hwdep_pcm_shm->captured_iso[iso].offset); h->hwdep_pcm_shm->captured_iso[iso].offset);
@@ -154,7 +159,7 @@ usx2y_driver_get_channel_addresses_capture (alsa_driver_t *driver,
iso = h->capture_iso_start; iso = h->capture_iso_start;
} }
#ifdef DBGHWDEP #ifdef DBGHWDEP
dbg_offset += sprintf(dbg_buffer + dbg_offset, "iso = %i(%i;%i); ", iso,
dbg_offset += sprintf(dbg_buffer + dbg_offset, "ciso = %i(%i;%i); ", iso,
h->hwdep_pcm_shm->captured_iso[iso].offset, h->hwdep_pcm_shm->captured_iso[iso].offset,
h->hwdep_pcm_shm->captured_iso[iso].frame); h->hwdep_pcm_shm->captured_iso[iso].frame);
#endif #endif
@@ -180,10 +185,21 @@ usx2y_driver_get_channel_addresses_capture (alsa_driver_t *driver,
((chn & 1) ? driver->capture_sample_bytes : 0); ((chn & 1) ? driver->capture_sample_bytes : 0);
} }
#ifdef DBGHWDEP #ifdef DBGHWDEP
{
int f = 0;
unsigned *u = driver->capture_addr[0];
static unsigned last;
dbg_offset += sprintf(dbg_buffer + dbg_offset, "\nvon %6u bis %6u\n", last, u[0]);
while (f < *capture_avail && dbg_offset < (sizeof(dbg_buffer) - 256)) {
if (u[f] != last + 1)
dbg_offset += sprintf(dbg_buffer + dbg_offset, "\nooops %6u %6u\n", last, u[f]);
last = u[f++];
}
}
if (dbg_offset < (sizeof(dbg_buffer) - 256)) if (dbg_offset < (sizeof(dbg_buffer) - 256))
dbg_offset += sprintf(dbg_buffer + dbg_offset, "avail %li@%p\n", *capture_avail, driver->capture_addr[0]); dbg_offset += sprintf(dbg_buffer + dbg_offset, "avail %li@%p\n", *capture_avail, driver->capture_addr[0]);
else { else {
jack_error(dbg_buffer);
printf(dbg_buffer);
return -1; return -1;
} }
#endif #endif
@@ -199,6 +215,12 @@ usx2y_driver_start (alsa_driver_t *driver)


usx2y_t *h = (usx2y_t *) driver->hw->private; usx2y_t *h = (usx2y_t *) driver->hw->private;


if (driver->capture_nchannels == 4) {
// US428 channels 3+4 are on a seperate 2 channel stream.
// ALSA thinks its 1 stream with 4 channels, so we have to hack here.
driver->capture_interleave_skip = 2 * driver->capture_sample_bytes;
}

driver->poll_last = 0; driver->poll_last = 0;
driver->poll_next = 0; driver->poll_next = 0;


@@ -445,9 +467,9 @@ usx2y_driver_null_cycle (alsa_driver_t* driver, jack_nframes_t nframes)
static int static int
usx2y_driver_read (alsa_driver_t *driver, jack_nframes_t nframes) usx2y_driver_read (alsa_driver_t *driver, jack_nframes_t nframes)
{ {
snd_pcm_sframes_t contiguous;
snd_pcm_uframes_t contiguous;
snd_pcm_sframes_t nread; snd_pcm_sframes_t nread;
snd_pcm_sframes_t offset;
snd_pcm_uframes_t offset;
jack_default_audio_sample_t* buf[4]; jack_default_audio_sample_t* buf[4];
channel_t chn; channel_t chn;
JSList *node; JSList *node;
@@ -460,61 +482,55 @@ usx2y_driver_read (alsa_driver_t *driver, jack_nframes_t nframes)
} }


nread = 0; nread = 0;
contiguous = 0;


while (nframes) {
if (snd_pcm_mmap_begin (driver->capture_handle,
&driver->capture_areas,
&offset, &nframes_) < 0) {
jack_error ("ALSA/USX2Y: %s: mmap areas info error",
driver->alsa_name_capture);
return -1;
}


contiguous = (nframes > driver->frames_per_cycle) ?
driver->frames_per_cycle : nframes;
for (chn = 0, node = driver->capture_ports;
node; node = jack_slist_next (node), chn++) {
port = (jack_port_t *) node->data;
if (!jack_port_connected (port)) {
continue;
}
buf[chn] = jack_port_get_buffer (port, nframes_);
}


if (snd_pcm_mmap_begin (
driver->capture_handle, &driver->capture_areas,
(snd_pcm_uframes_t *) &offset,
(snd_pcm_uframes_t *) &nframes_) < 0) {
jack_error ("ALSA/USX2Y: %s: mmap areas info error",
driver->alsa_name_capture);
while (nframes) {

contiguous = nframes;
if (usx2y_driver_get_channel_addresses_capture (
driver, &contiguous) < 0) {
return -1; return -1;
} }

for (chn = 0, node = driver->capture_ports; for (chn = 0, node = driver->capture_ports;
node && chn < 4;
node = jack_slist_next (node), chn++) {
node; node = jack_slist_next (node), chn++) {
port = (jack_port_t *) node->data; port = (jack_port_t *) node->data;
if (!jack_port_connected (port)) { if (!jack_port_connected (port)) {
/* no-copy optimization */
continue; continue;
} }
buf[chn] = jack_port_get_buffer (port, nframes_);
}

while (nframes) {
contiguous = nframes;
if (usx2y_driver_get_channel_addresses_capture (
driver, &contiguous) < 0) {
return -1;
}
for (chn = 0, node = driver->capture_ports;
node && chn < 4;
node = jack_slist_next (node), chn++) {
port = (jack_port_t *) node->data;
if (!jack_port_connected (port)) {
/* no-copy optimization */
continue;
}
alsa_driver_read_from_channel (driver, chn,
buf[chn] + nread, contiguous);
}
nread += contiguous;
nframes -= contiguous;
}

if ((err = snd_pcm_mmap_commit (driver->capture_handle,
offset, nframes_)) < 0) {
jack_error ("ALSA/USX2Y: could not complete read of %"
PRIu32 " frames: error = %d", nframes_, err);
return -1;
alsa_driver_read_from_channel (driver, chn,
buf[chn] + nread,
contiguous);
/* sample_move_dS_s24(buf[chn] + nread, */
/* driver->capture_addr[chn], */
/* contiguous, */
/* driver->capture_interleave_skip); */
} }
nread += contiguous;
nframes -= contiguous;
}


// nframes -= contiguous;
if ((err = snd_pcm_mmap_commit (driver->capture_handle,
offset, nframes_)) < 0) {
jack_error ("ALSA/USX2Y: could not complete read of %"
PRIu32 " frames: error = %d", nframes_, err);
return -1;
} }


return 0; return 0;
@@ -527,11 +543,10 @@ usx2y_driver_write (alsa_driver_t* driver, jack_nframes_t nframes)
JSList *node; JSList *node;
jack_default_audio_sample_t* buf[2]; jack_default_audio_sample_t* buf[2];
snd_pcm_sframes_t nwritten; snd_pcm_sframes_t nwritten;
snd_pcm_sframes_t contiguous;
snd_pcm_sframes_t offset;
snd_pcm_uframes_t contiguous;
snd_pcm_uframes_t offset;
jack_port_t *port; jack_port_t *port;
int err; int err;
int dbg_loops = 1;
snd_pcm_uframes_t nframes_ = nframes; snd_pcm_uframes_t nframes_ = nframes;


driver->process_count++; driver->process_count++;
@@ -541,7 +556,6 @@ usx2y_driver_write (alsa_driver_t* driver, jack_nframes_t nframes)
} }


nwritten = 0; nwritten = 0;
contiguous = 0;


/* check current input monitor request status */ /* check current input monitor request status */


@@ -563,83 +577,45 @@ usx2y_driver_write (alsa_driver_t* driver, jack_nframes_t nframes)
} }
} }


while (nframes) {
if (snd_pcm_mmap_begin(driver->playback_handle,
&driver->playback_areas,
&offset, &nframes_) < 0) {
jack_error ("ALSA/USX2Y: %s: mmap areas info error",
driver->alsa_name_capture);
return -1;
}


if (--dbg_loops)
return dbg_loops;
for (chn = 0, node = driver->playback_ports;
node; node = jack_slist_next (node), chn++) {
port = (jack_port_t *) node->data;
buf[chn] = jack_port_get_buffer (port, nframes_);
}


contiguous = (nframes > driver->frames_per_cycle) ?
driver->frames_per_cycle : nframes;
while (nframes) {


if (snd_pcm_mmap_begin(
driver->playback_handle, &driver->playback_areas,
&offset, &nframes_) < 0) {
jack_error ("ALSA/USX2Y: %s: mmap areas info error",
driver->alsa_name_capture);
contiguous = nframes;
if (usx2y_driver_get_channel_addresses_playback (
driver, &contiguous) < 0) {
return -1; return -1;
} }

for (chn = 0, node = driver->playback_ports; for (chn = 0, node = driver->playback_ports;
node && chn < 2;
node = jack_slist_next (node), chn++) {
node; node = jack_slist_next (node), chn++) {
port = (jack_port_t *) node->data; port = (jack_port_t *) node->data;
if (!jack_port_connected (port)) {
continue;
}
buf[chn] = jack_port_get_buffer (port, nframes_);
}

while (nframes) {
contiguous = nframes;
if (usx2y_driver_get_channel_addresses_playback (
driver, &contiguous) < 0) {
return -1;
}
for (chn = 0, node = driver->playback_ports;
node && chn < 2;
node = jack_slist_next (node), chn++) {
port = (jack_port_t *) node->data;
if (!jack_port_connected (port)) {
continue;
}
alsa_driver_write_to_channel (driver, chn,
buf[chn] + nwritten,
contiguous);
}
nwritten += contiguous;
if (driver->channels_not_done) {
alsa_driver_silence_untouched_channels (driver,
contiguous);
}
nframes -= contiguous;
}

if ((err = snd_pcm_mmap_commit (driver->playback_handle,
offset, nframes_)) < 0) {
jack_error ("ALSA/USX2Y: could not complete playback of %"
PRIu32 " frames: error = %d", nframes_, err);
if (err != EPIPE && err != ESTRPIPE)
return -1;
alsa_driver_write_to_channel (driver, chn,
buf[chn] + nwritten,
contiguous);
} }
// nframes -= contiguous;
nwritten += contiguous;
nframes -= contiguous;
} }


/* { */
/* usx2y_t *h = (usx2y_t *) driver->hw->private; */
/* unsigned *pu = (unsigned *)h->hwdep_pcm_shm->playback; */
/* int i = sizeof(h->hwdep_pcm_shm->playback) / sizeof(*pu); */

/* while (i) { */
/* if (*(pu)) { */
/* jack_error("%p;error %u(=0x%X)@%p", */
/* h->hwdep_pcm_shm->playback, */
/* *pu, *pu, pu); */
/* return -1; */
/* } */
/* --i; */
/* ++pu; */
/* } */
/* } */
if ((err = snd_pcm_mmap_commit (driver->playback_handle,
offset, nframes_)) < 0) {
jack_error ("ALSA/USX2Y: could not complete playback of %"
PRIu32 " frames: error = %d", nframes_, err);
if (err != EPIPE && err != ESTRPIPE)
return -1;
}


return 0; return 0;
} }


+ 42
- 47
linux/alsa/usx2y.h View File

@@ -1,22 +1,22 @@
/* /*
Copyright (C) 2001 Paul Davis
Copyright (C) 2004 Karsten Wiese, Rui Nuno Capela
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.
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.
$Id: usx2y.h,v 1.2 2005/11/23 11:24:29 letz Exp $
Copyright (C) 2001 Paul Davis
Copyright (C) 2004 Karsten Wiese, Rui Nuno Capela
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.
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.
$Id: usx2y.h 855 2004-12-28 05:50:18Z joq $
*/ */


#ifndef __jack_usx2y_h__ #ifndef __jack_usx2y_h__
@@ -28,38 +28,33 @@


#define USX2Y_SSS (((USX2Y_MAXPACK * USX2Y_MAXBUFFERMS * USX2Y_MAXSTRIDE + 4096) / 4096) * 4096) #define USX2Y_SSS (((USX2Y_MAXPACK * USX2Y_MAXBUFFERMS * USX2Y_MAXSTRIDE + 4096) / 4096) * 4096)


struct snd_usX2Y_hwdep_pcm_shm
{
char playback[USX2Y_SSS];
char capture0x8[USX2Y_SSS];
char capture0xA[USX2Y_SSS];
volatile int playback_iso_head;
int playback_iso_start;
struct
{
int frame,
offset,
length;
}
captured_iso[128];
volatile int captured_iso_head;
volatile unsigned captured_iso_frames;
int capture_iso_start;
struct snd_usX2Y_hwdep_pcm_shm {
char playback[USX2Y_SSS];
char capture0x8[USX2Y_SSS];
char capture0xA[USX2Y_SSS];
volatile int playback_iso_head;
int playback_iso_start;
struct {
int frame,
offset,
length;
} captured_iso[128];
volatile int captured_iso_head;
volatile unsigned captured_iso_frames;
int capture_iso_start;
}; };
typedef struct snd_usX2Y_hwdep_pcm_shm snd_usX2Y_hwdep_pcm_shm_t; typedef struct snd_usX2Y_hwdep_pcm_shm snd_usX2Y_hwdep_pcm_shm_t;


typedef struct
{
alsa_driver_t *driver;
snd_hwdep_t *hwdep_handle;
struct pollfd pfds;
struct snd_usX2Y_hwdep_pcm_shm *hwdep_pcm_shm;
int playback_iso_start;
int playback_iso_bytes_done;
int capture_iso_start;
int capture_iso_bytes_done;
}
usx2y_t;
typedef struct {
alsa_driver_t *driver;
snd_hwdep_t *hwdep_handle;
struct pollfd pfds;
struct snd_usX2Y_hwdep_pcm_shm *hwdep_pcm_shm;
int playback_iso_start;
int playback_iso_bytes_done;
int capture_iso_start;
int capture_iso_bytes_done;
} usx2y_t;


jack_hardware_t * jack_hardware_t *
jack_alsa_usx2y_hw_new (alsa_driver_t *driver); jack_alsa_usx2y_hw_new (alsa_driver_t *driver);


+ 24
- 7
macosx/Jackdmp.xcode/project.pbxproj View File

@@ -1009,7 +1009,6 @@
4BF8D1CE0834EF2200C94B91, 4BF8D1CE0834EF2200C94B91,
4BF8D1D60834EF2F00C94B91, 4BF8D1D60834EF2F00C94B91,
4BF8D1E80834EF6700C94B91, 4BF8D1E80834EF6700C94B91,
4BF8D1EC0834EF7500C94B91,
4BF8D2050834EFD100C94B91, 4BF8D2050834EFD100C94B91,
4BF8D2060834EFD100C94B91, 4BF8D2060834EFD100C94B91,
4BF8D2350834F14400C94B91, 4BF8D2350834F14400C94B91,
@@ -1028,6 +1027,8 @@
4B003AB408E2B2BA0060EFDC, 4B003AB408E2B2BA0060EFDC,
4B98AE040931D30C0091932A, 4B98AE040931D30C0091932A,
4B1880CB09A1DDF100154099, 4B1880CB09A1DDF100154099,
4BCD4CF50B00A0F90091F8E8,
4BCD4CF90B00A15B0091F8E8,
); );
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -2079,6 +2080,7 @@
}; };
4BA550F905E241D900569492 = { 4BA550F905E241D900569492 = {
children = ( children = (
4BCD4CF40B00A0F90091F8E8,
4B168CA4076A5333005B2802, 4B168CA4076A5333005B2802,
4BF8D1FB0834EFD100C94B91, 4BF8D1FB0834EFD100C94B91,
4BF8D1FC0834EFD100C94B91, 4BF8D1FC0834EFD100C94B91,
@@ -2661,6 +2663,27 @@
refType = 2; refType = 2;
sourceTree = SOURCE_ROOT; sourceTree = SOURCE_ROOT;
}; };
4BCD4CF40B00A0F90091F8E8 = {
fileEncoding = 30;
isa = PBXFileReference;
lastKnownFileType = sourcecode.cpp.cpp;
name = JackAPIWrapper.cpp;
path = ../common/JackAPIWrapper.cpp;
refType = 2;
sourceTree = SOURCE_ROOT;
};
4BCD4CF50B00A0F90091F8E8 = {
fileRef = 4BCD4CF40B00A0F90091F8E8;
isa = PBXBuildFile;
settings = {
};
};
4BCD4CF90B00A15B0091F8E8 = {
fileRef = 4BF8D1E90834EF7500C94B91;
isa = PBXBuildFile;
settings = {
};
};
4BD561C708EEB910006BBC2A = { 4BD561C708EEB910006BBC2A = {
fileEncoding = 30; fileEncoding = 30;
isa = PBXFileReference; isa = PBXFileReference;
@@ -4557,12 +4580,6 @@
settings = { settings = {
}; };
}; };
4BF8D1EC0834EF7500C94B91 = {
fileRef = 4BF8D1E90834EF7500C94B91;
isa = PBXBuildFile;
settings = {
};
};
4BF8D1ED0834EF9200C94B91 = { 4BF8D1ED0834EF9200C94B91 = {
fileEncoding = 30; fileEncoding = 30;
isa = PBXFileReference; isa = PBXFileReference;


Loading…
Cancel
Save