void* _ambix_read_chunk(ambix_t*ax, uint32_t id, uint32_t chunk_it, int64_t *datasize) { #if defined HAVE_SF_GET_CHUNK_ITERATOR int err; SF_CHUNK_INFO chunk_info; SF_CHUNK_ITERATOR * iterator; int i; memset (&chunk_info, 0, sizeof (chunk_info)); memcpy(chunk_info.id, &id, 4); chunk_info.id_size = 4; iterator = sf_get_chunk_iterator (PRIVATE(ax)->sf_file, &chunk_info); if (!iterator) { *datasize = 0; return NULL; } // jump to wanted iterator for (i=0; i<chunk_it; i++) { iterator = sf_next_chunk_iterator (iterator) ; if (!iterator) { *datasize = 0; return NULL; } } memset (&chunk_info, 0, sizeof (chunk_info)); err = sf_get_chunk_size (iterator, &chunk_info); if (!chunk_info.datalen) { *datasize = 0; return NULL; } chunk_info.data = malloc (chunk_info.datalen); // has to be freed later by the caller! err = sf_get_chunk_data (iterator, &chunk_info); // free (chunk_info.data); *datasize = chunk_info.datalen; return chunk_info.data; #endif *datasize = 0; return NULL; }
static void chunk_test_helper (const char *filename, int typemajor, const char * testdata) { SNDFILE *file ; SF_INFO sfinfo ; SF_CHUNK_INFO chunk_info ; uint32_t length_before ; int err ; sfinfo.samplerate = 44100 ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; switch (typemajor) { case SF_FORMAT_OGG : sfinfo.format = typemajor | SF_FORMAT_VORBIS ; break ; default : sfinfo.format = typemajor | SF_FORMAT_PCM_16 ; break ; } ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; /* Set up the chunk to write. */ memset (&chunk_info, 0, sizeof (chunk_info)) ; snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ; chunk_info.id_size = 4 ; chunk_info.data = strdup (testdata) ; chunk_info.datalen = strlen (chunk_info.data) ; length_before = chunk_info.datalen ; err = sf_set_chunk (file, &chunk_info) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_set_chunk returned for testdata '%s' : %s\n", __LINE__, testdata, sf_error_number (err) ) ; memset (chunk_info.data, 0, chunk_info.datalen) ; free (chunk_info.data) ; sf_close (file) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; memset (&chunk_info, 0, sizeof (chunk_info)) ; snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ; chunk_info.id_size = 4 ; err = sf_get_chunk_size (file, &chunk_info) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_get_chunk_size returned for testdata '%s' : %s", __LINE__, testdata, sf_error_number (err) ) ; exit_if_true ( length_before > chunk_info.datalen || chunk_info.datalen - length_before > 4, "\n\nLine %d : testdata '%s' : Bad chunk length %u (previous length %u)\n", __LINE__, testdata, chunk_info.datalen, length_before ) ; chunk_info.data = malloc (chunk_info.datalen) ; err = sf_get_chunk_data (file, &chunk_info) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_get_chunk_size returned for testdata '%s' : %s", __LINE__, testdata, sf_error_number (err) ) ; exit_if_true ( memcmp (testdata, chunk_info.data, length_before), "\n\nLine %d : Data compare failed.\n %s\n %s\n\n", __LINE__, testdata, (char*) chunk_info.data ) ; free (chunk_info.data) ; sf_close (file) ; unlink (filename) ; } /* chunk_test_helper */
static int read_uuidchunk(ambix_t*ax) { #if defined HAVE_SF_GET_CHUNK_ITERATOR && defined (HAVE_SF_CHUNK_INFO) int err ; SF_CHUNK_INFO chunk_info ; SNDFILE*file=PRIVATE(ax)->sf_file; SF_CHUNK_ITERATOR *iterator; uint32_t chunkver=0; const char*id="uuid"; memset (&chunk_info, 0, sizeof (chunk_info)) ; snprintf (chunk_info.id, sizeof (chunk_info.id), "%s", id) ; chunk_info.id_size = 4 ; for(iterator = sf_get_chunk_iterator (file, &chunk_info); NULL!=iterator; iterator=sf_next_chunk_iterator (iterator)) { if(chunk_info.data) free(chunk_info.data); chunk_info.data=NULL; err = sf_get_chunk_size (iterator, &chunk_info) ; if(err != SF_ERR_NO_ERROR) { continue; } if(chunk_info.datalen<16) { continue; } chunk_info.data = malloc (chunk_info.datalen) ; if(!chunk_info.data) { return AMBIX_ERR_UNKNOWN; } err = sf_get_chunk_data (iterator, &chunk_info) ; if(err != SF_ERR_NO_ERROR) { continue; } chunkver=_ambix_checkUUID((const char*)chunk_info.data); if(1==chunkver) { if(_ambix_uuid1_to_matrix(((const char*)chunk_info.data+16), chunk_info.datalen-16, &ax->matrix, ax->byteswap)) { if(chunk_info.data) free(chunk_info.data) ; return AMBIX_ERR_SUCCESS; } } else continue; } if(chunk_info.data) free(chunk_info.data) ; return AMBIX_ERR_UNKNOWN; #elif defined HAVE_SF_UUID_INFO SF_UUID_INFO uuid; SNDFILE*file=PRIVATE(ax)->sf_file; memset(&uuid, 0, sizeof(uuid)); strncpy(uuid.id, _ambix_getUUID(1), 16); if ( !sf_command(file, SFC_GET_UUID, &uuid, sizeof(uuid)) ) { // extended if(_ambix_uuid1_to_matrix(uuid.data, uuid.data_size, &ax->matrix, ax->byteswap)) { return AMBIX_ERR_SUCCESS; } } #endif return AMBIX_ERR_UNKNOWN; }
static void multichunk_test_helper (const char *filename, int format, const char * testdata [], size_t testdata_len) { SNDFILE *file ; SF_INFO sfinfo ; SF_CHUNK_INFO chunk_info ; SF_CHUNK_ITERATOR * iterator ; uint32_t length_before [16] ; int err, allow_fd ; size_t i ; exit_if_true ( ARRAY_LEN (length_before) < testdata_len, "\n\nLine %d : Bad array length.\n\n", __LINE__ ) ; sfinfo.samplerate = 44100 ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; sfinfo.format = format ; switch (format & SF_FORMAT_SUBMASK) { case SF_FORMAT_ALAC_16 : allow_fd = SF_FALSE ; break ; default : allow_fd = SF_TRUE ; break ; } ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ; /* Set up the chunk to write. */ for (i = 0 ; i < testdata_len ; i++) { memset (&chunk_info, 0, sizeof (chunk_info)) ; snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ; chunk_info.id_size = 4 ; chunk_info.data = strdup (testdata [i]) ; chunk_info.datalen = strlen (chunk_info.data) ; length_before [i] = chunk_info.datalen ; err = sf_set_chunk (file, &chunk_info) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_set_chunk returned for testdata[%d] '%s' : %s\n\n", __LINE__, (int) i, testdata [i], sf_error_number (err) ) ; memset (chunk_info.data, 0, chunk_info.datalen) ; free (chunk_info.data) ; } sf_close (file) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ; memset (&chunk_info, 0, sizeof (chunk_info)) ; snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ; chunk_info.id_size = 4 ; iterator = sf_get_chunk_iterator (file, &chunk_info) ; i = 0 ; while (iterator) { memset (&chunk_info, 0, sizeof (chunk_info)) ; err = sf_get_chunk_size (iterator, &chunk_info) ; exit_if_true ( i > testdata_len, "\n\nLine %d : iterated to chunk #%d, but only %d chunks have been written\n\n", __LINE__, (int) i, (int) testdata_len ) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_get_chunk_size returned for testdata[%d] '%s' : %s\n\n", __LINE__, (int) i, testdata [i], sf_error_number (err) ) ; exit_if_true ( length_before [i] > chunk_info.datalen || chunk_info.datalen - length_before [i] > 4, "\n\nLine %d : testdata[%d] '%s' : Bad chunk length %u (previous length %u)\n\n", __LINE__, (int) i, testdata [i], chunk_info.datalen, length_before [i] ) ; chunk_info.data = malloc (chunk_info.datalen) ; err = sf_get_chunk_data (iterator, &chunk_info) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_get_chunk_size returned for testdata[%d] '%s' : %s\n\n", __LINE__, (int) i, testdata [i], sf_error_number (err) ) ; exit_if_true ( 4 != chunk_info.id_size, "\n\nLine %d : testdata[%d] : Bad ID length %u (previous length %u)\n\n", __LINE__, (int) i, chunk_info.id_size, 4 ) ; exit_if_true ( memcmp ("Test", chunk_info.id, 4), "\n\nLine %d : ID compare failed at %d.\n %s\n %s\n\n", __LINE__, (int) i, "Test", (char*) chunk_info.id ) ; exit_if_true ( memcmp (testdata [i], chunk_info.data, length_before [i]), "\n\nLine %d : Data compare failed at %d.\n %s\n %s\n\n", __LINE__, (int) i, testdata [i], (char*) chunk_info.data ) ; free (chunk_info.data) ; iterator = sf_next_chunk_iterator (iterator) ; i++ ; } sf_close (file) ; unlink (filename) ; } /* multichunk_test_helper */