Exemple #1
0
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;
}
void AudioFileSndfile::open(const char* filename, IAudioFile::Mode mode)
{
    _mode = mode;
    _path = filename;

    if (ModeClosed == mode) {
        return;
    }

    static int sfmode[ModeCount] = {
        0,
        SFM_READ,
        SFM_WRITE,
        SFM_RDWR,
    };

    SF_INFO sfinfo;
    sfinfo.channels = int(_info.channels);
    sfinfo.format = formatConvert(_info.format);
    LOG(DEBUG, "File format before opening: " << sfinfo.format);
    sfinfo.frames = _info.frames;
    sfinfo.samplerate = int(_info.sampleRate);
    sfinfo.seekable = true;
    sfinfo.sections = 0;

    auto psndfile = sf_open(filename, sfmode[mode], &sfinfo);
    auto deleter = [](SNDFILE* handle) { sf_close(handle); };
    _handle = std::shared_ptr<SNDFILE>(psndfile, deleter);

    if (!_handle) {
        int errorNumber = sf_error(NULL);
        SNDFILE_ERROR(errorNumber, "Error opening file handle");
    }

    _mode = mode;

    if (_mode == ModeWrite) {
        return;
    }

    _info.channels = unsigned(sfinfo.channels);
    _info.frames = unsigned(sfinfo.frames);
    _info.sampleRate = unsigned(sfinfo.samplerate);
    _info.seekable = bool(sfinfo.seekable);
    _info.format = formatConvert(sfinfo.format);

    switch (int(_info.format.minor)) {
    case MinorDPCM_8:
    case MinorPCM_S8:
    case MinorPCM_U8:
        _info.sampleType = Sound::Type::Int8;
        break;

    case MinorALAC_20:
    case MinorALAC_24:
    case MinorDWVW_24:
    case MinorPCM_24:
        // 24 bit

    case MinorALAC_32:
    case MinorPCM_32:
        _info.sampleType = Sound::Type::Int32;
        break;

    case MinorDWVW_N:
    case MinorFloat:
    case MinorVorbis:
    // TODO: move following subformats to AudioFileMPG123
    case MinorMPEG1_0_DualChannel:
    case MinorMPEG1_0_JointStereo:
    case MinorMPEG1_0_Mono:
    case MinorMPEG1_0_Stereo:
    case MinorMPEG2_0_DualChannel:
    case MinorMPEG2_0_JointStereo:
    case MinorMPEG2_0_Mono:
    case MinorMPEG2_0_Stereo:
    case MinorMPEG2_5_DualChannel:
    case MinorMPEG2_5_JointStereo:
    case MinorMPEG2_5_Mono:
    case MinorMPEG2_5_Stereo:
        _info.sampleType = Sound::Type::Float32;
        break;

    case MinorDouble:
        _info.sampleType = Sound::Type::Float64;
        break;

    default:
        _info.sampleType = Sound::Type::Int16;
    }

    // unknown chunks
    SF_CHUNK_ITERATOR* it = sf_get_chunk_iterator(_handle.get(), NULL);
    SF_CHUNK_INFO sfci;
    memset(&sfci, 0, sizeof sfci);
    _rawChunksData.clear();

    while (it) {
        int errorNumber = sf_get_chunk_data(it, &sfci);

        if (errorNumber) {
            SNDFILE_ERROR(errorNumber, "Error reading chunk data");
        }

        std::string id(sfci.id, sfci.id_size);
        std::vector<ChunkData> data;
        data.assign(reinterpret_cast<ChunkData*>(sfci.data),
            reinterpret_cast<ChunkData*>(sfci.data) + sfci.datalen);
        _rawChunksData.push_back({ id, data });
    }
}
Exemple #3
0
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;
}
Exemple #4
0
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 */
Exemple #5
0
static void
chunk_test_helper (const char *filename, int format, const char * testdata)
{	SNDFILE			*file ;
	SF_INFO			sfinfo ;
	SF_CHUNK_INFO	chunk_info ;
	SF_CHUNK_ITERATOR * iterator ;
	uint32_t		length_before ;
	int				err, allow_fd ;

	switch (format & SF_FORMAT_SUBMASK)
	{	case SF_FORMAT_ALAC_16 :
			allow_fd = SF_FALSE ;
			break ;
		default :
			allow_fd = SF_TRUE ;
			break ;
		} ;

	sfinfo.samplerate	= 44100 ;
	sfinfo.channels		= 1 ;
	sfinfo.frames		= 0 ;
	sfinfo.format		= format ;

	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __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\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, 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) ;
	err = sf_get_chunk_size (iterator, &chunk_info) ;
	exit_if_true (
		err != SF_ERR_NO_ERROR,
		"\n\nLine %d : sf_get_chunk_size returned for testdata '%s' : %s\n\n", __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\n", __LINE__, testdata, chunk_info.datalen, length_before
		) ;

	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 '%s' : %s\n\n", __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 */