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