- commit
- 400aebaa8e6b0942aad55146b1f79008aa368be2
- parent
- a5eedb8e9de8c0ddfdca53fb6d769f5e922bb123
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2019-12-17 14:27
use more than one buffer assumes that input is ordered
Diffstat
| M | beat.c | 79 | +++++++++++++++++++++++++++++++++++++++++++------------------ |
1 files changed, 56 insertions, 23 deletions
diff --git a/beat.c b/beat.c
@@ -2,11 +2,16 @@ 2 2 #include <string.h> 3 3 #include <sndfile.h> 4 4 -1 5 #define MIN(A, B) ((A) < (B) ? (A) : (B)) -1 6 5 7 struct context { 6 8 int samplerate; 7 9 int frames_per_beat; // samplerate * 60 / bpm 8 10 int frames; -1 11 int buf_cur; -1 12 size_t buf_len; 9 13 float *buf; -1 14 float *buf2; 10 15 }; 11 16 12 17 void add_file_at_beat(const char *path, int beat, struct context ctx) { @@ -21,37 +26,29 @@ void add_file_at_beat(const char *path, int beat, struct context ctx) { 21 26 22 27 while (1) { 23 28 int count = sf_readf_float(sndfile, fbuf, ibs);24 -125 -1 if (pos + count >= ctx.frames) {26 -1 count = ctx.frames - pos - 1;27 -1 }-1 29 count = MIN(count, ctx.frames - pos - 1); -1 30 int rel_pos = pos - ctx.buf_cur * ctx.buf_len; 28 31 29 32 if (count <= 0) break; 30 33 31 34 for (int i = 0; i < count; ++i) { 32 35 pos += 1;33 -1 ctx.buf[pos] += fbuf[i];-1 36 rel_pos += 1; -1 37 if (rel_pos >= 2 * ctx.buf_len) { -1 38 printf("dropping %s at %i\n", path, pos); -1 39 sf_close(sndfile); -1 40 return; -1 41 } else if (rel_pos >= ctx.buf_len) { -1 42 ctx.buf2[rel_pos - ctx.buf_len] += fbuf[i]; -1 43 } else { -1 44 ctx.buf[rel_pos] += fbuf[i]; -1 45 } 34 46 } 35 47 } 36 48 37 49 sf_close(sndfile); 38 50 } 39 5140 -1 void write_file(const char *path, struct context ctx) {41 -1 SF_INFO sfinfo;42 -143 -1 sfinfo.channels = 1;44 -1 sfinfo.format = SF_FORMAT_FLAC | SF_FORMAT_PCM_16;45 -1 sfinfo.frames = ctx.frames;46 -1 sfinfo.samplerate = ctx.samplerate;47 -1 sfinfo.sections = 1;48 -1 sfinfo.seekable = 1;49 -150 -1 SNDFILE *sndfile = sf_open(path, SFM_WRITE, &sfinfo);51 -1 sf_writef_float(sndfile, ctx.buf, ctx.frames);52 -1 sf_close(sndfile);53 -1 }54 -155 52 int main(int argc, char **argv) { 56 53 if (argc < 6 || argc % 2 != 1) { 57 54 printf("Usage: beat OUTFILE SAMPLERATE FRAMES_PER_BEAT BEATS BEAT INFILE [BEAT INFILEā¦]\n"); @@ -64,15 +61,51 @@ int main(int argc, char **argv) { 64 61 ctx.frames_per_beat = atoi(argv[3]); 65 62 ctx.frames = atoi(argv[4]) * ctx.frames_per_beat; 66 6367 -1 float buf[ctx.frames];68 -1 memset(buf, 0, ctx.frames * sizeof(float));-1 64 ctx.buf_len = MIN(ctx.frames / 4, 1 << 18); -1 65 ctx.buf_cur = 0; -1 66 -1 67 float buf[ctx.buf_len]; -1 68 memset(buf, 0, ctx.buf_len * sizeof(float)); 69 69 ctx.buf = buf; 70 70 -1 71 float buf2[ctx.buf_len]; -1 72 memset(buf2, 0, ctx.buf_len * sizeof(float)); -1 73 ctx.buf2 = buf2; -1 74 -1 75 SF_INFO sfinfo; -1 76 sfinfo.channels = 1; -1 77 sfinfo.format = SF_FORMAT_FLAC | SF_FORMAT_PCM_16; -1 78 sfinfo.frames = ctx.frames; -1 79 sfinfo.samplerate = ctx.samplerate; -1 80 sfinfo.sections = 1; -1 81 sfinfo.seekable = 1; -1 82 -1 83 SNDFILE *sndfile = sf_open(argv[1], SFM_WRITE, &sfinfo); -1 84 71 85 for (int i = 5; i + 1 < argc; i += 2) { 72 86 int beat = atoi(argv[i]); 73 87 char *path = argv[i + 1]; -1 88 -1 89 if (beat * ctx.frames_per_beat >= (ctx.buf_cur + 1) * ctx.buf_len) { -1 90 sf_writef_float(sndfile, ctx.buf, ctx.buf_len); -1 91 memset(ctx.buf, 0, ctx.buf_len * sizeof(float)); -1 92 -1 93 float *tmp = ctx.buf; -1 94 ctx.buf = ctx.buf2; -1 95 ctx.buf2 = tmp; -1 96 ctx.buf_cur += 1; -1 97 } -1 98 74 99 add_file_at_beat(path, beat, ctx); 75 100 } 76 10177 -1 write_file(argv[1], ctx);-1 102 int rest = ctx.frames - ctx.buf_cur * ctx.buf_len; -1 103 if (rest > ctx.buf_len) { -1 104 sf_writef_float(sndfile, ctx.buf, ctx.buf_len); -1 105 sf_writef_float(sndfile, ctx.buf2, rest - ctx.buf_len); -1 106 } else { -1 107 sf_writef_float(sndfile, ctx.buf, rest); -1 108 } -1 109 -1 110 sf_close(sndfile); 78 111 }