1 2#include "sfconfig.h" 3 4#include <stdio.h> 5#include <stdlib.h> 6#include <math.h> 7#include <sndfile.h> 8 9 10static void * 11get_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 61static void 62test_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 88static void 89print_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 120int 121main (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