The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/sound/pcm/feeder_fmt.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999 Cameron Grant <cg@FreeBSD.org>
    3  * Copyright (c) 2005 Ariff Abdullah <ariff@FreeBSD.org>
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * *New* and rewritten soft format converter, supporting 24/32bit pcm data,
   28  * simplified and optimized.
   29  *
   30  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   31  *                                                                         *
   32  * This new implementation is fully dedicated in memory of Cameron Grant,  *
   33  * the creator of the magnificent, highly addictive feeder infrastructure. *
   34  *                                                                         *
   35  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   36  *
   37  */
   38 
   39 #include <dev/sound/pcm/sound.h>
   40 #include "feeder_if.h"
   41 
   42 SND_DECLARE_FILE("$FreeBSD: releng/6.1/sys/dev/sound/pcm/feeder_fmt.c 154970 2006-01-29 02:27:28Z ariff $");
   43 
   44 MALLOC_DEFINE(M_FMTFEEDER, "fmtfeed", "pcm format feeder");
   45 
   46 #define FEEDBUFSZ       8192
   47 #define FEEDBUF24SZ     8190
   48 
   49 #define FMT_TRACE(x...) /* printf(x) */
   50 #define FMT_TEST(x, y...) /* if (x) FMT_TRACE(y) */
   51 #define FMT_ALIGNBYTE(x) /* x */
   52 
   53 /*
   54  * Sign inverted ulaw/alaw -> 8 table
   55  */
   56 static uint8_t ulaw_to_s8_tbl[] = {
   57   131,  135,  139,  143,  147,  151,  155,  159,
   58   163,  167,  171,  175,  179,  183,  187,  191,
   59   194,  196,  198,  200,  202,  204,  206,  208,
   60   210,  212,  214,  216,  218,  220,  222,  224,
   61   226,  227,  228,  229,  230,  231,  232,  233,
   62   234,  235,  236,  237,  238,  239,  240,  241,
   63   241,  242,  242,  243,  243,  244,  244,  245,
   64   245,  246,  246,  247,  247,  248,  248,  249,
   65   249,  249,  250,  250,  250,  250,  251,  251,
   66   251,  251,  252,  252,  252,  252,  253,  253,
   67   253,  253,  253,  253,  254,  254,  254,  254,
   68   254,  254,  254,  254,  255,  255,  255,  255,
   69   255,  255,  255,  255,  255,  255,  255,  255,
   70     0,    0,    0,    0,    0,    0,    0,    0,
   71     0,    0,    0,    0,    0,    0,    0,    0,
   72     0,    0,    0,    0,    0,    0,    0,    0,
   73   125,  121,  117,  113,  109,  105,  101,   97,
   74    93,   89,   85,   81,   77,   73,   69,   65,
   75    62,   60,   58,   56,   54,   52,   50,   48,
   76    46,   44,   42,   40,   38,   36,   34,   32,
   77    30,   29,   28,   27,   26,   25,   24,   23,
   78    22,   21,   20,   19,   18,   17,   16,   15,
   79    15,   14,   14,   13,   13,   12,   12,   11,
   80    11,   10,   10,    9,    9,    8,    8,    7,
   81     7,    7,    6,    6,    6,    6,    5,    5,
   82     5,    5,    4,    4,    4,    4,    3,    3,
   83     3,    3,    3,    3,    2,    2,    2,    2,
   84     2,    2,    2,    2,    1,    1,    1,    1,
   85     1,    1,    1,    1,    1,    1,    1,    1,
   86     0,    0,    0,    0,    0,    0,    0,    0,
   87     0,    0,    0,    0,    0,    0,    0,    0,
   88     0,    0,    0,    0,    0,    0,    0,    0,
   89 };
   90 
   91 static uint8_t alaw_to_s8_tbl[] = {
   92   236,  237,  234,  235,  240,  241,  238,  239,
   93   228,  229,  226,  227,  232,  233,  230,  231,
   94   246,  246,  245,  245,  248,  248,  247,  247,
   95   242,  242,  241,  241,  244,  244,  243,  243,
   96   171,  175,  163,  167,  187,  191,  179,  183,
   97   139,  143,  131,  135,  155,  159,  147,  151,
   98   214,  216,  210,  212,  222,  224,  218,  220,
   99   198,  200,  194,  196,  206,  208,  202,  204,
  100   255,  255,  255,  255,  255,  255,  255,  255,
  101   255,  255,  255,  255,  255,  255,  255,  255,
  102     0,    0,    0,    0,    0,    0,    0,    0,
  103     0,    0,    0,    0,    0,    0,    0,    0,
  104   251,  251,  251,  251,  252,  252,  252,  252,
  105   249,  249,  249,  249,  250,  250,  250,  250,
  106   254,  254,  254,  254,  254,  254,  254,  254,
  107   253,  253,  253,  253,  253,  253,  253,  253,
  108    20,   19,   22,   21,   16,   15,   18,   17,
  109    28,   27,   30,   29,   24,   23,   26,   25,
  110    10,   10,   11,   11,    8,    8,    9,    9,
  111    14,   14,   15,   15,   12,   12,   13,   13,
  112    85,   81,   93,   89,   69,   65,   77,   73,
  113   117,  113,  125,  121,  101,   97,  109,  105,
  114    42,   40,   46,   44,   34,   32,   38,   36,
  115    58,   56,   62,   60,   50,   48,   54,   52,
  116     1,    1,    1,    1,    1,    1,    1,    1,
  117     1,    1,    1,    1,    1,    1,    1,    1,
  118     0,    0,    0,    0,    0,    0,    0,    0,
  119     0,    0,    0,    0,    0,    0,    0,    0,
  120     5,    5,    5,    5,    4,    4,    4,    4,
  121     7,    7,    7,    7,    6,    6,    6,    6,
  122     2,    2,    2,    2,    2,    2,    2,    2,
  123     3,    3,    3,    3,    3,    3,    3,    3,
  124 };
  125 
  126 static uint8_t u8_to_ulaw_tbl[] = {
  127      0,    0,    0,    0,    0,    1,    1,    1,
  128      1,    2,    2,    2,    2,    3,    3,    3,
  129      3,    4,    4,    4,    4,    5,    5,    5,
  130      5,    6,    6,    6,    6,    7,    7,    7,
  131      7,    8,    8,    8,    8,    9,    9,    9,
  132      9,   10,   10,   10,   10,   11,   11,   11,
  133     11,   12,   12,   12,   12,   13,   13,   13,
  134     13,   14,   14,   14,   14,   15,   15,   15,
  135     15,   16,   16,   17,   17,   18,   18,   19,
  136     19,   20,   20,   21,   21,   22,   22,   23,
  137     23,   24,   24,   25,   25,   26,   26,   27,
  138     27,   28,   28,   29,   29,   30,   30,   31,
  139     31,   32,   33,   34,   35,   36,   37,   38,
  140     39,   40,   41,   42,   43,   44,   45,   46,
  141     47,   49,   51,   53,   55,   57,   59,   61,
  142     63,   66,   70,   74,   78,   84,   92,  104,
  143    254,  231,  219,  211,  205,  201,  197,  193,
  144    190,  188,  186,  184,  182,  180,  178,  176,
  145    175,  174,  173,  172,  171,  170,  169,  168,
  146    167,  166,  165,  164,  163,  162,  161,  160,
  147    159,  159,  158,  158,  157,  157,  156,  156,
  148    155,  155,  154,  154,  153,  153,  152,  152,
  149    151,  151,  150,  150,  149,  149,  148,  148,
  150    147,  147,  146,  146,  145,  145,  144,  144,
  151    143,  143,  143,  143,  142,  142,  142,  142,
  152    141,  141,  141,  141,  140,  140,  140,  140,
  153    139,  139,  139,  139,  138,  138,  138,  138,
  154    137,  137,  137,  137,  136,  136,  136,  136,
  155    135,  135,  135,  135,  134,  134,  134,  134,
  156    133,  133,  133,  133,  132,  132,  132,  132,
  157    131,  131,  131,  131,  130,  130,  130,  130,
  158    129,  129,  129,  129,  128,  128,  128,  128,
  159 };
  160 
  161 static uint8_t u8_to_alaw_tbl[] = {
  162    42,   42,   42,   42,   42,   43,   43,   43,
  163    43,   40,   40,   40,   40,   41,   41,   41,
  164    41,   46,   46,   46,   46,   47,   47,   47,
  165    47,   44,   44,   44,   44,   45,   45,   45,
  166    45,   34,   34,   34,   34,   35,   35,   35,
  167    35,   32,   32,   32,   32,   33,   33,   33,
  168    33,   38,   38,   38,   38,   39,   39,   39,
  169    39,   36,   36,   36,   36,   37,   37,   37,
  170    37,   58,   58,   59,   59,   56,   56,   57,
  171    57,   62,   62,   63,   63,   60,   60,   61,
  172    61,   50,   50,   51,   51,   48,   48,   49,
  173    49,   54,   54,   55,   55,   52,   52,   53,
  174    53,   10,   11,    8,    9,   14,   15,   12,
  175    13,    2,    3,    0,    1,    6,    7,    4,
  176     5,   24,   30,   28,   18,   16,   22,   20,
  177   106,  110,   98,  102,  122,  114,   75,   90,
  178   213,  197,  245,  253,  229,  225,  237,  233,
  179   149,  151,  145,  147,  157,  159,  153,  155,
  180   133,  132,  135,  134,  129,  128,  131,  130,
  181   141,  140,  143,  142,  137,  136,  139,  138,
  182   181,  181,  180,  180,  183,  183,  182,  182,
  183   177,  177,  176,  176,  179,  179,  178,  178,
  184   189,  189,  188,  188,  191,  191,  190,  190,
  185   185,  185,  184,  184,  187,  187,  186,  186,
  186   165,  165,  165,  165,  164,  164,  164,  164,
  187   167,  167,  167,  167,  166,  166,  166,  166,
  188   161,  161,  161,  161,  160,  160,  160,  160,
  189   163,  163,  163,  163,  162,  162,  162,  162,
  190   173,  173,  173,  173,  172,  172,  172,  172,
  191   175,  175,  175,  175,  174,  174,  174,  174,
  192   169,  169,  169,  169,  168,  168,  168,  168,
  193   171,  171,  171,  171,  170,  170,  170,  170,
  194 };
  195 
  196 static int
  197 feed_table_u8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  198                         uint32_t count, void *source)
  199 {
  200         int j, k = FEEDER_FEED(f->source, c, b, count, source);
  201         uint8_t *tbl = (uint8_t *)f->data;
  202         
  203         j = k;
  204         while (j > 0) {
  205                 j--;
  206                 b[j] = tbl[b[j]] ^ 0x80;
  207         }
  208         return k;
  209 }
  210 
  211 static int
  212 feed_table_s16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  213                         uint32_t count, void *source)
  214 {
  215         int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
  216         uint8_t *tbl = (uint8_t *)f->data;
  217         
  218         i = k;
  219         k <<= 1;
  220         j = k;
  221         while (i > 0) {
  222                 b[--j] = tbl[b[--i]];
  223                 b[--j] = 0;
  224         }
  225         return k;
  226 }
  227 
  228 static int
  229 feed_table_xlaw(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  230                         uint32_t count, void *source)
  231 {
  232         int j, k = FEEDER_FEED(f->source, c, b, count, source);
  233         uint8_t *tbl = (uint8_t *)f->data;
  234 
  235         j = k;
  236         while (j > 0) {
  237                 j--;
  238                 b[j] = tbl[b[j]];
  239         }
  240         return k;
  241 }
  242 
  243 static struct pcm_feederdesc feeder_ulawtou8_desc[] = {
  244         {FEEDER_FMT, AFMT_MU_LAW, AFMT_U8, 0},
  245         {FEEDER_FMT, AFMT_MU_LAW|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
  246         {0, 0, 0, 0},
  247 };
  248 static kobj_method_t feeder_ulawtou8_methods[] = {
  249         KOBJMETHOD(feeder_feed, feed_table_u8),
  250         {0, 0}
  251 };
  252 FEEDER_DECLARE(feeder_ulawtou8, 0, ulaw_to_s8_tbl);
  253 
  254 static struct pcm_feederdesc feeder_alawtou8_desc[] = {
  255         {FEEDER_FMT, AFMT_A_LAW, AFMT_U8, 0},
  256         {FEEDER_FMT, AFMT_A_LAW|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
  257         {0, 0, 0, 0},
  258 };
  259 static kobj_method_t feeder_alawtou8_methods[] = {
  260         KOBJMETHOD(feeder_feed, feed_table_u8),
  261         {0, 0}
  262 };
  263 FEEDER_DECLARE(feeder_alawtou8, 0, alaw_to_s8_tbl);
  264 
  265 static struct pcm_feederdesc feeder_ulawtos16le_desc[] = {
  266         {FEEDER_FMT, AFMT_MU_LAW, AFMT_S16_LE, 0},
  267         {FEEDER_FMT, AFMT_MU_LAW|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
  268         {0, 0, 0, 0},
  269 };
  270 static kobj_method_t feeder_ulawtos16le_methods[] = {
  271         KOBJMETHOD(feeder_feed, feed_table_s16le),
  272         {0, 0}
  273 };
  274 FEEDER_DECLARE(feeder_ulawtos16le, 0, ulaw_to_s8_tbl);
  275 
  276 static struct pcm_feederdesc feeder_alawtos16le_desc[] = {
  277         {FEEDER_FMT, AFMT_A_LAW, AFMT_S16_LE, 0},
  278         {FEEDER_FMT, AFMT_A_LAW|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
  279         {0, 0, 0, 0},
  280 };
  281 static kobj_method_t feeder_alawtos16le_methods[] = {
  282         KOBJMETHOD(feeder_feed, feed_table_s16le),
  283         {0, 0}
  284 };
  285 FEEDER_DECLARE(feeder_alawtos16le, 0, alaw_to_s8_tbl);
  286 
  287 static struct pcm_feederdesc feeder_u8toulaw_desc[] = {
  288         {FEEDER_FMT, AFMT_U8, AFMT_MU_LAW, 0},
  289         {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_MU_LAW|AFMT_STEREO, 0},
  290         {0, 0, 0, 0},
  291 };
  292 static kobj_method_t feeder_u8toulaw_methods[] = {
  293         KOBJMETHOD(feeder_feed, feed_table_xlaw),
  294         {0, 0}
  295 };
  296 FEEDER_DECLARE(feeder_u8toulaw, 0, u8_to_ulaw_tbl);
  297 
  298 static struct pcm_feederdesc feeder_u8toalaw_desc[] = {
  299         {FEEDER_FMT, AFMT_U8, AFMT_A_LAW, 0},
  300         {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_A_LAW|AFMT_STEREO, 0},
  301         {0, 0, 0, 0},
  302 };
  303 static kobj_method_t feeder_u8toalaw_methods[] = {
  304         KOBJMETHOD(feeder_feed, feed_table_xlaw),
  305         {0, 0}
  306 };
  307 FEEDER_DECLARE(feeder_u8toalaw, 0, u8_to_alaw_tbl);
  308 
  309 /*
  310  * Conversion rules:-
  311  *      1. BE -> LE
  312  *      2. if fmt == u8 , u8 -> s8 (economical)
  313  *      3. Xle -> 16le
  314  *      4. if fmt != u8 && fmt == u16le , u16le -> s16le
  315  *      4. s16le mono -> s16le stereo
  316  *
  317  * All conversion done in byte level to preserve endianess.
  318  */
  319 
  320 static int
  321 feed_common_init(struct pcm_feeder *f)
  322 {
  323         f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_NOWAIT|M_ZERO);
  324         if (f->data == NULL)
  325                 return ENOMEM;
  326         return 0;
  327 }
  328 
  329 static int
  330 feed_common_free(struct pcm_feeder *f)
  331 {
  332         if (f->data)
  333                 free(f->data, M_FMTFEEDER);
  334         f->data = NULL;
  335         return 0;
  336 }
  337 
  338 /*
  339  * Bit conversion
  340  */
  341 static int
  342 feed_8to16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  343                         uint32_t count, void *source)
  344 {
  345         int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
  346         
  347         i = k;
  348         k <<= 1;
  349         j = k;
  350         while (i > 0) {
  351                 b[--j] = b[--i];
  352                 b[--j] = 0;
  353         }
  354         return k;
  355 }
  356 static struct pcm_feederdesc feeder_8to16le_desc[] = {
  357         {FEEDER_FMT, AFMT_U8, AFMT_U16_LE, 0},
  358         {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
  359         {FEEDER_FMT, AFMT_S8, AFMT_S16_LE, 0},
  360         {FEEDER_FMT, AFMT_S8|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
  361         {0, 0, 0, 0},
  362 };
  363 static kobj_method_t feeder_8to16le_methods[] = {
  364         KOBJMETHOD(feeder_feed, feed_8to16le),
  365         {0, 0}
  366 };
  367 FEEDER_DECLARE(feeder_8to16le, 0, NULL);
  368 
  369 static int
  370 feed_16leto8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  371                         uint32_t count, void *source)
  372 {
  373         int i, j, k;
  374         uint8_t *src = (uint8_t *)f->data;
  375         
  376         k = count << 1;
  377         k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
  378         if (k < 2) {
  379                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  380                                 __func__, k);
  381                 return 0;
  382         }
  383         FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
  384         FMT_ALIGNBYTE(k &= ~1);
  385         i = k;
  386         j = k >> 1;
  387         while (i > 0) {
  388                 b[--j] = src[--i];
  389                 i--;
  390         }
  391         return k >> 1;
  392 }
  393 static struct pcm_feederdesc feeder_16leto8_desc[] = {
  394         {FEEDER_FMT, AFMT_U16_LE, AFMT_U8, 0},
  395         {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
  396         {FEEDER_FMT, AFMT_S16_LE, AFMT_S8, 0},
  397         {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S8|AFMT_STEREO, 0},
  398         {0, 0, 0, 0},
  399 };
  400 static kobj_method_t feeder_16leto8_methods[] = {
  401         KOBJMETHOD(feeder_init, feed_common_init),
  402         KOBJMETHOD(feeder_free, feed_common_free),
  403         KOBJMETHOD(feeder_feed, feed_16leto8),
  404         {0, 0}
  405 };
  406 FEEDER_DECLARE(feeder_16leto8, 0, NULL);
  407 
  408 static int
  409 feed_16leto24le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  410                         uint32_t count, void *source)
  411 {
  412         int i, j, k;
  413 
  414         k = (count / 3) << 1;
  415         k = FEEDER_FEED(f->source, c, b, k, source);
  416         if (k < 2) {
  417                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  418                                 __func__, k);
  419                 return 0;
  420         }
  421         FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
  422         FMT_ALIGNBYTE(k &= ~1);
  423         i = k;
  424         j = (k >> 1) * 3;
  425         k = j;
  426         while (i > 0) {
  427                 b[--j] = b[--i];
  428                 b[--j] = b[--i];
  429                 b[--j] = 0;
  430         }
  431         return k;
  432 }
  433 static struct pcm_feederdesc feeder_16leto24le_desc[] = {
  434         {FEEDER_FMT, AFMT_U16_LE, AFMT_U24_LE, 0},
  435         {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U24_LE|AFMT_STEREO, 0},
  436         {FEEDER_FMT, AFMT_S16_LE, AFMT_S24_LE, 0},
  437         {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0},
  438         {0, 0, 0, 0},
  439 };
  440 static kobj_method_t feeder_16leto24le_methods[] = {
  441         KOBJMETHOD(feeder_feed, feed_16leto24le),
  442         {0, 0}
  443 };
  444 FEEDER_DECLARE(feeder_16leto24le, 0, NULL);
  445 
  446 static int
  447 feed_24leto16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  448                         uint32_t count, void *source)
  449 {
  450         int i, j, k;
  451         uint8_t *src = (uint8_t *)f->data;
  452 
  453         k = (count * 3) >> 1;
  454         k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUF24SZ), source);
  455         if (k < 3) {
  456                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  457                                 __func__, k);
  458                 return 0;
  459         }
  460         FMT_TEST(k % 3, "%s: Bytes not 24bit aligned.\n", __func__);
  461         FMT_ALIGNBYTE(k -= k % 3);
  462         i = (k / 3) << 1;
  463         j = i;
  464         while (i > 0) {
  465                 b[--i] = src[--k];
  466                 b[--i] = src[--k];
  467                 k--;
  468         }
  469         return j;
  470 }
  471 static struct pcm_feederdesc feeder_24leto16le_desc[] = {
  472         {FEEDER_FMT, AFMT_U24_LE, AFMT_U16_LE, 0},
  473         {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
  474         {FEEDER_FMT, AFMT_S24_LE, AFMT_S16_LE, 0},
  475         {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
  476         {0, 0, 0, 0},
  477 };
  478 static kobj_method_t feeder_24leto16le_methods[] = {
  479         KOBJMETHOD(feeder_init, feed_common_init),
  480         KOBJMETHOD(feeder_free, feed_common_free),
  481         KOBJMETHOD(feeder_feed, feed_24leto16le),
  482         {0, 0}
  483 };
  484 FEEDER_DECLARE(feeder_24leto16le, 1, NULL);
  485 
  486 static int
  487 feed_16leto32le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  488                         uint32_t count, void *source)
  489 {
  490         int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
  491         if (k < 2) {
  492                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  493                                 __func__, k);
  494                 return 0;
  495         }
  496         FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
  497         FMT_ALIGNBYTE(k &= ~1);
  498         i = k;
  499         j = k << 1;
  500         k = j;
  501         while (i > 0) {
  502                 b[--j] = b[--i];
  503                 b[--j] = b[--i];
  504                 b[--j] = 0;
  505                 b[--j] = 0;
  506         }
  507         return k;
  508 }
  509 static struct pcm_feederdesc feeder_16leto32le_desc[] = {
  510         {FEEDER_FMT, AFMT_U16_LE, AFMT_U32_LE, 0},
  511         {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U32_LE|AFMT_STEREO, 0},
  512         {FEEDER_FMT, AFMT_S16_LE, AFMT_S32_LE, 0},
  513         {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S32_LE|AFMT_STEREO, 0},
  514         {0, 0, 0, 0},
  515 };
  516 static kobj_method_t feeder_16leto32le_methods[] = {
  517         KOBJMETHOD(feeder_feed, feed_16leto32le),
  518         {0, 0}
  519 };
  520 FEEDER_DECLARE(feeder_16leto32le, 0, NULL);
  521 
  522 static int
  523 feed_32leto16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  524                         uint32_t count, void *source)
  525 {
  526         int i, j, k;
  527         uint8_t *src = (uint8_t *)f->data;
  528 
  529         k = count << 1;
  530         k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
  531         if (k < 4) {
  532                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  533                                 __func__, k);
  534                 return 0;
  535         }
  536         FMT_TEST(k & 3, "%s: Bytes not 32bit aligned.\n", __func__);
  537         FMT_ALIGNBYTE(k &= ~3);
  538         i = k;
  539         k >>= 1;
  540         j = k;
  541         while (i > 0) {
  542                 b[--j] = src[--i];
  543                 b[--j] = src[--i];
  544                 i -= 2;
  545         }
  546         return k;
  547 }
  548 static struct pcm_feederdesc feeder_32leto16le_desc[] = {
  549         {FEEDER_FMT, AFMT_U32_LE, AFMT_U16_LE, 0},
  550         {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
  551         {FEEDER_FMT, AFMT_S32_LE, AFMT_S16_LE, 0},
  552         {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
  553         {0, 0, 0, 0},
  554 };
  555 static kobj_method_t feeder_32leto16le_methods[] = {
  556         KOBJMETHOD(feeder_init, feed_common_init),
  557         KOBJMETHOD(feeder_free, feed_common_free),
  558         KOBJMETHOD(feeder_feed, feed_32leto16le),
  559         {0, 0}
  560 };
  561 FEEDER_DECLARE(feeder_32leto16le, 1, NULL);
  562 /*
  563  * Bit conversion end
  564  */
  565 
  566 /*
  567  * Channel conversion (mono -> stereo)
  568  */
  569 static int
  570 feed_monotostereo8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  571                         uint32_t count, void *source)
  572 {
  573         int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
  574 
  575         i = k;
  576         j = k << 1;
  577         while (i > 0) {
  578                 b[--j] = b[--i];
  579                 b[--j] = b[i];
  580         }
  581         return k << 1;
  582 }
  583 static struct pcm_feederdesc feeder_monotostereo8_desc[] = {
  584         {FEEDER_FMT, AFMT_U8, AFMT_U8|AFMT_STEREO, 0},
  585         {FEEDER_FMT, AFMT_S8, AFMT_S8|AFMT_STEREO, 0},
  586         {0, 0, 0, 0},
  587 };
  588 static kobj_method_t feeder_monotostereo8_methods[] = {
  589         KOBJMETHOD(feeder_feed, feed_monotostereo8),
  590         {0, 0}
  591 };
  592 FEEDER_DECLARE(feeder_monotostereo8, 0, NULL);
  593 
  594 static int
  595 feed_monotostereo16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  596                         uint32_t count, void *source)
  597 {
  598         int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
  599         uint8_t l, m;
  600 
  601         if (k < 2) {
  602                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  603                                 __func__, k);
  604                 return 0;
  605         }
  606         FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
  607         FMT_ALIGNBYTE(k &= ~1);
  608         i = k;
  609         j = k << 1;
  610         while (i > 0) {
  611                 l = b[--i];
  612                 m = b[--i];
  613                 b[--j] = l;
  614                 b[--j] = m;
  615                 b[--j] = l;
  616                 b[--j] = m;
  617         }
  618         return k << 1;
  619 }
  620 static struct pcm_feederdesc feeder_monotostereo16_desc[] = {
  621         {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_LE|AFMT_STEREO, 0},
  622         {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_LE|AFMT_STEREO, 0},
  623         {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_BE|AFMT_STEREO, 0},
  624         {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_BE|AFMT_STEREO, 0},
  625         {0, 0, 0, 0},
  626 };
  627 static kobj_method_t feeder_monotostereo16_methods[] = {
  628         KOBJMETHOD(feeder_feed, feed_monotostereo16),
  629         {0, 0}
  630 };
  631 FEEDER_DECLARE(feeder_monotostereo16, 0, NULL);
  632 
  633 static int
  634 feed_monotostereo24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  635                         uint32_t count, void *source)
  636 {
  637         int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
  638         uint8_t l, m, n;
  639 
  640         if (k < 3) {
  641                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  642                                 __func__, k);
  643                 return 0;
  644         }
  645         FMT_TEST(k % 3, "%s: Bytes not 24bit aligned.\n", __func__);
  646         FMT_ALIGNBYTE(k -= k % 3);
  647         i = k;
  648         j = k << 1;
  649         while (i > 0) {
  650                 l = b[--i];
  651                 m = b[--i];
  652                 n = b[--i];
  653                 b[--j] = l;
  654                 b[--j] = m;
  655                 b[--j] = n;
  656                 b[--j] = l;
  657                 b[--j] = m;
  658                 b[--j] = n;
  659         }
  660         return k << 1;
  661 }
  662 static struct pcm_feederdesc feeder_monotostereo24_desc[] = {
  663         {FEEDER_FMT, AFMT_U24_LE, AFMT_U24_LE|AFMT_STEREO, 0},
  664         {FEEDER_FMT, AFMT_S24_LE, AFMT_S24_LE|AFMT_STEREO, 0},
  665         {FEEDER_FMT, AFMT_U24_BE, AFMT_U24_BE|AFMT_STEREO, 0},
  666         {FEEDER_FMT, AFMT_S24_BE, AFMT_S24_BE|AFMT_STEREO, 0},
  667         {0, 0, 0, 0},
  668 };
  669 static kobj_method_t feeder_monotostereo24_methods[] = {
  670         KOBJMETHOD(feeder_feed, feed_monotostereo24),
  671         {0, 0}
  672 };
  673 FEEDER_DECLARE(feeder_monotostereo24, 0, NULL);
  674 
  675 static int
  676 feed_monotostereo32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  677                         uint32_t count, void *source)
  678 {
  679         int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
  680         uint8_t l, m, n, o;
  681 
  682         if (k < 4) {
  683                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  684                                 __func__, k);
  685                 return 0;
  686         }
  687         FMT_TEST(k & 3, "%s: Bytes not 32bit aligned.\n", __func__);
  688         FMT_ALIGNBYTE(k &= ~3);
  689         i = k;
  690         j = k << 1;
  691         while (i > 0) {
  692                 l = b[--i];
  693                 m = b[--i];
  694                 n = b[--i];
  695                 o = b[--i];
  696                 b[--j] = l;
  697                 b[--j] = m;
  698                 b[--j] = n;
  699                 b[--j] = o;
  700                 b[--j] = l;
  701                 b[--j] = m;
  702                 b[--j] = n;
  703                 b[--j] = o;
  704         }
  705         return k << 1;
  706 }
  707 static struct pcm_feederdesc feeder_monotostereo32_desc[] = {
  708         {FEEDER_FMT, AFMT_U32_LE, AFMT_U32_LE|AFMT_STEREO, 0},
  709         {FEEDER_FMT, AFMT_S32_LE, AFMT_S32_LE|AFMT_STEREO, 0},
  710         {FEEDER_FMT, AFMT_U32_BE, AFMT_U32_BE|AFMT_STEREO, 0},
  711         {FEEDER_FMT, AFMT_S32_BE, AFMT_S32_BE|AFMT_STEREO, 0},
  712         {0, 0, 0, 0},
  713 };
  714 static kobj_method_t feeder_monotostereo32_methods[] = {
  715         KOBJMETHOD(feeder_feed, feed_monotostereo32),
  716         {0, 0}
  717 };
  718 FEEDER_DECLARE(feeder_monotostereo32, 0, NULL);
  719 /*
  720  * Channel conversion (mono -> stereo) end
  721  */
  722 
  723 /*
  724  * Channel conversion (stereo -> mono)
  725  */
  726 static int
  727 feed_stereotomono8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  728                         uint32_t count, void *source)
  729 {
  730         int i, j, k;
  731         uint8_t *src = (uint8_t *)f->data;
  732 
  733         k = count << 1;
  734         k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
  735         if (k < 2) {
  736                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  737                                 __func__, k);
  738                 return 0;
  739         }
  740         FMT_TEST(k & 1, "%s: Bytes not 8bit (stereo) aligned.\n", __func__);
  741         FMT_ALIGNBYTE(k &= ~1);
  742         i = k >> 1;
  743         j = i;
  744         while (i > 0) {
  745                 k--;
  746                 b[--i] = src[--k];
  747         }
  748         return j;
  749 }
  750 static struct pcm_feederdesc feeder_stereotomono8_desc[] = {
  751         {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_U8, 0},
  752         {FEEDER_FMT, AFMT_S8|AFMT_STEREO, AFMT_S8, 0},
  753         {0, 0, 0, 0},
  754 };
  755 static kobj_method_t feeder_stereotomono8_methods[] = {
  756         KOBJMETHOD(feeder_init, feed_common_init),
  757         KOBJMETHOD(feeder_free, feed_common_free),
  758         KOBJMETHOD(feeder_feed, feed_stereotomono8),
  759         {0, 0}
  760 };
  761 FEEDER_DECLARE(feeder_stereotomono8, 0, NULL);
  762 
  763 static int
  764 feed_stereotomono16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  765                         uint32_t count, void *source)
  766 {
  767         int i, j, k;
  768         uint8_t *src = (uint8_t *)f->data;
  769 
  770         k = count << 1;
  771         k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
  772         if (k < 4) {
  773                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  774                                 __func__, k);
  775                 return 0;
  776         }
  777         FMT_TEST(k & 3, "%s: Bytes not 16bit (stereo) aligned.\n", __func__);
  778         FMT_ALIGNBYTE(k &= ~3);
  779         i = k >> 1;
  780         j = i;
  781         while (i > 0) {
  782                 k -= 2;
  783                 b[--i] = src[--k];
  784                 b[--i] = src[--k];
  785         }
  786         return j;
  787 }
  788 static struct pcm_feederdesc feeder_stereotomono16_desc[] = {
  789         {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U16_LE, 0},
  790         {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S16_LE, 0},
  791         {FEEDER_FMT, AFMT_U16_BE|AFMT_STEREO, AFMT_U16_BE, 0},
  792         {FEEDER_FMT, AFMT_S16_BE|AFMT_STEREO, AFMT_S16_BE, 0},
  793         {0, 0, 0, 0},
  794 };
  795 static kobj_method_t feeder_stereotomono16_methods[] = {
  796         KOBJMETHOD(feeder_init, feed_common_init),
  797         KOBJMETHOD(feeder_free, feed_common_free),
  798         KOBJMETHOD(feeder_feed, feed_stereotomono16),
  799         {0, 0}
  800 };
  801 FEEDER_DECLARE(feeder_stereotomono16, 0, NULL);
  802 
  803 static int
  804 feed_stereotomono24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  805                         uint32_t count, void *source)
  806 {
  807         int i, j, k;
  808         uint8_t *src = (uint8_t *)f->data;
  809 
  810         k = count << 1;
  811         k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUF24SZ), source);
  812         if (k < 6) {
  813                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  814                                 __func__, k);
  815                 return 0;
  816         }
  817         FMT_TEST(k % 6, "%s: Bytes not 24bit (stereo) aligned.\n", __func__);
  818         FMT_ALIGNBYTE(k -= k % 6);
  819         i = k >> 1;
  820         j = i;
  821         while (i > 0) {
  822                 k -= 3;
  823                 b[--i] = src[--k];
  824                 b[--i] = src[--k];
  825                 b[--i] = src[--k];
  826         }
  827         return j;
  828 }
  829 static struct pcm_feederdesc feeder_stereotomono24_desc[] = {
  830         {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_U24_LE, 0},
  831         {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_S24_LE, 0},
  832         {FEEDER_FMT, AFMT_U24_BE|AFMT_STEREO, AFMT_U24_BE, 0},
  833         {FEEDER_FMT, AFMT_S24_BE|AFMT_STEREO, AFMT_S24_BE, 0},
  834         {0, 0, 0, 0},
  835 };
  836 static kobj_method_t feeder_stereotomono24_methods[] = {
  837         KOBJMETHOD(feeder_init, feed_common_init),
  838         KOBJMETHOD(feeder_free, feed_common_free),
  839         KOBJMETHOD(feeder_feed, feed_stereotomono24),
  840         {0, 0}
  841 };
  842 FEEDER_DECLARE(feeder_stereotomono24, 0, NULL);
  843 
  844 static int
  845 feed_stereotomono32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  846                         uint32_t count, void *source)
  847 {
  848         int i, j, k;
  849         uint8_t *src = (uint8_t *)f->data;
  850 
  851         k = count << 1;
  852         k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
  853         if (k < 8) {
  854                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  855                                 __func__, k);
  856                 return 0;
  857         }
  858         FMT_TEST(k & 7, "%s: Bytes not 32bit (stereo) aligned.\n", __func__);
  859         FMT_ALIGNBYTE(k &= ~7);
  860         i = k >> 1;
  861         j = i;
  862         while (i > 0) {
  863                 k -= 4;
  864                 b[--i] = src[--k];
  865                 b[--i] = src[--k];
  866                 b[--i] = src[--k];
  867                 b[--i] = src[--k];
  868         }
  869         return j;
  870 }
  871 static struct pcm_feederdesc feeder_stereotomono32_desc[] = {
  872         {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_U32_LE, 0},
  873         {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_S32_LE, 0},
  874         {FEEDER_FMT, AFMT_U32_BE|AFMT_STEREO, AFMT_U32_BE, 0},
  875         {FEEDER_FMT, AFMT_S32_BE|AFMT_STEREO, AFMT_S32_BE, 0},
  876         {0, 0, 0, 0},
  877 };
  878 static kobj_method_t feeder_stereotomono32_methods[] = {
  879         KOBJMETHOD(feeder_init, feed_common_init),
  880         KOBJMETHOD(feeder_free, feed_common_free),
  881         KOBJMETHOD(feeder_feed, feed_stereotomono32),
  882         {0, 0}
  883 };
  884 FEEDER_DECLARE(feeder_stereotomono32, 0, NULL);
  885 /*
  886  * Channel conversion (stereo -> mono) end
  887  */
  888 
  889 /*
  890  * Sign conversion
  891  */
  892 static int
  893 feed_sign8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  894                         uint32_t count, void *source)
  895 {
  896         int i, j = FEEDER_FEED(f->source, c, b, count, source);
  897 
  898         i = j;
  899         while (i > 0)
  900                 b[--i] ^= 0x80;
  901         return j;
  902 }
  903 static struct pcm_feederdesc feeder_sign8_desc[] = {
  904         {FEEDER_FMT, AFMT_U8, AFMT_S8, 0},
  905         {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_S8|AFMT_STEREO, 0},
  906         {FEEDER_FMT, AFMT_S8, AFMT_U8, 0},
  907         {FEEDER_FMT, AFMT_S8|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
  908         {0, 0, 0, 0},
  909 };
  910 static kobj_method_t feeder_sign8_methods[] = {
  911         KOBJMETHOD(feeder_feed, feed_sign8),
  912         {0, 0}
  913 };
  914 FEEDER_DECLARE(feeder_sign8, 0, NULL);
  915 
  916 static int
  917 feed_sign16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  918                         uint32_t count, void *source)
  919 {
  920         int i, j = FEEDER_FEED(f->source, c, b, count, source);
  921 
  922         if (j < 2) {
  923                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  924                                 __func__, j);
  925                 return 0;
  926         }
  927         FMT_TEST(j & 1, "%s: Bytes not 16bit aligned.\n", __func__);
  928         FMT_ALIGNBYTE(j &= ~1);
  929         i = j;
  930         while (i > 0) {
  931                 b[--i] ^= 0x80;
  932                 i--;
  933         }
  934         return j;
  935 }
  936 static struct pcm_feederdesc feeder_sign16le_desc[] = {
  937         {FEEDER_FMT, AFMT_U16_LE, AFMT_S16_LE, 0},
  938         {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
  939         {FEEDER_FMT, AFMT_S16_LE, AFMT_U16_LE, 0},
  940         {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
  941         {0, 0, 0, 0},
  942 };
  943 static kobj_method_t feeder_sign16le_methods[] = {
  944         KOBJMETHOD(feeder_feed, feed_sign16le),
  945         {0, 0}
  946 };
  947 FEEDER_DECLARE(feeder_sign16le, 0, NULL);
  948 
  949 static int
  950 feed_sign24le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  951                         uint32_t count, void *source)
  952 {
  953         int i, j = FEEDER_FEED(f->source, c, b, count, source);
  954 
  955         if (j < 3) {
  956                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  957                                 __func__, j);
  958                 return 0;
  959         }
  960         FMT_TEST(j % 3, "%s: Bytes not 24bit aligned.\n", __func__);
  961         FMT_ALIGNBYTE(j -= j % 3);
  962         i = j;
  963         while (i > 0) {
  964                 b[--i] ^= 0x80;
  965                 i -= 2;
  966         }
  967         return j;
  968 }
  969 static struct pcm_feederdesc feeder_sign24le_desc[] = {
  970         {FEEDER_FMT, AFMT_U24_LE, AFMT_S24_LE, 0},
  971         {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0},
  972         {FEEDER_FMT, AFMT_S24_LE, AFMT_U24_LE, 0},
  973         {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_U24_LE|AFMT_STEREO, 0},
  974         {0, 0, 0, 0},
  975 };
  976 static kobj_method_t feeder_sign24le_methods[] = {
  977         KOBJMETHOD(feeder_feed, feed_sign24le),
  978         {0, 0}
  979 };
  980 FEEDER_DECLARE(feeder_sign24le, 0, NULL);
  981 
  982 static int
  983 feed_sign32le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
  984                         uint32_t count, void *source)
  985 {
  986         int i, j = FEEDER_FEED(f->source, c, b, count, source);
  987 
  988         if (j < 4) {
  989                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
  990                                 __func__, j);
  991                 return 0;
  992         }
  993         FMT_TEST(j & 3, "%s: Bytes not 32bit aligned.\n", __func__);
  994         FMT_ALIGNBYTE(j &= ~3);
  995         i = j;
  996         while (i > 0) {
  997                 b[--i] ^= 0x80;
  998                 i -= 3;
  999         }
 1000         return j;
 1001 }
 1002 static struct pcm_feederdesc feeder_sign32le_desc[] = {
 1003         {FEEDER_FMT, AFMT_U32_LE, AFMT_S32_LE, 0},
 1004         {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_S32_LE|AFMT_STEREO, 0},
 1005         {FEEDER_FMT, AFMT_S32_LE, AFMT_U32_LE, 0},
 1006         {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_U32_LE|AFMT_STEREO, 0},
 1007         {0, 0, 0, 0},
 1008 };
 1009 static kobj_method_t feeder_sign32le_methods[] = {
 1010         KOBJMETHOD(feeder_feed, feed_sign32le),
 1011         {0, 0}
 1012 };
 1013 FEEDER_DECLARE(feeder_sign32le, 0, NULL);
 1014 /*
 1015  * Sign conversion end.
 1016  */
 1017 
 1018 /*
 1019  * Endian conversion.
 1020  */
 1021 static int
 1022 feed_endian16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
 1023                         uint32_t count, void *source)
 1024 {
 1025         int i, j = FEEDER_FEED(f->source, c, b, count, source);
 1026         uint8_t v;
 1027 
 1028         if (j < 2) {
 1029                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
 1030                                 __func__, j);
 1031                 return 0;
 1032         }
 1033         FMT_TEST(j & 1, "%s: Bytes not 16bit aligned.\n", __func__);
 1034         FMT_ALIGNBYTE(j &= ~1);
 1035         i = j;
 1036         while (i > 0) {
 1037                 v = b[--i];
 1038                 b[i] = b[i - 1];
 1039                 b[--i] = v;
 1040         }
 1041         return j;
 1042 }
 1043 static struct pcm_feederdesc feeder_endian16_desc[] = {
 1044         {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_BE, 0},
 1045         {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U16_BE|AFMT_STEREO, 0},
 1046         {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_BE, 0},
 1047         {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S16_BE|AFMT_STEREO, 0},
 1048         {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_LE, 0},
 1049         {FEEDER_FMT, AFMT_U16_BE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
 1050         {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_LE, 0},
 1051         {FEEDER_FMT, AFMT_S16_BE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
 1052         {0, 0, 0, 0},
 1053 };
 1054 static kobj_method_t feeder_endian16_methods[] = {
 1055         KOBJMETHOD(feeder_feed, feed_endian16),
 1056         {0, 0}
 1057 };
 1058 FEEDER_DECLARE(feeder_endian16, 0, NULL);
 1059 
 1060 static int
 1061 feed_endian24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
 1062                         uint32_t count, void *source)
 1063 {
 1064         int i, j = FEEDER_FEED(f->source, c, b, count, source);
 1065         uint8_t v;
 1066 
 1067         if (j < 3) {
 1068                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
 1069                                 __func__, j);
 1070                 return 0;
 1071         }
 1072         FMT_TEST(j % 3, "%s: Bytes not 24bit aligned.\n", __func__);
 1073         FMT_ALIGNBYTE(j -= j % 3);
 1074         i = j;
 1075         while (i > 0) {
 1076                 v = b[--i];
 1077                 b[i] = b[i - 2];
 1078                 b[i -= 2] = v;
 1079         }
 1080         return j;
 1081 }
 1082 static struct pcm_feederdesc feeder_endian24_desc[] = {
 1083         {FEEDER_FMT, AFMT_U24_LE, AFMT_U24_BE, 0},
 1084         {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_U24_BE|AFMT_STEREO, 0},
 1085         {FEEDER_FMT, AFMT_S24_LE, AFMT_S24_BE, 0},
 1086         {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_S24_BE|AFMT_STEREO, 0},
 1087         {FEEDER_FMT, AFMT_U24_BE, AFMT_U24_LE, 0},
 1088         {FEEDER_FMT, AFMT_U24_BE|AFMT_STEREO, AFMT_U24_LE|AFMT_STEREO, 0},
 1089         {FEEDER_FMT, AFMT_S24_BE, AFMT_S24_LE, 0},
 1090         {FEEDER_FMT, AFMT_S24_BE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0},
 1091         {0, 0, 0, 0},
 1092 };
 1093 static kobj_method_t feeder_endian24_methods[] = {
 1094         KOBJMETHOD(feeder_feed, feed_endian24),
 1095         {0, 0}
 1096 };
 1097 FEEDER_DECLARE(feeder_endian24, 0, NULL);
 1098 
 1099 static int
 1100 feed_endian32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
 1101                         uint32_t count, void *source)
 1102 {
 1103         int i, j = FEEDER_FEED(f->source, c, b, count, source);
 1104         uint8_t l, m;
 1105 
 1106         if (j < 4) {
 1107                 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
 1108                                 __func__, j);
 1109                 return 0;
 1110         }
 1111         FMT_TEST(j & 3, "%s: Bytes not 32bit aligned.\n", __func__);
 1112         FMT_ALIGNBYTE(j &= ~3);
 1113         i = j;
 1114         while (i > 0) {
 1115                 l = b[--i];
 1116                 m = b[--i];
 1117                 b[i] = b[i - 1];
 1118                 b[i + 1] = b[i - 2];
 1119                 b[--i] = m;
 1120                 b[--i] = l;
 1121         }
 1122         return j;
 1123 }
 1124 static struct pcm_feederdesc feeder_endian32_desc[] = {
 1125         {FEEDER_FMT, AFMT_U32_LE, AFMT_U32_BE, 0},
 1126         {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_U32_BE|AFMT_STEREO, 0},
 1127         {FEEDER_FMT, AFMT_S32_LE, AFMT_S32_BE, 0},
 1128         {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_S32_BE|AFMT_STEREO, 0},
 1129         {FEEDER_FMT, AFMT_U32_BE, AFMT_U32_LE, 0},
 1130         {FEEDER_FMT, AFMT_U32_BE|AFMT_STEREO, AFMT_U32_LE|AFMT_STEREO, 0},
 1131         {FEEDER_FMT, AFMT_S32_BE, AFMT_S32_LE, 0},
 1132         {FEEDER_FMT, AFMT_S32_BE|AFMT_STEREO, AFMT_S32_LE|AFMT_STEREO, 0},
 1133         {0, 0, 0, 0},
 1134 };
 1135 static kobj_method_t feeder_endian32_methods[] = {
 1136         KOBJMETHOD(feeder_feed, feed_endian32),
 1137         {0, 0}
 1138 };
 1139 FEEDER_DECLARE(feeder_endian32, 0, NULL);
 1140 /*
 1141  * Endian conversion end
 1142  */

Cache object: 0de6c0f53673813d50f157e885770854


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.