• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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