Example #1
0
status CAFFile::readInit(AFfilesetup setup)
{
	m_fh->seek(8, File::SeekFromBeginning);

	if (!allocateTrack())
		return AF_FAIL;

	off_t currentOffset = m_fh->tell();
	off_t fileLength = m_fh->length();

	while (currentOffset < fileLength)
	{
		Tag chunkType;
		int64_t chunkLength;
		if (!readTag(&chunkType) ||
			!readS64(&chunkLength))
			return AF_FAIL;

		currentOffset += 12;

		if (chunkType == "data" && chunkLength == -1)
			chunkLength = fileLength - currentOffset;
		else if (chunkLength < 0)
			_af_error(AF_BAD_HEADER,
				"invalid chunk length %jd for chunk type %s\n",
				static_cast<intmax_t>(chunkLength), chunkType.name().c_str());

		if (chunkType == "desc")
		{
			if (parseDescription(chunkType, chunkLength) == AF_FAIL)
				return AF_FAIL;
		}
		else if (chunkType == "data")
		{
			if (parseData(chunkType, chunkLength) == AF_FAIL)
				return AF_FAIL;
		}

		currentOffset = m_fh->seek(currentOffset + chunkLength,
			File::SeekFromBeginning);
	}

	return AF_SUCCEED;
}
Example #2
0
status WAVEFile::readInit(AFfilesetup setup)
{
	Tag type, formtype;
	uint32_t size;
	uint32_t index = 0;

	bool hasFormat = false;
	bool hasData = false;
	bool hasCue = false;
	bool hasList = false;
	bool hasPlayList = false;
	bool hasFrameCount = false;
	bool hasINST = false;

	Track *track = allocateTrack();

	fh->seek(0, File::SeekFromBeginning);

	readTag(&type);
	readU32(&size);
	readTag(&formtype);

	assert(type == "RIFF");
	assert(formtype == "WAVE");

#ifdef DEBUG
	printf("size: %d\n", size);
#endif

	/* Include the offset of the form type. */
	index += 4;

	while (index < size)
	{
		Tag chunkid;
		uint32_t chunksize = 0;
		status result;

#ifdef DEBUG
		printf("index: %d\n", index);
#endif
		readTag(&chunkid);
		readU32(&chunksize);

#ifdef DEBUG
		printf("%s size: %d\n", chunkid.name().c_str(), chunksize);
#endif

		if (chunkid == "fmt ")
		{
			result = parseFormat(chunkid, chunksize);
			if (result == AF_FAIL)
				return AF_FAIL;

			hasFormat = true;
		}
		else if (chunkid == "data")
		{
			/* The format chunk must precede the data chunk. */
			if (!hasFormat)
			{
				_af_error(AF_BAD_HEADER, "missing format chunk in WAVE file");
				return AF_FAIL;
			}

			result = parseData(chunkid, chunksize);
			if (result == AF_FAIL)
				return AF_FAIL;

			hasData = true;
		}
		else if (chunkid == "inst")
		{
			result = parseInstrument(chunkid, chunksize);
			if (result == AF_FAIL)
				return AF_FAIL;
		}
		else if (chunkid == "fact")
		{
			hasFrameCount = true;
			result = parseFrameCount(chunkid, chunksize);
			if (result == AF_FAIL)
				return AF_FAIL;
		}
		else if (chunkid == "cue ")
		{
			hasCue = true;
			result = parseCues(chunkid, chunksize);
			if (result == AF_FAIL)
				return AF_FAIL;
		}
		else if (chunkid == "LIST" || chunkid == "list")
		{
			hasList = true;
			result = parseList(chunkid, chunksize);
			if (result == AF_FAIL)
				return AF_FAIL;
		}
		else if (chunkid == "INST")
		{
			hasINST = true;
			result = parseInstrument(chunkid, chunksize);
			if (result == AF_FAIL)
				return AF_FAIL;
		}
		else if (chunkid == "plst")
		{
			hasPlayList = true;
			result = parsePlayList(chunkid, chunksize);
			if (result == AF_FAIL)
				return AF_FAIL;
		}

		index += chunksize + 8;

		/* All chunks must be aligned on an even number of bytes */
		if ((index % 2) != 0)
			index++;

		fh->seek(index + 8, File::SeekFromBeginning);
	}

	/* The format chunk and the data chunk are required. */
	if (!hasFormat || !hasData)
	{
		return AF_FAIL;
	}

	/*
		At this point we know that the file has a format chunk
		and a data chunk, so we can assume that track->f and
		track->data_size have been initialized.
	*/
	if (!hasFrameCount)
	{
		track->totalfframes = track->data_size /
			(int) _af_format_frame_size(&track->f, false);
	}

	if (track->f.compressionType != AF_COMPRESSION_NONE &&
		(track->f.compressionType == AF_COMPRESSION_G711_ULAW ||
		track->f.compressionType == AF_COMPRESSION_G711_ALAW))
	{
		track->totalfframes = track->data_size / track->f.channelCount;
	}

	/*
		A return value of AF_SUCCEED indicates successful parsing.
	*/
	return AF_SUCCEED;
}
Example #3
0
status IFFFile::readInit(AFfilesetup setup)
{
	m_fh->seek(0, File::SeekFromBeginning);

	Tag type;
	uint32_t size;
	Tag formtype;

	readTag(&type);
	readU32(&size);
	readTag(&formtype);

	if (type != "FORM" || formtype != "8SVX")
		return AF_FAIL;

	/* IFF/8SVX files have only one track. */
	Track *track = allocateTrack();
	if (!track)
		return AF_FAIL;

	/* Set the index to include the form type ('8SVX' in this case). */
	size_t index = 4;
	while (index < size)
	{
		Tag chunkid;
		uint32_t chunksize = 0;
		status result = AF_SUCCEED;

		readTag(&chunkid);
		readU32(&chunksize);

		if (chunkid == "VHDR")
		{
			result = parseVHDR(chunkid, chunksize);
		}
		else if (chunkid == "BODY")
		{
			result = parseBODY(chunkid, chunksize);
		}
		else if (chunkid == "NAME" ||
			chunkid == "AUTH" ||
			chunkid == "(c) " ||
			chunkid == "ANNO")
		{
			parseMiscellaneous(chunkid, chunksize);
		}

		if (result == AF_FAIL)
			return AF_FAIL;

		/*
			Increment the index by the size of the chunk
			plus the size of the chunk header.
		*/
		index += chunksize + 8;

		/* All chunks must be aligned on an even number of bytes. */
		if ((index % 2) != 0)
			index++;

		/* Set the seek position to the beginning of the next chunk. */
		m_fh->seek(index + 8, File::SeekFromBeginning);
	}

	/* The file has been successfully parsed. */
	return AF_SUCCEED;
}
Example #4
0
status SampleVisionFile::readInit(AFfilesetup)
{
	m_fh->seek(0, File::SeekFromBeginning);

	char magic[kSMPMagicLength];
	if (m_fh->read(magic, kSMPMagicLength) != (ssize_t) kSMPMagicLength)
		return AF_FAIL;
	if (strncmp(magic, kSMPMagic, kSMPMagicLength) != 0)
		return AF_FAIL;

	char version[kSMPVersionLength];
	if (m_fh->read(version, kSMPVersionLength) != (ssize_t) kSMPVersionLength)
		return AF_FAIL;
	if (strncmp(version, kSMPVersion, kSMPVersionLength) != 0)
		return AF_FAIL;

	Track *track = allocateTrack();

	char name[kSMPNameLength + 1];
	m_fh->read(name, kSMPNameLength);
	name[kSMPNameLength] = '\0';
	trimTrailingSpaces(name);
	if (strlen(name) > 0)
		addMiscellaneous(AF_MISC_NAME, name);

	char comment[kSMPCommentLength + 1];
	m_fh->read(comment, kSMPCommentLength);
	comment[kSMPCommentLength] = '\0';
	trimTrailingSpaces(comment);
	if (strlen(comment) > 0)
		addMiscellaneous(AF_MISC_COMMENT, comment);

	uint32_t frameCount;
	readU32(&frameCount);
	track->totalfframes = frameCount;
	track->fpos_first_frame = m_fh->tell();
	track->data_size = 2 * frameCount;

	m_fh->seek(track->data_size, File::SeekFromCurrent);

	uint16_t reserved;
	readU16(&reserved);

	parseLoops();
	parseMarkers();

	uint8_t midiNote;
	uint32_t sampleRate;
	uint32_t smpteOffset;
	uint32_t cycleLength;

	readU8(&midiNote);
	readU32(&sampleRate);
	readU32(&smpteOffset);
	readU32(&cycleLength);

	track->f.byteOrder = AF_BYTEORDER_LITTLEENDIAN;
	track->f.sampleRate = sampleRate;
	track->f.channelCount = 1;
	track->f.compressionType = AF_COMPRESSION_NONE;
	track->f.framesPerPacket = 1;
	_af_set_sample_format(&track->f, AF_SAMPFMT_TWOSCOMP, 16);
	track->f.computeBytesPerPacketPCM();

	return AF_SUCCEED;
}
Example #5
0
status NeXTFile::readInit(AFfilesetup setup)
{
	uint32_t id, offset, length, encoding, sampleRate, channelCount;

	fh->seek(0, File::SeekFromBeginning);

	fh->read(&id, 4);
	assert(!memcmp(&id, ".snd", 4));

	readU32(&offset);
	readU32(&length);
	readU32(&encoding);
	readU32(&sampleRate);
	readU32(&channelCount);

#ifdef DEBUG
	printf("id, offset, length, encoding, sampleRate, channelCount:\n"
		" %d %d %d %d %d %d\n",
		id, offset, length, encoding, sampleRate, channelCount);
#endif

	Track *track = allocateTrack();
	if (!track)
		return AF_FAIL;

	track->f.byteOrder = AF_BYTEORDER_BIGENDIAN;

	/* Override the compression type later if necessary. */
	track->f.compressionType = AF_COMPRESSION_NONE;

	track->fpos_first_frame = offset;

	off_t lengthAvailable = fh->length() - offset;
	if (length == _AU_LENGTH_UNSPECIFIED || static_cast<off_t>(length) > lengthAvailable)
		length = lengthAvailable;

	track->data_size = length;

	switch (encoding)
	{
		case _AU_FORMAT_MULAW_8:
			track->f.sampleWidth = 16;
			track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
			track->f.compressionType = AF_COMPRESSION_G711_ULAW;
			break;
		case _AU_FORMAT_ALAW_8:
			track->f.sampleWidth = 16;
			track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
			track->f.compressionType = AF_COMPRESSION_G711_ALAW;
			break;
		case _AU_FORMAT_LINEAR_8:
			track->f.sampleWidth = 8;
			track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
			break;
		case _AU_FORMAT_LINEAR_16:
			track->f.sampleWidth = 16;
			track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
			break;
		case _AU_FORMAT_LINEAR_24:
			track->f.sampleWidth = 24;
			track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
			break;
		case _AU_FORMAT_LINEAR_32:
			track->f.sampleWidth = 32;
			track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
			break;
		case _AU_FORMAT_FLOAT:
			track->f.sampleWidth = 32;
			track->f.sampleFormat = AF_SAMPFMT_FLOAT;
			break;
		case _AU_FORMAT_DOUBLE:
			track->f.sampleWidth = 64;
			track->f.sampleFormat = AF_SAMPFMT_DOUBLE;
			break;

		default:
			/*
				This encoding method is not recognized.
			*/
			_af_error(AF_BAD_SAMPFMT, "bad sample format");
			return AF_FAIL;
	}

	_af_set_sample_format(&track->f, track->f.sampleFormat, track->f.sampleWidth);

	track->f.sampleRate = sampleRate;
	track->f.channelCount = channelCount;
	int frameSize = _af_format_frame_size(&track->f, false);
	track->totalfframes = length / frameSize;

#ifdef DEBUG
	printf("_af_next_read_init\n");
	_af_print_filehandle(file);
#endif

	/* The file has been parsed successfully. */
	return AF_SUCCEED;
}
Example #6
0
status AVRFile::readInit(AFfilesetup setup)
{
	uint32_t	magic;
	char		name[8];
	uint16_t	mono, resolution, sign, loop, midi;
	uint32_t	rate, size, loopStart, loopEnd;
	char		reserved[26];
	char		user[64];

	m_fh->seek(0, File::SeekFromBeginning);

	if (m_fh->read(&magic, 4) != 4)
	{
		_af_error(AF_BAD_READ, "could not read AVR file header");
		return AF_FAIL;
	}

	if (memcmp(&magic, "2BIT", 4) != 0)
	{
		_af_error(AF_BAD_FILEFMT, "file is not AVR format");
		return AF_FAIL;
	}

	/* Read name. */
	m_fh->read(name, 8);

	readU16(&mono);
	readU16(&resolution);
	readU16(&sign);
	readU16(&loop);
	readU16(&midi);

	readU32(&rate);
	readU32(&size);
	readU32(&loopStart);
	readU32(&loopEnd);

	m_fh->read(reserved, 26);
	m_fh->read(user, 64);

	Track *track = allocateTrack();
	if (!track)
		return AF_FAIL;

	/* Use only low-order three bytes of sample rate. */
	track->f.sampleRate = rate & 0xffffff;

	if (sign == 0)
		track->f.sampleFormat = AF_SAMPFMT_UNSIGNED;
	else if (sign == 0xffff)
		track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
	else
	{
		_af_error(AF_BAD_SAMPFMT, "bad sample format in AVR file");
		return AF_FAIL;
	}

	if (resolution != 8 && resolution != 16)
	{
		_af_error(AF_BAD_WIDTH, "bad sample width %d in AVR file",
			resolution);
		return AF_FAIL;
	}
	track->f.sampleWidth = resolution;

	track->f.byteOrder = AF_BYTEORDER_BIGENDIAN;

	if (mono == 0)
		track->f.channelCount = 1;
	else if (mono == 0xffff)
		track->f.channelCount = 2;
	else
	{
		_af_error(AF_BAD_CHANNELS,
			"invalid number of channels in AVR file");
		return AF_FAIL;
	}

	track->f.compressionType = AF_COMPRESSION_NONE;

	track->f.framesPerPacket = 1;
	track->f.computeBytesPerPacketPCM();

	_af_set_sample_format(&track->f, track->f.sampleFormat, track->f.sampleWidth);

	track->fpos_first_frame = m_fh->tell();
	track->totalfframes = size;
	track->data_size = track->totalfframes * track->f.bytesPerFrame(false);
	track->nextfframe = 0;
	track->fpos_next_frame = track->fpos_first_frame;

	/* The file has been parsed successfully. */
	return AF_SUCCEED;
}
Example #7
0
status NISTFile::readInit(AFfilesetup setup)
{
    char header[NIST_SPHERE_HEADER_LENGTH + 1];
    int intval;
    char strval[NIST_SPHERE_MAX_FIELD_LENGTH];
    int sample_n_bytes;

    m_fh->seek(0, File::SeekFromBeginning);

    if (m_fh->read(header, NIST_SPHERE_HEADER_LENGTH) != NIST_SPHERE_HEADER_LENGTH)
    {
        _af_error(AF_BAD_READ, "Could not read NIST SPHERE file header");
        return AF_FAIL;
    }

    header[NIST_SPHERE_HEADER_LENGTH] = '\0';

    if (memcmp(header, "NIST_1A\n   1024\n", 16) != 0)
    {
        _af_error(AF_BAD_FILEFMT, "Bad NIST SPHERE file header");
        return AF_FAIL;
    }

    Track *track = allocateTrack();
    if (!track)
        return AF_FAIL;

    // Read channel count.
    if (nist_header_read_int(header, "channel_count", &intval))
    {
        if (intval < 1)
        {
            _af_error(AF_BAD_CHANNELS, "invalid number of channels %d",
                      intval);
            return AF_FAIL;
        }
        track->f.channelCount = intval;
    }
    else
    {
        _af_error(AF_BAD_HEADER, "number of channels not specified");
        return AF_FAIL;
    }

    // Read number of bytes per sample.
    if (!nist_header_read_int(header, "sample_n_bytes", &sample_n_bytes))
    {
        _af_error(AF_BAD_HEADER, "bytes per sample not specified");
        return AF_FAIL;
    }

    track->f.framesPerPacket = 1;

    /*
    	Since some older NIST SPHERE files lack a sample_coding
    	field, if sample_n_bytes is 1, assume mu-law;
    	otherwise assume linear PCM.
    */
    track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
    if (sample_n_bytes == 1)
    {
        track->f.compressionType = AF_COMPRESSION_G711_ULAW;
        track->f.sampleWidth = 16;
        track->f.bytesPerPacket = track->f.channelCount;
    }
    else
    {
        track->f.compressionType = AF_COMPRESSION_NONE;
        track->f.sampleWidth = sample_n_bytes * 8;
        track->f.computeBytesPerPacketPCM();
    }

    if (nist_header_read_string(header, "sample_coding", &intval, strval))
    {
        if (strcmp(strval, "pcm") == 0)
            ;
        else if (strcmp(strval, "ulaw") == 0 || strcmp(strval, "mu-law") == 0)
        {
            track->f.compressionType = AF_COMPRESSION_G711_ULAW;
            track->f.sampleWidth = 16;
        }
        else if (strcmp(strval, "alaw") == 0)
        {
            track->f.compressionType = AF_COMPRESSION_G711_ALAW;
            track->f.sampleWidth = 16;
        }
        else
        {
            _af_error(AF_BAD_SAMPFMT,
                      "unrecognized NIST SPHERE sample format %s", strval);
            return AF_FAIL;
        }
    }

    // Read string representing byte order.
    if (nist_header_read_string(header, "sample_byte_format", &intval, strval))
    {
        if (intval > 1)
        {
            if (strncmp(strval, "01", 2) == 0)
                track->f.byteOrder = AF_BYTEORDER_LITTLEENDIAN;
            else
                track->f.byteOrder = AF_BYTEORDER_BIGENDIAN;
        }
        else
            track->f.byteOrder = _AF_BYTEORDER_NATIVE;
    }
    else
    {
        /*
        	Fail if this field is not present and sample
        	width is more than one byte.
        */
        if (track->f.compressionType == AF_COMPRESSION_NONE &&
                track->f.sampleWidth > 8)
        {
            _af_error(AF_BAD_HEADER, "sample byte order not specified");
            return AF_FAIL;
        }
    }

    // Read significant bits per sample.
    if (nist_header_read_int(header, "sample_sig_bits", &intval))
    {
        if (intval < 1 || intval > 32)
        {
            _af_error(AF_BAD_WIDTH, "invalid sample width %d bits\n",
                      intval);
            return AF_FAIL;
        }

        /*
        	Use specified significant bits value as the
        	sample width for uncompressed data as long
        	as the number of bytes per sample remains
        	unchanged.
        */
        if (track->f.compressionType == AF_COMPRESSION_NONE &&
                (intval + 7) / 8 == sample_n_bytes)
        {
            track->f.sampleWidth = intval;
        }
    }

    // Read sample rate.
    if (nist_header_read_int(header, "sample_rate", &intval))
    {
        if (intval <= 0)
        {
            _af_error(AF_BAD_RATE, "invalid sample rate %d Hz\n", intval);
            return AF_FAIL;
        }
        track->f.sampleRate = intval;
    }
    else
    {
        _af_error(AF_BAD_HEADER, "sample rate not specified");
        return AF_FAIL;
    }

    // Read sample count.
    if (nist_header_read_int(header, "sample_count", &intval))
    {
        track->totalfframes = intval;
    }
    else
    {
        _af_error(AF_BAD_HEADER, "number of samples not specified");
        return AF_FAIL;
    }

    if (_af_set_sample_format(&track->f, track->f.sampleFormat,
                              track->f.sampleWidth) == AF_FAIL)
    {
        return AF_FAIL;
    }

    track->fpos_first_frame = NIST_SPHERE_HEADER_LENGTH;
    track->data_size = m_fh->length() - NIST_SPHERE_HEADER_LENGTH;
    track->nextfframe = 0;
    track->fpos_next_frame = track->fpos_first_frame;

    return AF_SUCCEED;
}
Example #8
0
status VOCFile::readInit(AFfilesetup)
{
	m_fh->seek(20, File::SeekFromBeginning);

	uint16_t dataOffset, version, checksum;
	readU16(&dataOffset);
	readU16(&version);
	readU16(&checksum);

	Track *track = allocateTrack();

	bool hasExtendedInfo = false;
	bool foundSoundData = false;

	off_t position = m_fh->tell();
	off_t fileLength = m_fh->length();
	while (position < fileLength)
	{
		uint32_t blockHeader;
		if (!readU32(&blockHeader))
			break;
		uint8_t blockType = blockHeader & 0xff;
		uint32_t blockSize = blockHeader >> 8;

		if (blockType == kVOCSoundData)
		{
			if (foundSoundData)
			{
				_af_error(AF_BAD_HEADER, "VOC file contains multiple sound data blocks");
				return AF_FAIL;
			}

			foundSoundData = true;

			uint8_t frequencyDivisor, codec;
			readU8(&frequencyDivisor);
			readU8(&codec);

			if (!hasExtendedInfo)
			{
				track->f.channelCount = 1;
				track->f.sampleRate = 1000000 / (256 - frequencyDivisor);
			}

			track->f.compressionType = AF_COMPRESSION_NONE;
			track->f.byteOrder = AF_BYTEORDER_LITTLEENDIAN;
			track->f.framesPerPacket = 1;

			if (codec == kVOCFormatU8)
			{
				_af_set_sample_format(&track->f, AF_SAMPFMT_UNSIGNED, 8);
				track->f.computeBytesPerPacketPCM();
			}
			else if (codec == kVOCFormatCreativeADPCM4_8 ||
				codec == kVOCFormatCreativeADPCM3_8 ||
				codec == kVOCFormatCreativeADPCM2_8)
			{
				_af_error(AF_BAD_NOT_IMPLEMENTED,
					"Creative ADPCM compression is not currently suppported");
				return AF_FAIL;
			}
			else
			{
				_af_error(AF_BAD_CODEC_TYPE,
					"VOC file contains unrecognized codec type %d", codec);
				return AF_FAIL;
			}

			track->fpos_first_frame = m_fh->tell();
			track->data_size = m_fh->length() - 1 - track->fpos_first_frame;
			track->computeTotalFileFrames();
		}
		else if (blockType == kVOCExtendedInfo)
		{
			if (foundSoundData)
			{
				_af_error(AF_BAD_HEADER, "VOC extended information found after sound data");
				return AF_FAIL;
			}

			hasExtendedInfo = true;

			uint16_t frequencyDivisor;
			uint8_t bitsPerSample;
			uint8_t isStereo;
			readU16(&frequencyDivisor);
			readU8(&bitsPerSample);
			readU8(&isStereo);

			track->f.sampleWidth = bitsPerSample;
			track->f.channelCount = isStereo ? 2 : 1;
			uint32_t frequencyDividend = 256000000 / (isStereo ? 2 : 1);
			track->f.sampleRate = frequencyDividend / (65536 - frequencyDivisor);
		}
		else if (blockType == kVOCSoundDataNew)
		{
			if (foundSoundData)
			{
				_af_error(AF_BAD_HEADER, "VOC file contains multiple sound data blocks");
				return AF_FAIL;
			}

			foundSoundData = true;

			uint32_t sampleRate;
			uint8_t bitsPerSample, channels;
			uint16_t format;
			uint32_t pad;
			readU32(&sampleRate);
			readU8(&bitsPerSample);
			readU8(&channels);
			readU16(&format);
			readU32(&pad);

			if (!channels)
			{
				_af_error(AF_BAD_CHANNELS, "invalid file with 0 channels");
				return AF_FAIL;
			}

			track->fpos_first_frame = m_fh->tell();
			track->data_size = blockSize - 12;

			track->f.compressionType = AF_COMPRESSION_NONE;
			track->f.byteOrder = AF_BYTEORDER_LITTLEENDIAN;
			track->f.sampleRate = sampleRate;
			track->f.channelCount = channels;
			track->f.framesPerPacket = 1;

			if (format == kVOCFormatU8)
			{
				_af_set_sample_format(&track->f, AF_SAMPFMT_UNSIGNED, 8);
				track->f.computeBytesPerPacketPCM();
			}
			else if (format == kVOCFormatS16)
			{
				_af_set_sample_format(&track->f, AF_SAMPFMT_TWOSCOMP, 16);
				track->f.computeBytesPerPacketPCM();
			}
			else if (format == kVOCFormatAlaw)
			{
				track->f.compressionType = AF_COMPRESSION_G711_ALAW;
				track->f.byteOrder = _AF_BYTEORDER_NATIVE;
				track->f.bytesPerPacket = track->f.channelCount;
				_af_set_sample_format(&track->f, AF_SAMPFMT_TWOSCOMP, 16);
			}
			else if (format == kVOCFormatUlaw)
			{
				track->f.compressionType = AF_COMPRESSION_G711_ULAW;
				track->f.byteOrder = _AF_BYTEORDER_NATIVE;
				track->f.bytesPerPacket = track->f.channelCount;
				_af_set_sample_format(&track->f, AF_SAMPFMT_TWOSCOMP, 16);
			}
			else if (format == kVOCFormatCreativeADPCM4_8 ||
				format == kVOCFormatCreativeADPCM3_8 ||
				format == kVOCFormatCreativeADPCM2_8 ||
				format == kVOCFormatCreativeADPCM4_16)
			{
				_af_error(AF_BAD_NOT_IMPLEMENTED,
					"Creative ADPCM compression is not currently supported");
				return AF_FAIL;
			}
			else
			{
				_af_error(AF_BAD_CODEC_TYPE,
					"VOC file contains unrecognized codec type %d", format);
				return AF_FAIL;
			}

			track->computeTotalFileFrames();
		}

		position += 4 + blockSize;

		m_fh->seek(position, File::SeekFromBeginning);
	}

	return AF_SUCCEED;
}