1 /* libSoX effect: Delay one or more channels (c) 2008 robs@users.sourceforge.net
3 * This library is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU Lesser General Public License as published by
5 * the Free Software Foundation; either version 2.1 of the License, or (at
6 * your option) any later version.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11 * General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 char * * argv
, * max_arg
;
24 size_t delay
, pad
, buffer_size
, buffer_index
;
25 sox_sample_t
* buffer
;
28 static int lsx_kill(sox_effect_t
* effp
)
30 priv_t
* p
= (priv_t
*)effp
->priv
;
33 for (i
= 0; i
< p
->argc
; ++i
)
39 static int create(sox_effect_t
* effp
, int argc
, char * * argv
)
41 priv_t
* p
= (priv_t
*)effp
->priv
;
42 size_t delay
, max_samples
= 0;
46 p
->argv
= lsx_calloc(p
->argc
= argc
, sizeof(*p
->argv
));
47 for (i
= 0; i
< p
->argc
; ++i
) {
48 char const * next
= lsx_parsesamples(1e5
, p
->argv
[i
] = lsx_strdup(argv
[i
]), &delay
, 't');
51 return lsx_usage(effp
);
53 if (delay
> max_samples
) {
55 p
->max_arg
= p
->argv
[i
];
61 static int stop(sox_effect_t
* effp
)
63 priv_t
* p
= (priv_t
*)effp
->priv
;
68 static int start(sox_effect_t
* effp
)
70 priv_t
* p
= (priv_t
*)effp
->priv
;
75 if (effp
->flow
< p
->argc
)
76 lsx_parsesamples(effp
->in_signal
.rate
, p
->argv
[effp
->flow
], &p
->buffer_size
, 't');
77 lsx_parsesamples(effp
->in_signal
.rate
, p
->max_arg
, &max_delay
, 't');
78 p
->buffer_index
= p
->delay
= 0;
79 p
->pad
= max_delay
- p
->buffer_size
;
80 p
->buffer
= lsx_malloc(p
->buffer_size
* sizeof(*p
->buffer
));
84 static int flow(sox_effect_t
* effp
, const sox_sample_t
* ibuf
,
85 sox_sample_t
* obuf
, size_t * isamp
, size_t * osamp
)
87 priv_t
* p
= (priv_t
*)effp
->priv
;
88 size_t len
= *isamp
= *osamp
= min(*isamp
, *osamp
);
91 memcpy(obuf
, ibuf
, len
* sizeof(*obuf
));
92 else for (; len
; --len
) {
93 if (p
->delay
< p
->buffer_size
) {
94 p
->buffer
[p
->delay
++] = *ibuf
++;
97 *obuf
++ = p
->buffer
[p
->buffer_index
];
98 p
->buffer
[p
->buffer_index
++] = *ibuf
++;
99 p
->buffer_index
%= p
->buffer_size
;
105 static int drain(sox_effect_t
* effp
, sox_sample_t
* obuf
, size_t * osamp
)
107 priv_t
* p
= (priv_t
*)effp
->priv
;
108 size_t len
= *osamp
= min(p
->delay
+ p
->pad
, *osamp
);
110 for (; p
->delay
&& len
; --p
->delay
, --len
) {
111 *obuf
++ = p
->buffer
[p
->buffer_index
++];
112 p
->buffer_index
%= p
->buffer_size
;
114 for (; p
->pad
&& len
; --p
->pad
, --len
)
119 sox_effect_handler_t
const * lsx_delay_effect_fn(void)
121 static sox_effect_handler_t handler
= {
122 "delay", "{length}", SOX_EFF_LENGTH
| SOX_EFF_MODIFY
,
123 create
, start
, flow
, drain
, stop
, lsx_kill
, sizeof(priv_t
)