traverso-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Traverso-commit] traverso/src engine/AlsaDriver.cpp engine/AlsaD...


From: Remon Sijrier
Subject: [Traverso-commit] traverso/src engine/AlsaDriver.cpp engine/AlsaD...
Date: Tue, 15 Jan 2008 19:51:50 +0000

CVSROOT:        /sources/traverso
Module name:    traverso
Changes by:     Remon Sijrier <r_sijrier>       08/01/15 19:51:50

Modified files:
        src/engine     : AlsaDriver.cpp AlsaDriver.h AudioDevice.cpp 
                         AudioDevice.h memops.cpp memops.h 
        src/traverso/dialogs/settings: Pages.cpp 
        src/traverso   : QuickDriverConfigWidget.cpp Traverso.cpp 
        src/traverso/ui: AlsaDevicesPage.ui 

Log message:
        * merged changes of  new release jack-audio-connection-kit 0.109.0 into 
AlsaDriver.
        * add Dither option to Alsa driver config page (dunno if dither makes 
sense, but well, it's there so why not adding the ability to use it :) )

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/traverso/src/engine/AlsaDriver.cpp?cvsroot=traverso&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/traverso/src/engine/AlsaDriver.h?cvsroot=traverso&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/traverso/src/engine/AudioDevice.cpp?cvsroot=traverso&r1=1.49&r2=1.50
http://cvs.savannah.gnu.org/viewcvs/traverso/src/engine/AudioDevice.h?cvsroot=traverso&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/traverso/src/engine/memops.cpp?cvsroot=traverso&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/traverso/src/engine/memops.h?cvsroot=traverso&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/traverso/src/traverso/dialogs/settings/Pages.cpp?cvsroot=traverso&r1=1.33&r2=1.34
http://cvs.savannah.gnu.org/viewcvs/traverso/src/traverso/QuickDriverConfigWidget.cpp?cvsroot=traverso&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/traverso/src/traverso/Traverso.cpp?cvsroot=traverso&r1=1.53&r2=1.54
http://cvs.savannah.gnu.org/viewcvs/traverso/src/traverso/ui/AlsaDevicesPage.ui?cvsroot=traverso&r1=1.3&r2=1.4

Patches:
Index: engine/AlsaDriver.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/engine/AlsaDriver.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- engine/AlsaDriver.cpp       3 Dec 2007 16:24:20 -0000       1.19
+++ engine/AlsaDriver.cpp       15 Jan 2008 19:51:48 -0000      1.20
@@ -20,9 +20,10 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
 
-$Id: AlsaDriver.cpp,v 1.19 2007/12/03 16:24:20 r_sijrier Exp $
 */
 
+/* ALSA driver based on jack-audio-connection-kit-0.109.0 alsa_driver.c */
+
 
 #include "AlsaDriver.h"
 #include "AudioChannel.h"
@@ -98,7 +99,7 @@
 }
 
 
-int AlsaDriver::setup(bool capture, bool playback, const QString& pcmName)
+int AlsaDriver::setup(bool capture, bool playback, const QString& pcmName, 
const QString& ditherShape)
 {
        unsigned long user_nperiods = 
device->get_driver_property("numberofperiods", 3).toInt();
        char *playback_pcm_name = pcmName.toAscii().data();
@@ -129,9 +130,13 @@
        playback_frame_latency = 0;
        channels_done = 0;
        channels_not_done = 0;
+       dither_state = 0;
 
        playback_addr = 0;
        capture_addr = 0;
+       playback_interleave_skip = NULL;
+       capture_interleave_skip = NULL;
+
 
        playback_hw_params = 0;
        capture_hw_params = 0;
@@ -145,9 +150,20 @@
        playback_nfds = 0;
        capture_nfds = 0;
 
+       if (ditherShape == "Rectangular") {
+               dither = Rectangular;
+       } else if (ditherShape == "Shaped") {
+               dither = Shaped;
+       } else if (ditherShape == "Triangular") {
+               dither = Triangular;
+       } else {
        dither = None;
+       }
+       
        soft_mode = false;
 
+       quirk_bswap = 0;
+
        process_count = 0;
 
        alsa_name_playback = strdup (playback_pcm_name);
@@ -277,7 +293,7 @@
        capture_and_playback_not_synced = false;
 
        if (capture_handle && playback_handle) {
-               if (snd_pcm_link (capture_handle, playback_handle) != 0) {
+               if (snd_pcm_link (playback_handle, capture_handle) != 0) {
                        capture_and_playback_not_synced = true;
                }
        }
@@ -303,15 +319,26 @@
                capture_addr = 0;
        }
 
+       if (playback_interleave_skip) {
+               free (playback_interleave_skip);
+               playback_interleave_skip = NULL;
+       }
+
+       if (capture_interleave_skip) {
+               free (capture_interleave_skip);
+               capture_interleave_skip = NULL;
+       }
+
+
        if (silent) {
                free(silent);
                silent = 0;
        }
 
-       /*      if (dither_state) {
-                       delete dither_state;
+       if (dither_state) {
+               free(dither_state);
                        dither_state = 0;
-               }*/
+       }
 }
 
 
@@ -328,21 +355,28 @@
                switch (dither) {
                case Rectangular:
                        fprintf (stderr,"Rectangular dithering at 16 bits\n");
-                       write_via_copy = sample_move_dither_rect_d16_sS;
+                       write_via_copy = quirk_bswap?
+                               sample_move_dither_rect_d16_sSs:
+                               sample_move_dither_rect_d16_sS;
                        break;
 
                case Triangular:
                        printf("Triangular dithering at 16 bits\n");
-                       write_via_copy = sample_move_dither_tri_d16_sS;
+                       write_via_copy = quirk_bswap?
+                               sample_move_dither_tri_d16_sSs:
+                               sample_move_dither_tri_d16_sS;
                        break;
 
                case Shaped:
                        printf("Noise-shaped dithering at 16 bits\n");
-                       write_via_copy = sample_move_dither_shaped_d16_sS;
+                       write_via_copy = quirk_bswap?
+                               sample_move_dither_shaped_d16_sSs:
+                               sample_move_dither_shaped_d16_sS;
                        break;
 
                default:
-                       write_via_copy = sample_move_d16_sS;
+                       write_via_copy = quirk_bswap?
+                               sample_move_d16_sSs : sample_move_d16_sS;
                        break;
                }
                break;
@@ -357,21 +391,28 @@
                switch (dither) {
                case Rectangular:
                        printf("Rectangular dithering at 24 bits\n");
-                       write_via_copy = sample_move_dither_rect_d24_sS;
+                       write_via_copy = quirk_bswap?
+                               sample_move_dither_rect_d24_sSs:
+                               sample_move_dither_rect_d24_sS;
                        break;
 
                case Triangular:
                        printf("Triangular dithering at 24 bits\n");
-                       write_via_copy = sample_move_dither_tri_d24_sS;
+                       write_via_copy = quirk_bswap?
+                               sample_move_dither_tri_d24_sSs:
+                               sample_move_dither_tri_d24_sS;
                        break;
 
                case Shaped:
                        printf("Noise-shaped dithering at 24 bits\n");
-                       write_via_copy = sample_move_dither_shaped_d24_sS;
+                       write_via_copy = quirk_bswap?
+                               sample_move_dither_shaped_d24_sSs:
+                               sample_move_dither_shaped_d24_sS;
                        break;
 
                default:
-                       write_via_copy = sample_move_d24_sS;
+                       write_via_copy = quirk_bswap?
+                               sample_move_d24_sSs : sample_move_d24_sS;
                        break;
                }
                break;
@@ -386,21 +427,28 @@
                switch (dither) {
                case Rectangular:
                        printf("Rectangular dithering at 32 bits\n");
-                       write_via_copy = sample_move_dither_rect_d32u24_sS;
+                       write_via_copy = quirk_bswap?
+                               sample_move_dither_rect_d32u24_sSs:
+                               sample_move_dither_rect_d32u24_sS;
                        break;
 
                case Triangular:
-                       printf("Triangular dithering at 32 bits\n");
-                       write_via_copy = sample_move_dither_tri_d32u24_sS;
+                       printf("Triangular dithering at 16 bits\n");
+                       write_via_copy = quirk_bswap?
+                               sample_move_dither_tri_d32u24_sSs:
+                               sample_move_dither_tri_d32u24_sS;
                        break;
 
                case Shaped:
                        printf("Noise-shaped dithering at 32 bits\n");
-                       write_via_copy = sample_move_dither_shaped_d32u24_sS;
+                       write_via_copy = quirk_bswap?
+                               sample_move_dither_shaped_d32u24_sSs:
+                               sample_move_dither_shaped_d32u24_sS;
                        break;
 
                default:
-                       write_via_copy = sample_move_d32u24_sS;
+                       write_via_copy = quirk_bswap?
+                               sample_move_d32u24_sSs : sample_move_d32u24_sS;
                        break;
                }
                break;
@@ -408,13 +456,16 @@
 
        switch (capture_sample_bytes) {
        case 2:
-               read_via_copy = sample_move_dS_s16;
+               read_via_copy = quirk_bswap?
+                       sample_move_dS_s16s : sample_move_dS_s16;
                break;
        case 3:
-               read_via_copy = sample_move_dS_s24;
+               read_via_copy = quirk_bswap?
+                       sample_move_dS_s24s : sample_move_dS_s24;
                break;
        case 4:
-               read_via_copy = sample_move_dS_s32u24;
+               read_via_copy = quirk_bswap?
+                       sample_move_dS_s32u24s : sample_move_dS_s32u24;
                break;
        }
 }
@@ -431,16 +482,20 @@
        int err, format;
        snd_pcm_uframes_t stop_th;
        static struct {
-               char Name[16];
+               char Name[32];
                snd_pcm_format_t format;
                int bitdepth;
-       }
-       formats[] = {
-                       {"32bit", SND_PCM_FORMAT_S32, 32},
-                       {"24bit", SND_PCM_FORMAT_S24_3, 24},
-                       {"16bit", SND_PCM_FORMAT_S16, 16},
+               int swapped;
+       } formats[] = {
+               {"32bit little-endian", SND_PCM_FORMAT_S32_LE, IS_LE},
+               {"32bit 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 NOFORMATS (sizeof(formats)/sizeof(formats[0]))
+#define NUMFORMATS (sizeof(formats)/sizeof(formats[0]))
+#define FIRST_16BIT_FORMAT 4
 
        if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0)  {
                PERROR ("ALSA: no playback configurations available (%s)", 
snd_strerror (err));
@@ -453,28 +508,31 @@
        }
 
        if ((err = snd_pcm_hw_params_set_access (handle, hw_params, 
SND_PCM_ACCESS_MMAP_NONINTERLEAVED)) < 0) {
-               if ((err = snd_pcm_hw_params_set_access ( handle, hw_params, 
SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) {
+               if ((err = snd_pcm_hw_params_set_access (handle, hw_params, 
SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) {
+                       if ((err = snd_pcm_hw_params_set_access (handle, 
hw_params, SND_PCM_ACCESS_MMAP_COMPLEX)) < 0) {
                        qDebug ("ALSA: mmap-based access is not possible for 
the %s "
                                "stream of this audio interface", stream_name);
                        return -1;
                }
        }
+       }
 
-       format = (sample_width == 4) ? 0 : (NOFORMATS - 1);
+       format = (sample_width == 4) ? 0 : (NUMFORMATS - 1);
        while (1) {
                if ((err = snd_pcm_hw_params_set_format ( handle, hw_params, 
formats[format].format)) < 0) {
-                       int failed_format = format;
-                       if (( (sample_width == 4) ? (format++ < (int)NOFORMATS 
- 1) : (format-- > 0))) {
-                               fprintf (stderr,"Note: audio device %s doesn't 
support a %s sample format"
-                                       " so Traverso will try a %s format 
instead\n", device_name,
-                                       formats[failed_format].Name,
-                                       formats[format].Name);
-                       } else {
-                               PERROR ("ALSA Driver: Sorry. The audio 
interface \"%s\" doesn't support any of the"
-                                       " hardware sample formats that 
Traverso's alsa-driver can use.", device_name);
+                       
+                       if (( (sample_width == 4) ? (format++ >= 
int(NUMFORMATS) - 1) : (format-- <= 0))) {
+                               printf("ALSA Driver: Sorry. The audio interface 
\"%s\" doesn't support any of the"
+                                       " hardware sample formats that 
Traverso's alsa-driver can use.\n", device_name);
                                return -1;
                        }
                } else {
+                       if (formats[format].swapped) {
+                               quirk_bswap = 1;
+                       } else {
+                               quirk_bswap = 0;
+                       }
+                       printf("ALSA: final selected sample format for %s: 
%s\n", stream_name, formats[format].Name);
                        device->set_bit_depth(formats[format].bitdepth);
                        break;
                }
@@ -533,9 +591,7 @@
        }
 
        if (*nperiodsp < user_nperiods) {
-               PERROR ("ALSA: got smaller periods %u than %u for %s",
-                       *nperiodsp, (unsigned int) user_nperiods,
-                       stream_name);
+               qWarning("ALSA: use %d periods for %s", *nperiodsp, 
stream_name);
                return -1;
        }
 
@@ -626,8 +682,8 @@
        frames_per_cycle = frames_per_interupt;
        user_nperiods = nperiods;
 
-       fprintf (stderr, "configuring for %d Hz, period = %ld frames, buffer = 
%ld periods\n", rate, (long)frames_per_cycle, user_nperiods);
-
+       fprintf (stderr, "configuring for %d Hz, period=%ld frames (%.1f ms), 
buffer=%ld periods\n", 
+                rate, (long)frames_per_cycle,(((float)frames_per_cycle / 
(float) rate) * 1000.0f), user_nperiods);
        if (capture_handle) {
                if (configure_stream (
                                        alsa_name_capture,
@@ -700,7 +756,8 @@
                err = snd_pcm_hw_params_get_period_size (playback_hw_params, 
&p_period_size, &dir);
                err = snd_pcm_hw_params_get_format (playback_hw_params, 
&playback_sample_format);
                err = snd_pcm_hw_params_get_access (playback_hw_params, 
&access);
-               playback_interleaved = (access == 
SND_PCM_ACCESS_MMAP_INTERLEAVED);
+               playback_interleaved = (access == 
SND_PCM_ACCESS_MMAP_INTERLEAVED) 
+                                       || (access == 
SND_PCM_ACCESS_MMAP_COMPLEX);
 
                if (p_period_size != frames_per_cycle) {
                        PERROR ("alsa_pcm: requested an interrupt every %ld 
frames but got %ld frames for playback", (long)frames_per_cycle, p_period_size);
@@ -714,7 +771,8 @@
                err = snd_pcm_hw_params_get_period_size (capture_hw_params, 
&c_period_size, &dir);
                err = snd_pcm_hw_params_get_format (capture_hw_params, 
&(capture_sample_format));
                err = snd_pcm_hw_params_get_access (capture_hw_params, &access);
-               capture_interleaved = (access == 
SND_PCM_ACCESS_MMAP_INTERLEAVED);
+               capture_interleaved = (access == 
SND_PCM_ACCESS_MMAP_INTERLEAVED) 
+                                       || (access == 
SND_PCM_ACCESS_MMAP_COMPLEX);
 
 
                if (c_period_size != frames_per_cycle) {
@@ -729,7 +787,8 @@
        if (playback_handle) {
                switch (playback_sample_format) {
                case SND_PCM_FORMAT_S32_LE:
-               case SND_PCM_FORMAT_S24_3:
+               case SND_PCM_FORMAT_S24_3LE:
+               case SND_PCM_FORMAT_S24_3BE:
                case SND_PCM_FORMAT_S16_LE:
                case SND_PCM_FORMAT_S32_BE:
                case SND_PCM_FORMAT_S16_BE:
@@ -744,7 +803,8 @@
        if (capture_handle) {
                switch (capture_sample_format) {
                case SND_PCM_FORMAT_S32_LE:
-               case SND_PCM_FORMAT_S24_3:
+               case SND_PCM_FORMAT_S24_3LE:
+               case SND_PCM_FORMAT_S24_3BE:
                case SND_PCM_FORMAT_S16_LE:
                case SND_PCM_FORMAT_S32_BE:
                case SND_PCM_FORMAT_S16_BE:
@@ -763,11 +823,10 @@
                        PERROR ("ALSA: %s: mmap areas info error", 
alsa_name_playback);
                        return -1;
                }
-               playback_interleave_skip = my_areas[0].step / 8;
+               
                interleave_unit = 
snd_pcm_format_physical_width(playback_sample_format) / 8;
        } else {
                interleave_unit = 0;  /* NOT USED */
-               playback_interleave_skip = 
snd_pcm_format_physical_width(playback_sample_format) / 8;
        }
 
        if (capture_interleaved) {
@@ -777,9 +836,6 @@
                        PERROR ("ALSA: %s: mmap areas info error", 
alsa_name_capture);
                        return -1;
                }
-               capture_interleave_skip = my_areas[0].step / 8;
-       } else {
-               capture_interleave_skip = 
snd_pcm_format_physical_width(capture_sample_format) / 8;
        }
 
        if (playback_nchannels > capture_nchannels) {
@@ -807,6 +863,8 @@
        if (playback_handle) {
                playback_addr =  (char**) malloc (sizeof (char *) * 
playback_nchannels);
                memset (playback_addr, 0, sizeof (char *) * playback_nchannels);
+               playback_interleave_skip = (unsigned long *) malloc (sizeof 
(unsigned long *) * playback_nchannels);
+               memset (playback_interleave_skip, 0, sizeof (unsigned long *) * 
playback_nchannels);
                silent = (unsigned long *) malloc (sizeof (unsigned long) * 
playback_nchannels);
 
                for (chn = 0; chn < playback_nchannels; chn++) {
@@ -823,6 +881,8 @@
        if (capture_handle) {
                capture_addr = (char **) malloc (sizeof (char *) * 
capture_nchannels);
                memset (capture_addr, 0, sizeof (char *) * capture_nchannels);
+               capture_interleave_skip = (unsigned long *) malloc (sizeof 
(unsigned long *) * capture_nchannels);
+               memset (capture_interleave_skip, 0, sizeof (unsigned long *) * 
capture_nchannels);
        }
 
        period_usecs = (trav_time_t) floor ((((float) frames_per_cycle) / 
frame_rate) * 1000000.0f);
@@ -859,6 +919,7 @@
                for (chn = 0; chn < capture_nchannels; chn++) {
                        const snd_pcm_channel_area_t *a = &capture_areas[chn];
                        capture_addr[chn] = (char *) a->addr + ((a->first + 
a->step * *capture_offset) / 8);
+                       capture_interleave_skip[chn] = (unsigned long ) 
(a->step / 8);
                }
        }
 
@@ -871,6 +932,7 @@
                for (chn = 0; chn < playback_nchannels; chn++) {
                        const snd_pcm_channel_area_t *a = &playback_areas[chn];
                        playback_addr[chn] = (char *) a->addr + ((a->first + 
a->step * *playback_offset) / 8);
+                       playback_interleave_skip[chn] = (unsigned long ) 
(a->step / 8);
                }
        }
 
@@ -1087,9 +1149,10 @@
 
        while (need_playback || need_capture) {
 
-               unsigned int p_timed_out, c_timed_out;
+               int poll_result;
                unsigned int ci = 0;
                unsigned int nfds;
+               unsigned short revents;
 
                nfds = 0;
 
@@ -1130,7 +1193,8 @@
 
                device->transport_cycle_end(poll_enter);
 
-               if (poll (pfd, nfds, poll_timeout) < 0) {
+               poll_result = poll (pfd, nfds, poll_timeout);
+               if (poll_result < 0) {
 
                        if (errno == EINTR) {
                                printf ("poll interrupt\n");
@@ -1185,29 +1249,20 @@
                        return (pfd[nfds-1].revents == POLLIN) ? 0 : -1;
                }
 
-               p_timed_out = 0;
-
                if (need_playback) {
-                       for (i = 0; i < playback_nfds; i++) {
-                               if (pfd[i].revents & POLLERR) {
-                                       PWARN("playback pollerror, 
xrun_detected is true");
-                                       xrun_detected = true;
+                       if (snd_pcm_poll_descriptors_revents(playback_handle, 
&pfd[0], playback_nfds, &revents) < 0) {
+                               qWarning("ALSA: playback revents failed");
+                               *status = -6;
+                               return 0;
                                }
 
-                               if (pfd[i].revents == 0) {
-                                       p_timed_out++;
-#ifdef DEBUG_WAKEUP
-
-                                       fprintf (stderr, "%" PRIu64
-                                               " playback stream timed out\n",
-                                               poll_ret);
-#endif
-
-                               }
+                       if (revents & POLLERR) {
+                               xrun_detected = TRUE;
                        }
 
-                       if (p_timed_out == 0) {
+                       if (revents & POLLOUT) {
                                need_playback = 0;
+
 #ifdef DEBUG_WAKEUP
 
                                fprintf (stderr, "%" PRIu64
@@ -1218,28 +1273,18 @@
                        }
                }
 
-               c_timed_out = 0;
-
                if (need_capture) {
-                       for (i = ci; i < nfds; i++) {
-                               if (pfd[i].revents & POLLERR) {
-                                       PWARN("capture pollerror, xrun_detected 
is true");
-                                       xrun_detected = true;
+                       if (snd_pcm_poll_descriptors_revents(capture_handle, 
&pfd[ci], capture_nfds, &revents) < 0) {
+                               qWarning ("ALSA: capture revents failed");
+                               *status = -6;
+                               return 0;
                                }
 
-                               if (pfd[i].revents == 0) {
-                                       c_timed_out++;
-#ifdef DEBUG_WAKEUP
-
-                                       fprintf (stderr, "%" PRIu64
-                                               " capture stream timed out\n",
-                                               poll_ret);
-#endif
-
-                               }
+                       if (revents & POLLERR) {
+                               xrun_detected = TRUE;
                        }
 
-                       if (c_timed_out == 0) {
+                       if (revents & POLLIN) {
                                need_capture = 0;
 #ifdef DEBUG_WAKEUP
 
@@ -1251,9 +1296,8 @@
                        }
                }
 
-               if ((p_timed_out && (p_timed_out == playback_nfds)) &&
-                               (c_timed_out && (c_timed_out == capture_nfds))) 
{
-                       PERROR ("ALSA: poll time out, polled for %ld usecs", 
(long)(poll_ret - poll_enter));
+               if (poll_result == 0) {
+                       qWarning ("ALSA: poll time out, polled for %ld usecs", 
(long)(poll_ret - poll_enter));
                        *status = -5;
                        return 0;
                }
@@ -1390,14 +1434,14 @@
        audio_sample_t* buf;
        int err;
 
-       if (!capture_handle) {
-               return 0;
-       }
-
        if (nframes > frames_per_cycle) {
                return -1;
        }
 
+       if (!capture_handle) {
+               return 0;
+       }
+
        nread = 0;
        contiguous = 0;
        orig_nframes = nframes;

Index: engine/AlsaDriver.h
===================================================================
RCS file: /sources/traverso/traverso/src/engine/AlsaDriver.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- engine/AlsaDriver.h 27 Feb 2007 19:48:34 -0000      1.6
+++ engine/AlsaDriver.h 15 Jan 2008 19:51:48 -0000      1.7
@@ -20,7 +20,6 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
 
-$Id: AlsaDriver.h,v 1.6 2007/02/27 19:48:34 r_sijrier Exp $
 */
 
 #ifndef ALSADRIVER_H
@@ -36,9 +35,11 @@
 #include "defines.h"
 
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-       #define SND_PCM_FORMAT_S24_3 SND_PCM_FORMAT_S24_3LE
+#define IS_LE 0
+#define IS_BE 1
 #elif __BYTE_ORDER == __BIG_ENDIAN
-       #define SND_PCM_FORMAT_S24_3 SND_PCM_FORMAT_S24_3BE
+#define IS_LE 1
+#define IS_BE 0
 #endif
 
 
@@ -58,7 +59,7 @@
        int detach();
        int bufsize(nframes_t nframes);
        int restart();
-       int setup(bool capture=true, bool playback=true, const QString& 
pcmName="hw:0");
+       int setup(bool capture=true, bool playback=true, const QString& 
pcmName="hw:0", const QString& dither="None");
 
        QString get_device_name();
        QString get_device_longname();
@@ -102,7 +103,7 @@
                        (playback_addr[chn],
                        0, nframes * playback_sample_bytes,
                        interleave_unit,
-                       playback_interleave_skip);
+                       playback_interleave_skip[chn]);
                } else {
                        memset (playback_addr[chn], 0,  nframes * 
playback_sample_bytes);
                }
@@ -116,7 +117,7 @@
                        (playback_addr[chn],
                        0, nframes * playback_sample_bytes,
                        interleave_unit,
-                       playback_interleave_skip);
+                       playback_interleave_skip[chn]);
                } else {
                        memset (playback_addr[chn], 0, nframes * 
playback_sample_bytes);
                }
@@ -124,12 +125,12 @@
 
        inline void read_from_channel (channel_t channel, audio_sample_t *buf, 
nframes_t nsamples)
        {
-               read_via_copy (buf, capture_addr[channel], nsamples, 
capture_interleave_skip);
+               read_via_copy (buf, capture_addr[channel], nsamples, 
capture_interleave_skip[channel]);
        }
 
        inline void write_to_channel (channel_t channel, audio_sample_t *buf, 
nframes_t nsamples)
        {
-               write_via_copy (playback_addr[channel], buf, nsamples, 
playback_interleave_skip, dither_state + channel);
+               write_via_copy (playback_addr[channel], buf, nsamples, 
playback_interleave_skip[channel], dither_state + channel);
                mark_channel_done (channel);
        }
 
@@ -138,8 +139,8 @@
                channel_copy (  playback_addr[output_channel],
                        capture_addr[input_channel],
                        nsamples * playback_sample_bytes,
-                       playback_interleave_skip,
-                       capture_interleave_skip);
+                       playback_interleave_skip[output_channel],
+                       capture_interleave_skip[input_channel]);
                mark_channel_done (output_channel);
        }
 
@@ -174,8 +175,8 @@
        unsigned int                  playback_nfds;
        unsigned int                  capture_nfds;
        unsigned long                 interleave_unit;
-       unsigned long                 capture_interleave_skip;
-       unsigned long                 playback_interleave_skip;
+       unsigned long                *capture_interleave_skip;
+       unsigned long                *playback_interleave_skip;
        channel_t                     max_nchannels;
        channel_t                     user_nchannels;
        channel_t                     playback_nchannels;
@@ -205,10 +206,11 @@
        snd_pcm_hw_params_t          *capture_hw_params;
        snd_pcm_sw_params_t          *capture_sw_params;
 
-       bool soft_mode;
-       bool capture_and_playback_not_synced;
-       bool playback_interleaved;
-       bool capture_interleaved;
+       char soft_mode;
+       char capture_and_playback_not_synced;
+       char playback_interleaved;
+       char capture_interleaved;
+       char quirk_bswap;
 
        ReadCopyFunction read_via_copy;
        WriteCopyFunction write_via_copy;

Index: engine/AudioDevice.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/engine/AudioDevice.cpp,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -b -r1.49 -r1.50
--- engine/AudioDevice.cpp      7 Dec 2007 11:22:32 -0000       1.49
+++ engine/AudioDevice.cpp      15 Jan 2008 19:51:48 -0000      1.50
@@ -17,7 +17,7 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
 
-$Id: AudioDevice.cpp,v 1.49 2007/12/07 11:22:32 r_sijrier Exp $
+$Id: AudioDevice.cpp,v 1.50 2008/01/15 19:51:48 r_sijrier Exp $
 */
 
 #include "AudioDevice.h"
@@ -41,7 +41,6 @@
 #include "AudioChannel.h"
 #include "AudioBus.h"
 #include "Tsar.h"
-
 //#include <sys/mman.h>
 
 // Always put me below _all_ includes, this is needed
@@ -320,13 +319,15 @@
                                const QString& driverType,
                                bool capture,
                                bool playback,
-                               const QString& cardDevice)
+                               const QString& cardDevice,
+                               const QString& ditherShape)
 {
        PENTER;
 
        m_rate = rate;
        m_bufferSize = bufferSize;
        m_xrunCount = 0;
+       m_ditherShape = ditherShape;
 
        shutdown();
 
@@ -421,7 +422,7 @@
 #if defined (ALSA_SUPPORT)
        if (driverType == "ALSA") {
                driver =  new AlsaDriver(this, m_rate, m_bufferSize);
-               if (driver->setup(capture,playback, cardDevice) < 0) {
+               if (((AlsaDriver*)driver)->setup(capture,playback, cardDevice, 
m_ditherShape) < 0) {
                        message(tr("Audiodevice: Failed to create the ALSA 
Driver"), WARNING);
                        delete driver;
                        driver = 0;

Index: engine/AudioDevice.h
===================================================================
RCS file: /sources/traverso/traverso/src/engine/AudioDevice.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- engine/AudioDevice.h        7 Dec 2007 11:22:32 -0000       1.27
+++ engine/AudioDevice.h        15 Jan 2008 19:51:49 -0000      1.28
@@ -17,7 +17,7 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
 
-$Id: AudioDevice.h,v 1.27 2007/12/07 11:22:32 r_sijrier Exp $
+$Id: AudioDevice.h,v 1.28 2008/01/15 19:51:49 r_sijrier Exp $
 */
 
 #ifndef AUDIODEVICE_H
@@ -56,7 +56,8 @@
                                const QString& driverType, 
                                bool capture=true,
                                bool playback=true,
-                               const QString& device="hw:0" );
+                               const QString& device="hw:0",
+                               const QString& ditherShape="None");
 
        void add_client(Client* client);
        void remove_client(Client* client);
@@ -167,6 +168,7 @@
        uint                    m_bitdepth;
        uint                    m_xrunCount;
        QString                 m_driverType;
+       QString                 m_ditherShape;
        QHash<QString, QVariant> m_driverProperties;
 
        int run_one_cycle(nframes_t nframes, float delayed_usecs);

Index: engine/memops.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/engine/memops.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- engine/memops.cpp   20 Apr 2006 14:50:44 -0000      1.1
+++ engine/memops.cpp   15 Jan 2008 19:51:49 -0000      1.2
@@ -15,7 +15,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
 
-    $Id: memops.cpp,v 1.1 2006/04/20 14:50:44 r_sijrier Exp $
+    $Id: memops.cpp,v 1.2 2008/01/15 19:51:49 r_sijrier Exp $
 */
 
 #define _ISOC9X_SOURCE  1
@@ -46,6 +46,38 @@
        return seed;
 } 
 
+void sample_move_d32u24_sSs (char *dst, 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, audio_sample_t *src, unsigned long 
nsamples, unsigned long dst_skip, dither_state_t*)
 
 {
@@ -130,6 +162,35 @@
        state->rm1 = rm1;
 }
 
+void sample_move_dS_s32u24s (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_dither_shaped_d32u24_sS (char *dst,  audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
        
 {
@@ -178,6 +239,145 @@
        state->idx = idx;
 }
 
+void sample_move_dither_rect_d32u24_sSs (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
+
+{
+       /* ALERT: signed sign-extension portability !!! */
+       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_tri_d32u24_sSs (char *dst,  audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
+       
+{
+       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_shaped_d32u24_sSs (char *dst,  audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
+       
+{
+       audio_sample_t     x;
+       audio_sample_t     xe; /* the innput sample - filtered error */
+       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_d24_sS (char *dst, audio_sample_t *src, unsigned long 
nsamples, unsigned long dst_skip, dither_state_t *)
 
 {
@@ -201,6 +401,36 @@
        }
 }      
 
+void sample_move_d24_sSs (char *dst, 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_dS_s24 (audio_sample_t *dst, char *src, unsigned long 
nsamples, unsigned long src_skip)
 {
        /* ALERT: signed sign-extension portability !!! */
@@ -249,6 +479,117 @@
        }
 }      
 
+void sample_move_dS_s24s (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_dither_rect_d24_sSs (char *dst, audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t *state)
+
+{
+       /* ALERT: signed sign-extension portability !!! */
+       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_tri_d24_sSs (char *dst,  audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t *state)
+       
+{
+       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,  audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t *state)
        
 {
@@ -335,6 +676,64 @@
        state->idx = idx;
 }
 
+void sample_move_dither_shaped_d24_sSs (char *dst,  audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
+       
+{
+       audio_sample_t     x;
+       audio_sample_t     xe; /* the innput sample - filtered error */
+       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_d16_sS (char *dst,  audio_sample_t *src, unsigned long 
nsamples, unsigned long dst_skip, dither_state_t* )
        
 {
@@ -356,6 +755,33 @@
        }
 }
 
+void sample_move_dither_rect_d16_sSs (char *dst,  audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
+       
+{
+       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,  audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t* )
        
 {
@@ -378,6 +804,39 @@
        }
 }
 
+void sample_move_dither_tri_d16_sSs (char *dst,  audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t *state)
+       
+{
+       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,  audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t *state)
        
 {
@@ -407,6 +866,105 @@
        state->rm1 = rm1;
 }
 
+void sample_move_dither_shaped_d16_sSs (char *dst,  audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
+       
+{
+       audio_sample_t     x;
+       audio_sample_t     xe; /* the innput sample - filtered error */
+       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_dS_s16s (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_d16_sSs (char *dst,  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_dither_shaped_d16_sS (char *dst,  audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
        
 {

Index: engine/memops.h
===================================================================
RCS file: /sources/traverso/traverso/src/engine/memops.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- engine/memops.h     20 Apr 2006 14:50:44 -0000      1.1
+++ engine/memops.h     15 Jan 2008 19:51:49 -0000      1.2
@@ -15,7 +15,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
 
-    $Id: memops.h,v 1.1 2006/04/20 14:50:44 r_sijrier Exp $
+    $Id: memops.h,v 1.2 2008/01/15 19:51:49 r_sijrier Exp $
 */
 
 #ifndef __jack_memops_h__
@@ -42,23 +42,38 @@
 } dither_state_t;
 
 
+void sample_move_d32u24_sSs          (char *dst, audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_move_d32u24_sS           (char *dst, audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_move_d24_sS              (char *dst, audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t *state);
+void sample_move_d24_sSs             (char *dst, audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_move_d16_sS              (char *dst, audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t *state);
+void sample_move_d16_sSs             (char *dst, audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t *state);
 
+void sample_move_dither_rect_d32u24_sSs   (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_move_dither_rect_d32u24_sS   (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
+void sample_move_dither_tri_d32u24_sSs    (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_move_dither_tri_d32u24_sS    (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
+void sample_move_dither_shaped_d32u24_sSs (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_move_dither_shaped_d32u24_sS (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_move_dither_rect_d24_sS      (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
+void sample_move_dither_rect_d24_sSs     (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_move_dither_tri_d24_sS       (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
+void sample_move_dither_tri_d24_sSs      (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
+void sample_move_dither_shaped_d24_sSs   (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_move_dither_shaped_d24_sS    (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_move_dither_rect_d16_sS      (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
+void sample_move_dither_rect_d16_sSs     (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_move_dither_tri_d16_sS       (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
+void sample_move_dither_tri_d16_sSs      (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_move_dither_shaped_d16_sS    (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
+void sample_move_dither_shaped_d16_sSs   (char *dst, audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
 
+void sample_move_dS_s32u24s          (audio_sample_t *dst, char *src, unsigned 
long nsamples, unsigned long src_skip);
 void sample_move_dS_s32u24           (audio_sample_t *dst, char *src, unsigned 
long nsamples, unsigned long src_skip);
 void sample_move_dS_s24              (audio_sample_t *dst, char *src, unsigned 
long nsamples, unsigned long src_skip);
+void sample_move_dS_s24s             (audio_sample_t *dst, char *src, unsigned 
long nsamples, unsigned long src_skip);
 void sample_move_dS_s16              (audio_sample_t *dst, char *src, unsigned 
long nsamples, unsigned long src_skip);
+void sample_move_dS_s16s             (audio_sample_t *dst, char *src, unsigned 
long nsamples, unsigned long src_skip);
 
 void sample_merge_d16_sS             (char *dst,  audio_sample_t *src, 
unsigned long nsamples, unsigned long dst_skip, dither_state_t *state);
 void sample_merge_d32u24_sS          (char *dst, audio_sample_t *src, unsigned 
long nsamples, unsigned long dst_skip, dither_state_t *state);

Index: traverso/dialogs/settings/Pages.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/traverso/dialogs/settings/Pages.cpp,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -b -r1.33 -r1.34
--- traverso/dialogs/settings/Pages.cpp 7 Jan 2008 18:11:31 -0000       1.33
+++ traverso/dialogs/settings/Pages.cpp 15 Jan 2008 19:51:49 -0000      1.34
@@ -137,6 +137,7 @@
        config().set_property("Hardware", "numberofperiods", periods);
        int index = m_alsadevices->devicesCombo->currentIndex();
        config().set_property("Hardware", "carddevice", 
m_alsadevices->devicesCombo->itemData(index));
+       config().set_property("Hardware", "DitherShape", 
m_alsadevices->ditherShapeComboBox->currentText());
        
 #endif
 
@@ -157,6 +158,7 @@
        config().set_property("Hardware", "drivertype", "ALSA");
        config().set_property("Hardware", "carddevice", "hw:0");
        config().set_property("Hardware", "numberofperiods", 3);
+       config().set_property("Hardware", "DitherShape", "None");
 #elif defined (JACK_SUPPORT)
        if (libjack_is_present)
                config().set_property("Hardware", "drivertype", "Jack");
@@ -224,8 +226,14 @@
 #if defined (ALSA_SUPPORT)
        m_alsadevices->devicesCombo->clear();
        int periodsIndex = config().get_property("Hardware", "numberofperiods", 
3).toInt();
+       QString ditherShape = config().get_property("Hardware", "DitherShape", 
"None").toString();
        m_alsadevices->periodsCombo->setCurrentIndex(periodsIndex - 2);
        
+       int shapeIndex = 
m_alsadevices->ditherShapeComboBox->findText(ditherShape);
+       if (shapeIndex >=0) {
+               m_alsadevices->ditherShapeComboBox->setCurrentIndex(shapeIndex);
+       }
+       
        QString name;
        for (int i=0; i<6; ++i) {
                name = AlsaDriver::alsa_device_name(false, i);
@@ -299,11 +307,12 @@
        
 
        QString cardDevice = "";
+       QString dithershape = "None";
 
 
 #if defined (ALSA_SUPPORT)
        int periods = m_alsadevices->periodsCombo->currentText().toInt();
-       
+       dithershape = m_alsadevices->ditherShapeComboBox->currentText();
        // The AlsaDriver retrieves it's periods number directly from config()
        // So there is no way to use the current selected one, other then
        // setting it now, and restoring it afterwards...
@@ -323,7 +332,7 @@
        }
 #endif
                        
-       audiodevice().set_parameters(rate, buffersize, driver, capture, 
playback, cardDevice);
+       audiodevice().set_parameters(rate, buffersize, driver, capture, 
playback, cardDevice, dithershape);
        
 #if defined (ALSA_SUPPORT)
        config().set_property("Hardware", "numberofperiods", currentperiods);

Index: traverso/QuickDriverConfigWidget.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/traverso/QuickDriverConfigWidget.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- traverso/QuickDriverConfigWidget.cpp        5 Nov 2007 15:49:31 -0000       
1.11
+++ traverso/QuickDriverConfigWidget.cpp        15 Jan 2008 19:51:49 -0000      
1.12
@@ -17,7 +17,7 @@
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
 
-$Id: QuickDriverConfigWidget.cpp,v 1.11 2007/11/05 15:49:31 r_sijrier Exp $
+$Id: QuickDriverConfigWidget.cpp,v 1.12 2008/01/15 19:51:49 r_sijrier Exp $
 */
 
 #include "QuickDriverConfigWidget.h"
@@ -69,6 +69,7 @@
        bool capture = config().get_property("Hardware", "capture", 1).toInt();
        bool playback = config().get_property("Hardware", "playback", 
1).toInt();
        QString cardDevice = "";
+       QString ditherShape = config().get_property("Hardware", "DitherShape", 
"None").toString();
        
 #if defined (ALSA_SUPPORT)
        if (driver == "ALSA") {
@@ -89,7 +90,7 @@
 #endif // end PORTAUDIO_SUPPORT
        
        
-       audiodevice().set_parameters(rate, bufSize, driver, capture, playback, 
cardDevice);
+       audiodevice().set_parameters(rate, bufSize, driver, capture, playback, 
cardDevice, ditherShape);
 
        config().set_property("Hardware", "samplerate", 
rateComboBox->currentText().toInt());
        config().set_property("Hardware", "buffersize", 
periodBufferSizesList.at(latencyComboBox->currentIndex()));

Index: traverso/Traverso.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/traverso/Traverso.cpp,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -b -r1.53 -r1.54
--- traverso/Traverso.cpp       3 Dec 2007 16:27:31 -0000       1.53
+++ traverso/Traverso.cpp       15 Jan 2008 19:51:49 -0000      1.54
@@ -314,6 +314,7 @@
        QString driverType = config().get_property("Hardware", "drivertype", 
"PortAudio").toString();
 #endif
        QString cardDevice = config().get_property("Hardware", "carddevice", 
"hw:0").toString();
+       QString ditherShape = config().get_property("Hardware", "DitherShape", 
"None").toString();
        bool capture = config().get_property("Hardware", "capture", 1).toInt();
        bool playback = config().get_property("Hardware", "playback", 
1).toInt();
 
@@ -348,7 +349,7 @@
        }
 #endif // end PORTAUDIO_SUPPORT
        
-       audiodevice().set_parameters(rate, bufferSize, driverType, capture, 
playback, cardDevice);
+       audiodevice().set_parameters(rate, bufferSize, driverType, capture, 
playback, cardDevice, ditherShape);
 }
 
 void Traverso::saveState( QSessionManager &  manager)

Index: traverso/ui/AlsaDevicesPage.ui
===================================================================
RCS file: /sources/traverso/traverso/src/traverso/ui/AlsaDevicesPage.ui,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- traverso/ui/AlsaDevicesPage.ui      8 May 2007 11:26:15 -0000       1.3
+++ traverso/ui/AlsaDevicesPage.ui      15 Jan 2008 19:51:50 -0000      1.4
@@ -6,7 +6,7 @@
     <x>0</x>
     <y>0</y>
     <width>356</width>
-    <height>93</height>
+    <height>123</height>
    </rect>
   </property>
   <property name="windowTitle" >
@@ -29,7 +29,7 @@
        <number>9</number>
       </property>
       <property name="spacing" >
-       <number>9</number>
+       <number>6</number>
       </property>
       <item>
        <layout class="QHBoxLayout" >
@@ -116,6 +116,55 @@
         </item>
        </layout>
       </item>
+      <item>
+       <layout class="QHBoxLayout" >
+        <property name="margin" >
+         <number>0</number>
+        </property>
+        <property name="spacing" >
+         <number>6</number>
+        </property>
+        <item>
+         <widget class="QLabel" name="label_3" >
+          <property name="toolTip" >
+           <string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" 
/>&lt;style type="text/css">
+p, li { white-space: pre-wrap; }
+&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; 
font-weight:400; font-style:normal; text-decoration:none;">
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; 
margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dither is used to make 
the audio cleaner. &lt;/p>
+&lt;p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; 
margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;/p>
+&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; 
margin-right:0px; -qt-block-indent:0; text-indent:0px;">The best way to 
describe it is to imagine a painting with many dots. If you view it up close 
you can see each dot and the image is not very clear. If you view it from far 
away the image becomes clearer because your eyes/brain dither the dots to 
smooth out the image. It is a murky subject and obviously a very personal 
choice as to what dither is the best. For most people it is just plain magic. 
Anyone running at 16bit who cares about quality or has CPU cycles to spare 
should run with dither. Triangular is probably the best compromise of quality 
vs cpu cost (its very fast), but shaped is the 
best&lt;/p>&lt;/body>&lt;/html></string>
+          </property>
+          <property name="text" >
+           <string>Dither</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QComboBox" name="ditherShapeComboBox" >
+          <item>
+           <property name="text" >
+            <string>None</string>
+           </property>
+          </item>
+          <item>
+           <property name="text" >
+            <string>Shaped</string>
+           </property>
+          </item>
+          <item>
+           <property name="text" >
+            <string>Rectangular</string>
+           </property>
+          </item>
+          <item>
+           <property name="text" >
+            <string>Triangular</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+       </layout>
+      </item>
      </layout>
     </widget>
    </item>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]