1 /* libSoX effect: Upsample (zero stuff)    (c) 2011 robs@users.sourceforge.net
2  *
3  * Sometimes filters perform better at higher sampling rates, so e.g.
4  *   sox -r 48k input output upsample 4 filter rate 48k vol 4
5  *
6  * This library is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or (at
9  * your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20 
21 #include "sox_i.h"
22 
23 typedef struct {unsigned factor, pos;} priv_t;
24 
create(sox_effect_t * effp,int argc,char ** argv)25 static int create(sox_effect_t * effp, int argc, char * * argv)
26 {
27   priv_t * p = (priv_t *)effp->priv;
28   p->factor = 2;
29   --argc, ++argv;
30   do {NUMERIC_PARAMETER(factor, 1, 256)} while (0);
31   return argc? lsx_usage(effp) : SOX_SUCCESS;
32 }
33 
start(sox_effect_t * effp)34 static int start(sox_effect_t * effp)
35 {
36   priv_t * p = (priv_t *) effp->priv;
37   effp->out_signal.rate = effp->in_signal.rate * p->factor;
38   return p->factor == 1? SOX_EFF_NULL : SOX_SUCCESS;
39 }
40 
flow(sox_effect_t * effp,const sox_sample_t * ibuf,sox_sample_t * obuf,size_t * isamp,size_t * osamp)41 static int flow(sox_effect_t * effp, const sox_sample_t * ibuf,
42     sox_sample_t * obuf, size_t * isamp, size_t * osamp)
43 {
44   priv_t * p = (priv_t *)effp->priv;
45   size_t ilen = *isamp, olen = *osamp;
46   while (sox_true) {
47     for (; p->pos && olen; p->pos = (p->pos + 1) % p->factor, --olen)
48       *obuf++ = 0;
49     if (!ilen || !olen)
50       break;
51     *obuf++ = *ibuf++;
52     --olen, --ilen;
53     ++p->pos;
54   }
55   *isamp -= ilen, *osamp -= olen;
56   return SOX_SUCCESS;
57 }
58 
lsx_upsample_effect_fn(void)59 sox_effect_handler_t const * lsx_upsample_effect_fn(void)
60 {
61   static sox_effect_handler_t handler = {"upsample", "[factor (2)]",
62     SOX_EFF_RATE | SOX_EFF_MODIFY, create, start, flow, NULL, NULL, NULL, sizeof(priv_t)};
63   return &handler;
64 }
65