]> git.alsa-project.org Git - alsa-lib.git/commitdiff
dmix: simplify mix_areas()
authorClemens Ladisch <clemens@ladisch.de>
Mon, 10 Dec 2007 11:32:36 +0000 (12:32 +0100)
committerClemens Ladisch <clemens@ladisch.de>
Mon, 10 Dec 2007 11:32:36 +0000 (12:32 +0100)
The code for the three supported sample widths is almost the same, so it
makes sense to merge the three cases.

src/pcm/pcm_direct.h
src/pcm/pcm_dmix.c

index 887612e8c455e842896b42ca99618b36c40193f6..a96fb4e65a98eff20503e67c1b38c6c59657638f 100644 (file)
 #define DIRECT_IPC_SEMS         1
 #define DIRECT_IPC_SEM_CLIENT   0
 
+typedef void (mix_areas_t)(unsigned int size,
+                          volatile void *dst, void *src,
+                          volatile signed int *sum, size_t dst_step,
+                          size_t src_step, size_t sum_step);
+
 typedef void (mix_areas_16_t)(unsigned int size,
                              volatile signed short *dst, signed short *src,
                              volatile signed int *sum, size_t dst_step,
index 28d616918f0191a8f74279dcb6c37811cd2fe711..b2c200d5758b8e6c248626b2a982f5c1d3699ae3 100644 (file)
@@ -156,95 +156,56 @@ static void mix_areas(snd_pcm_direct_t *dmix,
                      snd_pcm_uframes_t dst_ofs,
                      snd_pcm_uframes_t size)
 {
-       volatile signed int *sum;
        unsigned int src_step, dst_step;
-       unsigned int chn, dchn, channels;
+       unsigned int chn, dchn, channels, sample_size;
+       mix_areas_t *do_mix_areas;
        
        channels = dmix->channels;
-       if (dmix->shmptr->s.format == SND_PCM_FORMAT_S16_LE ||
-           dmix->shmptr->s.format == SND_PCM_FORMAT_S16_BE) {
-               signed short *src;
-               volatile signed short *dst;
-               if (dmix->interleaved) {
-                       /*
-                        * process all areas in one loop
-                        * it optimizes the memory accesses for this case
-                        */
-                       dmix->u.dmix.mix_areas_16(size * channels,
-                                                 ((signed short *)dst_areas[0].addr) + (dst_ofs * channels),
-                                                 ((signed short *)src_areas[0].addr) + (src_ofs * channels),
-                                                 dmix->u.dmix.sum_buffer + (dst_ofs * channels),
-                                                 sizeof(signed short),
-                                                 sizeof(signed short),
-                                                 sizeof(signed int));
-                       return;
-               }
-               for (chn = 0; chn < channels; chn++) {
-                       dchn = dmix->bindings ? dmix->bindings[chn] : chn;
-                       if (dchn >= dmix->shmptr->s.channels)
-                               continue;
-                       src_step = src_areas[chn].step / 8;
-                       dst_step = dst_areas[dchn].step / 8;
-                       src = (signed short *)(((char *)src_areas[chn].addr + src_areas[chn].first / 8) + (src_ofs * src_step));
-                       dst = (signed short *)(((char *)dst_areas[dchn].addr + dst_areas[dchn].first / 8) + (dst_ofs * dst_step));
-                       sum = dmix->u.dmix.sum_buffer + channels * dst_ofs + chn;
-                       dmix->u.dmix.mix_areas_16(size, dst, src, sum, dst_step, src_step, channels * sizeof(signed int));
-               }
-       } else if (dmix->shmptr->s.format == SND_PCM_FORMAT_S32_LE ||
-                  dmix->shmptr->s.format == SND_PCM_FORMAT_S32_BE) {
-               signed int *src;
-               volatile signed int *dst;
-               if (dmix->interleaved) {
-                       /*
-                        * process all areas in one loop
-                        * it optimizes the memory accesses for this case
-                        */
-                       dmix->u.dmix.mix_areas_32(size * channels,
-                                                 ((signed int *)dst_areas[0].addr) + (dst_ofs * channels),
-                                                 ((signed int *)src_areas[0].addr) + (src_ofs * channels),
-                                                 dmix->u.dmix.sum_buffer + (dst_ofs * channels),
-                                                 sizeof(signed int),
-                                                 sizeof(signed int),
-                                                 sizeof(signed int));
-                       return;
-               }
-               for (chn = 0; chn < channels; chn++) {
-                       dchn = dmix->bindings ? dmix->bindings[chn] : chn;
-                       if (dchn >= dmix->shmptr->s.channels)
-                               continue;
-                       src_step = src_areas[chn].step / 8;
-                       dst_step = dst_areas[dchn].step / 8;
-                       src = (signed int *)(((char *)src_areas[chn].addr + src_areas[chn].first / 8) + (src_ofs * src_step));
-                       dst = (signed int *)(((char *)dst_areas[dchn].addr + dst_areas[dchn].first / 8) + (dst_ofs * dst_step));
-                       sum = dmix->u.dmix.sum_buffer + channels * dst_ofs + chn;
-                       dmix->u.dmix.mix_areas_32(size, dst, src, sum, dst_step, src_step, channels * sizeof(signed int));
-               }
-       } else { /* SND_PCM_FORMAT_S24_3LE */
-               unsigned char *src;
-               volatile unsigned char *dst;
-               if (dmix->interleaved) {
-                       /*
-                        * process all areas in one loop
-                        * it optimizes the memory accesses for this case
-                        */
-                       dmix->u.dmix.mix_areas_24(size * channels,
-                                                 ((unsigned char *)dst_areas[0].addr) + 3 * dst_ofs * channels,
-                                                 ((unsigned char *)src_areas[0].addr) + 3 * src_ofs * channels,
-                                                 dmix->u.dmix.sum_buffer + (dst_ofs * channels),
-                                                 3, 3, sizeof(signed int));
-                       return;
-               }
-               for (chn = 0; chn < channels; chn++) {
-                       dchn = dmix->bindings ? dmix->bindings[chn] : chn;
-                       if (dchn >= dmix->shmptr->s.channels)
-                               continue;
-                       src_step = src_areas[chn].step / 8;
-                       dst_step = dst_areas[dchn].step / 8;
-                       src = (unsigned char *)(((char *)src_areas[chn].addr + src_areas[chn].first / 8) + (src_ofs * src_step));
-                       dst = (unsigned char *)(((char *)dst_areas[dchn].addr + dst_areas[dchn].first / 8) + (dst_ofs * dst_step));
-                       sum = dmix->u.dmix.sum_buffer + channels * dst_ofs + chn;
-                       dmix->u.dmix.mix_areas_24(size, dst, src, sum, dst_step, src_step, channels * sizeof(signed int));
-               }
+       switch (dmix->shmptr->s.format) {
+       case SND_PCM_FORMAT_S16_LE:
+       case SND_PCM_FORMAT_S16_BE:
+               sample_size = 2;
+               do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_16;
+               break;
+       case SND_PCM_FORMAT_S32_LE:
+       case SND_PCM_FORMAT_S32_BE:
+               sample_size = 4;
+               do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_32;
+               break;
+       case SND_PCM_FORMAT_S24_3LE:
+               sample_size = 3;
+               do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_24;
+               break;
+       default:
+               return;
+       }
+       if (dmix->interleaved) {
+               /*
+                * process all areas in one loop
+                * it optimizes the memory accesses for this case
+                */
+               do_mix_areas(size * channels,
+                            (unsigned char *)dst_areas[0].addr + sample_size * dst_ofs * channels,
+                            (unsigned char *)src_areas[0].addr + sample_size * src_ofs * channels,
+                            dmix->u.dmix.sum_buffer + dst_ofs * channels,
+                            sample_size,
+                            sample_size,
+                            sizeof(signed int));
+               return;
+       }
+       for (chn = 0; chn < channels; chn++) {
+               dchn = dmix->bindings ? dmix->bindings[chn] : chn;
+               if (dchn >= dmix->shmptr->s.channels)
+                       continue;
+               src_step = src_areas[chn].step / 8;
+               dst_step = dst_areas[dchn].step / 8;
+               do_mix_areas(size,
+                            ((unsigned char *)dst_areas[dchn].addr + dst_areas[dchn].first / 8) + dst_ofs * dst_step,
+                            ((unsigned char *)src_areas[chn].addr + src_areas[chn].first / 8) + src_ofs * src_step,
+                            dmix->u.dmix.sum_buffer + channels * dst_ofs + chn,
+                            dst_step,
+                            src_step,
+                            channels * sizeof(signed int));
        }
 }