136 lines
		
	
	
		
			3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			136 lines
		
	
	
		
			3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | 
 | ||
|  | #include "sfconfig.h"
 | ||
|  | 
 | ||
|  | #include <stdio.h>
 | ||
|  | #include <stdlib.h>
 | ||
|  | #include <math.h>
 | ||
|  | #include <sndfile.h>
 | ||
|  | 
 | ||
|  | 
 | ||
|  | static void * | ||
|  | get_cues (const char *filename, double *sr) | ||
|  | { | ||
|  |     SNDFILE    *file; | ||
|  |     SF_INFO	sfinfo; | ||
|  | 
 | ||
|  |     unsigned int err, size; | ||
|  |     uint32_t count = 0; | ||
|  |     SF_CUES_VAR(0) *info; | ||
|  | 
 | ||
|  |     if ((file = sf_open(filename, SFM_READ, &sfinfo)) == NULL) | ||
|  |     { | ||
|  | 	printf("can't open file '%s'\n", filename); | ||
|  | 	exit(1); | ||
|  |     } | ||
|  | 
 | ||
|  |     printf("\n---- get cues of file '%s'\n", filename); | ||
|  | 
 | ||
|  |     if ((err = sf_command(file, SFC_GET_CUE_COUNT, &count, sizeof(uint32_t))) == SF_FALSE) | ||
|  |     { | ||
|  | 	if (sf_error(file)) | ||
|  | 	{ | ||
|  | 	    printf("can't get cue info size for file '%s' (arg size %lu), err %s\n",  | ||
|  | 		   filename, sizeof(uint32_t), sf_strerror(file)); | ||
|  | 	    exit(2); | ||
|  | 	} | ||
|  | 	else | ||
|  | 	    printf("no cue info for file '%s'\n", filename); | ||
|  | 	return NULL; | ||
|  |     } | ||
|  | 	 | ||
|  |     size = sizeof(*info) + count * sizeof(SF_CUE_POINT); | ||
|  |     printf("number of cues %d  size %d\n", count, size); | ||
|  | 
 | ||
|  |     if (!(info = malloc(size))) | ||
|  | 	return NULL; | ||
|  | 
 | ||
|  |     if (sf_command(file, SFC_GET_CUE, info, size) == SF_FALSE) | ||
|  |     { | ||
|  | 	printf("can't get cue info of size %d for file '%s' error %s\n",  | ||
|  | 	       size, filename, sf_strerror(file)); | ||
|  | 	exit(3); | ||
|  |     } | ||
|  | 
 | ||
|  |     *sr = sfinfo.samplerate; | ||
|  |     sf_close(file); | ||
|  | 
 | ||
|  |     return info; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static void | ||
|  | test_cues (const char *filename) | ||
|  | { | ||
|  |     unsigned int i; | ||
|  |     double sr; | ||
|  |     SF_CUES_VAR(0) *info = get_cues(filename, &sr); | ||
|  | 
 | ||
|  |     if (info == NULL) | ||
|  | 	exit(1); | ||
|  |      | ||
|  |     for (i = 0; i < info->cue_count; i++) | ||
|  |     { | ||
|  | 	int    pos = info->cue_points[i].position; | ||
|  | 	double t   = (double) pos / sr; | ||
|  | 	double expected = i < 8  ?  (double) i / 3.  :  10. / 3.; | ||
|  | 	double error = (double) fabs(t - expected); | ||
|  | 
 | ||
|  | 	printf("cue %02d: markerID %02d  position %6d  offset %6d (time %.3f  expected %.3f  diff %f)  label '%s'\n", | ||
|  | 	       i, info->cue_points[i].indx, pos, info->cue_points[i].sample_offset, t, expected, error, info->cue_points[i].name); | ||
|  | 
 | ||
|  | 	if (error > 0.025) | ||
|  | 	    exit(4); | ||
|  |     } | ||
|  | 
 | ||
|  |     free(info); | ||
|  | } | ||
|  | 
 | ||
|  | static void | ||
|  | print_cues (const char *filename) | ||
|  | { | ||
|  |     unsigned int i; | ||
|  |     double sr; | ||
|  |     SF_CUES_VAR(0) *info = get_cues(filename, &sr); | ||
|  | 
 | ||
|  |     if (info == NULL) | ||
|  | 	exit(1); | ||
|  |      | ||
|  |     for (i = 0; i < info->cue_count; i++) | ||
|  |     { | ||
|  | 	int    pos    = info->cue_points[i].position; | ||
|  | 	int    indx   = info->cue_points[i].indx; | ||
|  | 	int    cstart = info->cue_points[i].chunk_start; | ||
|  | 	int    bstart = info->cue_points[i].block_start; | ||
|  | 	int    offset = info->cue_points[i].sample_offset; | ||
|  | 	const char *name = info->cue_points[i].name; | ||
|  | 	double t   = (double) pos / sr; | ||
|  | 
 | ||
|  | 	if (cstart != 0  ||  bstart != 0) | ||
|  | 	    printf("cue %02d time %7.3f: markerID %02d  position %8d  chunk_start %d  block_start %d  offset %8d  label '%s'\n", | ||
|  | 		   i, t, indx, pos, offset, cstart, bstart, name); | ||
|  | 	else | ||
|  | 	    printf("cue %02d  time %7.3f: markerID %02d  position %8d  offset %8d  label '%s'\n", | ||
|  | 		   i, t, indx, pos, offset, name); | ||
|  |     } | ||
|  | 
 | ||
|  |     free(info); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | int | ||
|  | main (int argc, char **argv) | ||
|  | { | ||
|  |     int i; | ||
|  |      | ||
|  |     if (argc > 1) | ||
|  | 	for (i = 1; i < argc; i++) | ||
|  | 	    print_cues(argv[i]); | ||
|  |     else | ||
|  |     { | ||
|  | 	test_cues("clickpluck24.wav"); | ||
|  | 	test_cues("clickpluck.wav"); | ||
|  | 	test_cues("clickpluck.aiff"); | ||
|  |     } | ||
|  |     return 0; | ||
|  | } |