mirror of
https://gitee.com/openharmony/third_party_libsnd
synced 2024-11-23 09:59:54 +00:00
ba8a7577c6
This work was originally submitted by Diemo Schwarz <schwarz@ircam.fr> in PR https://github.com/erikd/libsndfile/pull/197 which was rebased and cleaned up. Closes: https://github.com/erikd/libsndfile/pull/197
136 lines
3.0 KiB
C
136 lines
3.0 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;
|
|
}
|