1 /* libSoX effect: Skeleton effect used as sample for creating new effects.
2  *
3  * Copyright 1999-2008 Chris Bagwell And SoX Contributors
4  *
5  * This library is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation; either version 2.1 of the License, or (at
8  * your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this library; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 
20 #include "sox_i.h"
21 
22 /* Private data for effect */
23 typedef struct {
24   int  localdata;
25 } priv_t;
26 
27 /*
28  * Process command-line options but don't do other
29  * initialization now: effp->in_signal & effp->out_signal are not
30  * yet filled in.
31  */
getopts(sox_effect_t * effp,int argc,char UNUSED ** argv)32 static int getopts(sox_effect_t * effp, int argc, char UNUSED **argv)
33 {
34   priv_t * UNUSED p = (priv_t *)effp->priv;
35 
36   if (argc != 2)
37     return lsx_usage(effp);
38 
39   p->localdata = atoi(argv[1]);
40 
41   return p->localdata > 0 ? SOX_SUCCESS : SOX_EOF;
42 }
43 
44 /*
45  * Prepare processing.
46  * Do all initializations.
47  */
start(sox_effect_t * effp)48 static int start(sox_effect_t * effp)
49 {
50   if (effp->out_signal.channels == 1) {
51     lsx_fail("Can't run on mono data.");
52     return SOX_EOF;
53   }
54 
55   return SOX_SUCCESS;
56 }
57 
58 /*
59  * Process up to *isamp samples from ibuf and produce up to *osamp samples
60  * in obuf.  Write back the actual numbers of samples to *isamp and *osamp.
61  * Return SOX_SUCCESS or, if error occurs, SOX_EOF.
62  */
flow(sox_effect_t * effp,const sox_sample_t * ibuf,sox_sample_t * obuf,size_t * isamp,size_t * osamp)63 static int flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf,
64                            size_t *isamp, size_t *osamp)
65 {
66   priv_t * UNUSED p = (priv_t *)effp->priv;
67   size_t len, done;
68 
69   switch (effp->out_signal.channels) {
70   case 2:
71     /* Length to process will be buffer length / 2 since we
72      * work with two samples at a time.
73      */
74     len = min(*isamp, *osamp) / 2;
75     for (done = 0; done < len; done++)
76       {
77         obuf[0] = ibuf[0];
78         obuf[1] = ibuf[1];
79         /* Advance buffer by 2 samples */
80         ibuf += 2;
81         obuf += 2;
82       }
83 
84     *isamp = len * 2;
85     *osamp = len * 2;
86 
87     break;
88   }
89 
90   return SOX_SUCCESS;
91 }
92 
93 /*
94  * Drain out remaining samples if the effect generates any.
95  */
drain(sox_effect_t UNUSED * effp,sox_sample_t UNUSED * obuf,size_t * osamp)96 static int drain(sox_effect_t UNUSED * effp, sox_sample_t UNUSED *obuf, size_t *osamp)
97 {
98   *osamp = 0;
99   /* Return SOX_EOF when drain
100    * will not output any more samples.
101    * *osamp == 0 also indicates that.
102    */
103   return SOX_EOF;
104 }
105 
106 /*
107  * Do anything required when you stop reading samples.
108  */
stop(sox_effect_t UNUSED * effp)109 static int stop(sox_effect_t UNUSED * effp)
110 {
111   return SOX_SUCCESS;
112 }
113 
114 /*
115  * Do anything required when you kill an effect.
116  *      (free allocated memory, etc.)
117  */
lsx_kill(sox_effect_t UNUSED * effp)118 static int lsx_kill(sox_effect_t UNUSED * effp)
119 {
120   return SOX_SUCCESS;
121 }
122 
123 /*
124  * Function returning effect descriptor. This should be the only
125  * externally visible object.
126  */
127 const sox_effect_handler_t *lsx_skel_effect_fn(void);
lsx_skel_effect_fn(void)128 const sox_effect_handler_t *lsx_skel_effect_fn(void)
129 {
130   /*
131    * Effect descriptor.
132    * If no specific processing is needed for any of
133    * the 6 functions, then the function above can be deleted
134    * and NULL used in place of the its name below.
135    */
136   static sox_effect_handler_t sox_skel_effect = {
137     "skel", "[OPTION]", SOX_EFF_MCHAN,
138     getopts, start, flow, drain, stop, lsx_kill, sizeof(priv_t)
139   };
140   return &sox_skel_effect;
141 }
142