patch: (well, sort of) Native 32 bit float (LE) support

View: New views
1 Messages — Rating Filter:   Alert me  

patch: (well, sort of) Native 32 bit float (LE) support

by Florian Faber-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

attached is a patch against the alsa directory of jack1. It adds native
32 bit float (LE only) support to jack's alsa driver, thus saving the
float conversion and one division/multiplication for each sample.

Since it's only a couple of lines (mostly indentation), it shouldn't be
a problem integrating it into jack2..

It's tested with the new hdspm driver. The HDSPe line has native 32 bit
(LE) float support for coreaudio - and now for jack :)


Flo
--
Machines can do the work, so people have time to think.
public key 6C002249          x-hkp://wwwkeys.eu.pgp.net

[jack_float.diff]

diff -rupN /usr/portage/distfiles/svn-src/jack-audio-connection-kit/jack/drivers/alsa/alsa_driver.c alsa/alsa_driver.c
--- /usr/portage/distfiles/svn-src/jack-audio-connection-kit/jack/drivers/alsa/alsa_driver.c 2008-06-18 20:26:38.000000000 +0200
+++ alsa/alsa_driver.c 2008-07-22 17:38:00.000000000 +0200
@@ -233,129 +233,139 @@ alsa_driver_hw_specific (alsa_driver_t *
 static void
 alsa_driver_setup_io_function_pointers (alsa_driver_t *driver)
 {
- switch (driver->playback_sample_bytes) {
- case 2:
- if (driver->playback_interleaved) {
- driver->channel_copy = memcpy_interleave_d16_s16;
+  if (SNDRV_PCM_FORMAT_FLOAT_LE == driver->playback_sample_format) {
+  if (driver->playback_interleaved) {
+  driver->channel_copy = memcpy_interleave_d32_s32;
  } else {
  driver->channel_copy = memcpy_fake;
  }
-
- switch (driver->dither) {
+ driver->read_via_copy = sample_move_floatLE_sSs;
+ driver->write_via_copy = sample_move_dS_floatLE;
+  } else {
+ switch (driver->playback_sample_bytes) {
+ case 2:
+    if (driver->playback_interleaved) {
+ driver->channel_copy = memcpy_interleave_d16_s16;
+ } else {
+ driver->channel_copy = memcpy_fake;
+ }
+
+ switch (driver->dither) {
  case Rectangular:
- jack_info("Rectangular dithering at 16 bits");
- driver->write_via_copy = driver->quirk_bswap?
- sample_move_dither_rect_d16_sSs:
- sample_move_dither_rect_d16_sS;
- break;
-
- case Triangular:
- jack_info("Triangular dithering at 16 bits");
- driver->write_via_copy = driver->quirk_bswap?
- sample_move_dither_tri_d16_sSs:
- sample_move_dither_tri_d16_sS;
- break;
-
+  jack_info("Rectangular dithering at 16 bits");
+ driver->write_via_copy = driver->quirk_bswap?
+ sample_move_dither_rect_d16_sSs:
+ sample_move_dither_rect_d16_sS;
+ break;
+
+  case Triangular:
+ jack_info("Triangular dithering at 16 bits");
+ driver->write_via_copy = driver->quirk_bswap?
+ sample_move_dither_tri_d16_sSs:
+ sample_move_dither_tri_d16_sS;
+ break;
+
  case Shaped:
- jack_info("Noise-shaped dithering at 16 bits");
- driver->write_via_copy = driver->quirk_bswap?
- sample_move_dither_shaped_d16_sSs:
- sample_move_dither_shaped_d16_sS;
- break;
-
+ jack_info("Noise-shaped dithering at 16 bits");
+  driver->write_via_copy = driver->quirk_bswap?
+ sample_move_dither_shaped_d16_sSs:
+ sample_move_dither_shaped_d16_sS;
+ break;
+
  default:
- driver->write_via_copy = driver->quirk_bswap?
- sample_move_d16_sSs : sample_move_d16_sS;
- break;
- }
- break;
-
- case 3:
- if (driver->playback_interleaved) {
- driver->channel_copy = memcpy_interleave_d24_s24;
- } else {
- driver->channel_copy = memcpy_fake;
- }
-
- switch (driver->dither) {
+ driver->write_via_copy = driver->quirk_bswap?
+ sample_move_d16_sSs : sample_move_d16_sS;
+ break;
+ }
+  break;
+
+ case 3:
+ if (driver->playback_interleaved) {
+ driver->channel_copy = memcpy_interleave_d24_s24;
+  } else {
+ driver->channel_copy = memcpy_fake;
+ }
+
+ switch (driver->dither) {
  case Rectangular:
- jack_info("Rectangular dithering at 16 bits");
- driver->write_via_copy = driver->quirk_bswap?
- sample_move_dither_rect_d24_sSs:
- sample_move_dither_rect_d24_sS;
- break;
-
+ jack_info("Rectangular dithering at 16 bits");
+ driver->write_via_copy = driver->quirk_bswap?
+    sample_move_dither_rect_d24_sSs:
+ sample_move_dither_rect_d24_sS;
+ break;
+
  case Triangular:
- jack_info("Triangular dithering at 16 bits");
- driver->write_via_copy = driver->quirk_bswap?
- sample_move_dither_tri_d24_sSs:
- sample_move_dither_tri_d24_sS;
- break;
-
+ jack_info("Triangular dithering at 16 bits");
+ driver->write_via_copy = driver->quirk_bswap?
+ sample_move_dither_tri_d24_sSs:
+ sample_move_dither_tri_d24_sS;
+ break;
+
  case Shaped:
- jack_info("Noise-shaped dithering at 16 bits");
- driver->write_via_copy = driver->quirk_bswap?
- sample_move_dither_shaped_d24_sSs:
- sample_move_dither_shaped_d24_sS;
- break;
-
+ jack_info("Noise-shaped dithering at 16 bits");
+  driver->write_via_copy = driver->quirk_bswap?
+ sample_move_dither_shaped_d24_sSs:
+ sample_move_dither_shaped_d24_sS;
+ break;
+
  default:
- driver->write_via_copy = driver->quirk_bswap?
- sample_move_d24_sSs : sample_move_d24_sS;
+ driver->write_via_copy = driver->quirk_bswap?
+ sample_move_d24_sSs : sample_move_d24_sS;
+ break;
+  }
  break;
- }
- break;
-
- case 4:
- if (driver->playback_interleaved) {
- driver->channel_copy = memcpy_interleave_d32_s32;
- } else {
- driver->channel_copy = memcpy_fake;
- }
-
- switch (driver->dither) {
+
+ case 4:
+ if (driver->playback_interleaved) {
+ driver->channel_copy = memcpy_interleave_d32_s32;
+ } else {
+ driver->channel_copy = memcpy_fake;
+ }
+
+  switch (driver->dither) {
  case Rectangular:
- jack_info("Rectangular dithering at 16 bits");
- driver->write_via_copy = driver->quirk_bswap?
- sample_move_dither_rect_d32u24_sSs:
- sample_move_dither_rect_d32u24_sS;
- break;
-
+ jack_info("Rectangular dithering at 16 bits");
+ driver->write_via_copy = driver->quirk_bswap?
+ sample_move_dither_rect_d32u24_sSs:
+ sample_move_dither_rect_d32u24_sS;
+ break;
+
  case Triangular:
- jack_info("Triangular dithering at 16 bits");
- driver->write_via_copy = driver->quirk_bswap?
- sample_move_dither_tri_d32u24_sSs:
- sample_move_dither_tri_d32u24_sS;
- break;
-
+ jack_info("Triangular dithering at 16 bits");
+ driver->write_via_copy = driver->quirk_bswap?
+ sample_move_dither_tri_d32u24_sSs:
+ sample_move_dither_tri_d32u24_sS;
+ break;
+
  case Shaped:
- jack_info("Noise-shaped dithering at 16 bits");
- driver->write_via_copy = driver->quirk_bswap?
- sample_move_dither_shaped_d32u24_sSs:
- sample_move_dither_shaped_d32u24_sS;
- break;
-
+ jack_info("Noise-shaped dithering at 16 bits");
+ driver->write_via_copy = driver->quirk_bswap?
+ sample_move_dither_shaped_d32u24_sSs:
+ sample_move_dither_shaped_d32u24_sS;
+ break;
+
  default:
- driver->write_via_copy = driver->quirk_bswap?
- sample_move_d32u24_sSs : sample_move_d32u24_sS;
- break;
- }
- break;
- }
-
- switch (driver->capture_sample_bytes) {
- case 2:
- driver->read_via_copy = driver->quirk_bswap?
- sample_move_dS_s16s : sample_move_dS_s16;
- break;
- case 3:
- driver->read_via_copy = driver->quirk_bswap?
- sample_move_dS_s24s : sample_move_dS_s24;
- break;
- case 4:
- driver->read_via_copy = driver->quirk_bswap?
- sample_move_dS_s32u24s : sample_move_dS_s32u24;
+ driver->write_via_copy = driver->quirk_bswap?
+ sample_move_d32u24_sSs : sample_move_d32u24_sS;
+    break;
+  }
+  break;
+  }
+
+  switch (driver->capture_sample_bytes) {
+  case 2:
+ driver->read_via_copy = driver->quirk_bswap?
+          sample_move_dS_s16s : sample_move_dS_s16;
+ break;
+ case 3:
+ driver->read_via_copy = driver->quirk_bswap?
+ sample_move_dS_s24s : sample_move_dS_s24;
+ break;
+ case 4:
+ driver->read_via_copy = driver->quirk_bswap?
+ sample_move_dS_s32u24s : sample_move_dS_s32u24;
  break;
+ }
  }
 }
 
@@ -377,15 +387,16 @@ alsa_driver_configure_stream (alsa_drive
  snd_pcm_format_t format;
  int swapped;
  } formats[] = {
- {"32bit little-endian", SND_PCM_FORMAT_S32_LE, IS_LE},
- {"32bit big-endian", SND_PCM_FORMAT_S32_BE, IS_BE},
+  {"32bit float little-endian", SND_PCM_FORMAT_FLOAT_LE},
+ {"32bit integer little-endian", SND_PCM_FORMAT_S32_LE, IS_LE},
+ {"32bit integer big-endian", SND_PCM_FORMAT_S32_BE, IS_BE},
  {"24bit little-endian", SND_PCM_FORMAT_S24_3LE, IS_LE},
  {"24bit big-endian", SND_PCM_FORMAT_S24_3BE, IS_BE},
  {"16bit little-endian", SND_PCM_FORMAT_S16_LE, IS_LE},
  {"16bit big-endian", SND_PCM_FORMAT_S16_BE, IS_BE},
  };
 #define NUMFORMATS (sizeof(formats)/sizeof(formats[0]))
-#define FIRST_16BIT_FORMAT 4
+#define FIRST_16BIT_FORMAT 5
 
  if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0)  {
  jack_error ("ALSA: no playback configurations available (%s)",
@@ -759,6 +770,7 @@ alsa_driver_set_parameters (alsa_driver_
 
  if (driver->playback_handle) {
  switch (driver->playback_sample_format) {
+   case SND_PCM_FORMAT_FLOAT_LE:
  case SND_PCM_FORMAT_S32_LE:
  case SND_PCM_FORMAT_S24_3LE:
  case SND_PCM_FORMAT_S24_3BE:
@@ -776,6 +788,7 @@ alsa_driver_set_parameters (alsa_driver_
 
  if (driver->capture_handle) {
  switch (driver->capture_sample_format) {
+   case SND_PCM_FORMAT_FLOAT_LE:
  case SND_PCM_FORMAT_S32_LE:
  case SND_PCM_FORMAT_S24_3LE:
  case SND_PCM_FORMAT_S24_3BE:
diff -rupN /usr/portage/distfiles/svn-src/jack-audio-connection-kit/jack/drivers/alsa/alsa_driver.h alsa/alsa_driver.h
--- /usr/portage/distfiles/svn-src/jack-audio-connection-kit/jack/drivers/alsa/memops.c 2008-06-18 20:26:38.000000000 +0200
+++ alsa/memops.c 2008-07-22 17:25:28.000000000 +0200
@@ -49,6 +49,29 @@ inline unsigned int fast_rand() {
  return seed;
 }
 
+
+/* functions for native float sample data */
+
+void sample_move_floatLE_sSs (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) {
+ while (nsamples--) {
+ *dst = *((float *) src);
+ dst++;
+ src += src_skip;
+ }
+}
+
+void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) {
+ while (nsamples--) {
+ *((float *) dst) = *src;
+ dst += dst_skip;
+ src++;
+ }
+}
+
+
+
+/* functions for native integer sample data */
+
 void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
 
 {
@@ -1201,3 +1225,4 @@ memcpy_interleave_d32_s32 (char *dst, ch
  src_bytes -= 4;
  }
 }
+
diff -rupN /usr/portage/distfiles/svn-src/jack-audio-connection-kit/jack/drivers/alsa/memops.h alsa/memops.h
--- /usr/portage/distfiles/svn-src/jack-audio-connection-kit/jack/drivers/alsa/memops.h 2008-06-18 20:26:38.000000000 +0200
+++ alsa/memops.h 2008-07-22 15:45:58.000000000 +0200
@@ -39,7 +39,11 @@ typedef struct {
     float e[DITHER_BUF_SIZE];
 } dither_state_t;
 
+/* float functions */
+void sample_move_floatLE_sSs (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long dst_skip);
+void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
 
+/* integer functions */
 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);


_______________________________________________
Jack-Devel mailing list
Jack-Devel@...
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
LightInTheBox - Buy quality products at wholesale price