1 /* cmupvdbg.c -- debug support for cmupv
2  * Roger B. Dannenberg
3  * Nov 2015
4  */
5 
6 /* To see what data is going into the phase vocoder, write_pv_frame
7  * saves frames or buffers to disk as audio.
8  * If something is wrong with your applications delivery of analysis frames,
9  * probably most frames are wrong, so you should write, say, 10 initial
10  * files and look at them. Set MAX_FILES to 10 and MAX_SAVE to 10. Then,
11  * after running your program, use Audacity to open the 10 frames saved
12  * to disk: use the Files:Import:Audio command to load all 10 in one
13  * command as different tracks. You should see 10 tracks, each containing
14  * one frame, shifted to the correct source time location. (If not, then
15  * find and fix the bug.)
16  *
17  * This function is also useful for printing other data, e.g. synthesis frames
18  * or output buffers. To get the most out of this, you should set the first
19  * parameter, zeros, to the absolute sample offset, e.g. if you want to view
20  * synthesis frames that are spaced with a 64 sample hop size, you should set
21  * zeros to 0, 64, 128, 192, ... so that when you view the files in Audacity,
22  * the samples will line up in time with each other and with the output file.
23  *
24  * You can display multiple frame types and lengths, so the prefix parameter
25  * allows you to effectively label the data. This prefix is used to construct
26  * the file name.
27  *
28  * MAX_FILES tells how many files to write. Because of padding, file writing
29  * is an N-squared operation, so only write initial frames if possible, but
30  * use a large number if you need to see everything.
31  *
32  * MAX_SAVE tells how many file *names* to use. Files are numbered, so we'll
33  * simply take the number modulo MAX_SAVE so that file names are reused and
34  * old files are overwritten. Use a large value of MAX_SAVE to save everything.
35  * Use 1 to get only the last frame.
36  */
37 
38 #include "stdio.h"
39 #include "sndfile.h"
40 
41 
42 #define MAX_FILES 10
43 #define MAX_SAVE 10
44 static int file_no = 0;
45 
46 
write_pv_frame(long zeros,float * frame,long fftsize,char * prefix)47 void write_pv_frame(long zeros, float *frame, long fftsize, char *prefix)
48 {
49     float z = 0;
50     char path[128];
51     SF_INFO sfinfo;
52     SNDFILE *sf;
53     if (file_no >= MAX_FILES) return;
54     sprintf(path, "%s-%02d.wav", prefix, (file_no % MAX_SAVE) + 1);
55     sfinfo.frames = 0;
56     sfinfo.samplerate = 44100;
57     sfinfo.channels = 1;
58     sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
59     sfinfo.sections = 0;
60     sfinfo.seekable = 0;
61     sf = sf_open(path, SFM_WRITE, &sfinfo);
62     for (long i = 0; i < zeros; i++) {
63         sf_writef_float(sf, &z, 1);
64     }
65     sf_writef_float(sf, frame, fftsize);
66     sf_close(sf);
67     printf("wrote %s, %ld zeros\n", path, zeros);
68     file_no++;
69 }
70