1
2 #include "sfconfig.h"
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <math.h>
7 #include <sndfile.h>
8
9
10 static void *
get_cues(const char * filename,double * sr)11 get_cues (const char *filename, double *sr)
12 {
13 SNDFILE *file;
14 SF_INFO sfinfo;
15
16 unsigned int err, size;
17 uint32_t count = 0;
18 SF_CUES_VAR(0) *info;
19
20 if ((file = sf_open(filename, SFM_READ, &sfinfo)) == NULL)
21 {
22 printf("can't open file '%s'\n", filename);
23 exit(1);
24 }
25
26 printf("\n---- get cues of file '%s'\n", filename);
27
28 if ((err = sf_command(file, SFC_GET_CUE_COUNT, &count, sizeof(uint32_t))) == SF_FALSE)
29 {
30 if (sf_error(file))
31 {
32 printf("can't get cue info size for file '%s' (arg size %lu), err %s\n",
33 filename, sizeof(uint32_t), sf_strerror(file));
34 exit(2);
35 }
36 else
37 printf("no cue info for file '%s'\n", filename);
38 return NULL;
39 }
40
41 size = sizeof(*info) + count * sizeof(SF_CUE_POINT);
42 printf("number of cues %d size %d\n", count, size);
43
44 if (!(info = malloc(size)))
45 return NULL;
46
47 if (sf_command(file, SFC_GET_CUE, info, size) == SF_FALSE)
48 {
49 printf("can't get cue info of size %d for file '%s' error %s\n",
50 size, filename, sf_strerror(file));
51 exit(3);
52 }
53
54 *sr = sfinfo.samplerate;
55 sf_close(file);
56
57 return info;
58 }
59
60
61 static void
test_cues(const char * filename)62 test_cues (const char *filename)
63 {
64 unsigned int i;
65 double sr;
66 SF_CUES_VAR(0) *info = get_cues(filename, &sr);
67
68 if (info == NULL)
69 exit(1);
70
71 for (i = 0; i < info->cue_count; i++)
72 {
73 int pos = info->cue_points[i].position;
74 double t = (double) pos / sr;
75 double expected = i < 8 ? (double) i / 3. : 10. / 3.;
76 double error = (double) fabs(t - expected);
77
78 printf("cue %02d: markerID %02d position %6d offset %6d (time %.3f expected %.3f diff %f) label '%s'\n",
79 i, info->cue_points[i].indx, pos, info->cue_points[i].sample_offset, t, expected, error, info->cue_points[i].name);
80
81 if (error > 0.025)
82 exit(4);
83 }
84
85 free(info);
86 }
87
88 static void
print_cues(const char * filename)89 print_cues (const char *filename)
90 {
91 unsigned int i;
92 double sr;
93 SF_CUES_VAR(0) *info = get_cues(filename, &sr);
94
95 if (info == NULL)
96 exit(1);
97
98 for (i = 0; i < info->cue_count; i++)
99 {
100 int pos = info->cue_points[i].position;
101 int indx = info->cue_points[i].indx;
102 int cstart = info->cue_points[i].chunk_start;
103 int bstart = info->cue_points[i].block_start;
104 int offset = info->cue_points[i].sample_offset;
105 const char *name = info->cue_points[i].name;
106 double t = (double) pos / sr;
107
108 if (cstart != 0 || bstart != 0)
109 printf("cue %02d time %7.3f: markerID %02d position %8d chunk_start %d block_start %d offset %8d label '%s'\n",
110 i, t, indx, pos, offset, cstart, bstart, name);
111 else
112 printf("cue %02d time %7.3f: markerID %02d position %8d offset %8d label '%s'\n",
113 i, t, indx, pos, offset, name);
114 }
115
116 free(info);
117 }
118
119
120 int
main(int argc,char ** argv)121 main (int argc, char **argv)
122 {
123 int i;
124
125 if (argc > 1)
126 for (i = 1; i < argc; i++)
127 print_cues(argv[i]);
128 else
129 {
130 test_cues("clickpluck24.wav");
131 test_cues("clickpluck.wav");
132 test_cues("clickpluck.aiff");
133 }
134 return 0;
135 }
136