1 /* June 1, 1992
2 * Copyright 1992 Guido van Rossum And Sundry Contributors
3 * This source code is freely redistributable and may be used for
4 * any purpose. This copyright notice must be maintained.
5 * Guido van Rossum And Sundry Contributors are not responsible for
6 * the consequences of using this software.
7 */
8
9 /*
10 * "reverse" effect, uses a temporary file created by lsx_tmpfile().
11 */
12
13 #include "sox_i.h"
14 #include <string.h>
15
16 typedef struct {
17 off_t pos;
18 FILE * tmp_file;
19 } priv_t;
20
start(sox_effect_t * effp)21 static int start(sox_effect_t * effp)
22 {
23 priv_t * p = (priv_t *)effp->priv;
24 p->pos = 0;
25 p->tmp_file = lsx_tmpfile();
26 if (p->tmp_file == NULL) {
27 lsx_fail("can't create temporary file: %s", strerror(errno));
28 return SOX_EOF;
29 }
30 return SOX_SUCCESS;
31 }
32
flow(sox_effect_t * effp,const sox_sample_t * ibuf,sox_sample_t * obuf,size_t * isamp,size_t * osamp)33 static int flow(sox_effect_t * effp, const sox_sample_t * ibuf,
34 sox_sample_t * obuf, size_t * isamp, size_t * osamp)
35 {
36 priv_t * p = (priv_t *)effp->priv;
37 if (fwrite(ibuf, sizeof(*ibuf), *isamp, p->tmp_file) != *isamp) {
38 lsx_fail("error writing temporary file: %s", strerror(errno));
39 return SOX_EOF;
40 }
41 (void)obuf, *osamp = 0; /* samples not output until drain */
42 return SOX_SUCCESS;
43 }
44
drain(sox_effect_t * effp,sox_sample_t * obuf,size_t * osamp)45 static int drain(sox_effect_t * effp, sox_sample_t *obuf, size_t *osamp)
46 {
47 priv_t * p = (priv_t *)effp->priv;
48 int i, j;
49
50 if (p->pos == 0) {
51 fflush(p->tmp_file);
52 p->pos = ftello(p->tmp_file);
53 if (p->pos % sizeof(sox_sample_t) != 0) {
54 lsx_fail("temporary file has incorrect size");
55 return SOX_EOF;
56 }
57 p->pos /= sizeof(sox_sample_t);
58 }
59 p->pos -= *osamp = min((off_t)*osamp, p->pos);
60 fseeko(p->tmp_file, (off_t)(p->pos * sizeof(sox_sample_t)), SEEK_SET);
61 if (fread(obuf, sizeof(sox_sample_t), *osamp, p->tmp_file) != *osamp) {
62 lsx_fail("error reading temporary file: %s", strerror(errno));
63 return SOX_EOF;
64 }
65 for (i = 0, j = *osamp - 1; i < j; ++i, --j) { /* reverse the samples */
66 sox_sample_t temp = obuf[i];
67 obuf[i] = obuf[j];
68 obuf[j] = temp;
69 }
70 return p->pos? SOX_SUCCESS : SOX_EOF;
71 }
72
stop(sox_effect_t * effp)73 static int stop(sox_effect_t * effp)
74 {
75 priv_t * p = (priv_t *)effp->priv;
76 fclose(p->tmp_file); /* auto-deleted by lsx_tmpfile */
77 return SOX_SUCCESS;
78 }
79
lsx_reverse_effect_fn(void)80 sox_effect_handler_t const * lsx_reverse_effect_fn(void)
81 {
82 static sox_effect_handler_t handler = {
83 "reverse", NULL, SOX_EFF_MODIFY, NULL, start, flow, drain, stop, NULL, sizeof(priv_t)
84 };
85 return &handler;
86 }
87