Beispiel #1
0
static status next_write_header (AFfilehandle file)
{
	_Track		*track;
	int		frameSize;
	uint32_t	offset, length, encoding, sampleRate, channelCount;

	track = _af_filehandle_get_track(file, AF_DEFAULT_TRACK);

	frameSize = _af_format_frame_size(&track->f, false);

	offset = track->fpos_first_frame;
	length = track->totalfframes * frameSize;
	encoding = nextencodingtype(&track->f);
	sampleRate = track->f.sampleRate;
	channelCount = track->f.channelCount;

	if (af_fseek(file->fh, 0, SEEK_SET) != 0)
		_af_error(AF_BAD_LSEEK, "bad seek");

	af_fwrite(".snd", 4, 1, file->fh);
	af_write_uint32_be(&offset, file->fh);
	af_write_uint32_be(&length, file->fh);
	af_write_uint32_be(&encoding, file->fh);
	af_write_uint32_be(&sampleRate, file->fh);
	af_write_uint32_be(&channelCount, file->fh);

	return AF_SUCCEED;
}
static status next_write_header (AFfilehandle file)
{
	_Track		*track;
	int		frameSize;
	u_int32_t	offset, length, encoding, sampleRate, channelCount;

	track = _af_filehandle_get_track(file, AF_DEFAULT_TRACK);

	frameSize = _af_format_frame_size(&track->f, AF_FALSE);

        if (track->f.compressionType == AF_COMPRESSION_G711_ULAW ||
            track->f.compressionType == AF_COMPRESSION_G711_ALAW)
           frameSize = frameSize / 2;

	offset = HOST_TO_BENDIAN_INT32(track->fpos_first_frame);
	length = HOST_TO_BENDIAN_INT32(track->totalfframes * frameSize);
	encoding = HOST_TO_BENDIAN_INT32(nextencodingtype(&track->f));
	sampleRate = HOST_TO_BENDIAN_INT32(track->f.sampleRate);
	channelCount = HOST_TO_BENDIAN_INT32(track->f.channelCount);

	if (af_fseek(file->fh, 0, SEEK_SET) != 0)
		_af_error(AF_BAD_LSEEK, "bad seek");

	af_fwrite(".snd", 4, 1, file->fh);
	af_fwrite(&offset, 4, 1, file->fh);
	af_fwrite(&length, 4, 1, file->fh);
	af_fwrite(&encoding, 4, 1, file->fh);
	af_fwrite(&sampleRate, 4, 1, file->fh);
	af_fwrite(&channelCount, 4, 1, file->fh);

	return AF_SUCCEED;
}
Beispiel #3
0
status _af_wave_update (AFfilehandle file)
{
	_Track	*track;

	track = _af_filehandle_get_track(file, AF_DEFAULT_TRACK);

	if (track->fpos_first_frame != 0)
	{
		size_t	dataLength, fileLength;

		/*
			We call _af_format_frame_size to calculate the
			frame size of normal PCM data or compressed data.
		*/
		dataLength = track->totalfframes * _af_format_frame_size(&track->f, AF_FALSE);

		dataLength = HOST_TO_LENDIAN_INT32(dataLength);
		af_fseek(file->fh, track->fpos_first_frame - 4, SEEK_SET);
		af_fwrite(&dataLength, 4, 1, file->fh);

		fileLength = af_flength(file->fh);
		fileLength -= 8;
		fileLength = HOST_TO_LENDIAN_INT32(fileLength);

		af_fseek(file->fh, 4, SEEK_SET);
		af_fwrite(&fileLength, 4, 1, file->fh);
	}

	return AF_SUCCEED;
}
Beispiel #4
0
float afGetVirtualFrameSize (AFfilehandle file, int trackid, int stretch3to4)
{
	if (!_af_filehandle_ok(file))
		return -1;

	Track *track = file->getTrack(trackid);
	if (!track)
		return -1;

	return _af_format_frame_size(&track->v, stretch3to4);
}
Beispiel #5
0
status RawFile::readInit(AFfilesetup fileSetup)
{
	if (!fileSetup)
	{
		_af_error(AF_BAD_FILESETUP, "a valid AFfilesetup is required for reading raw data");
		return AF_FAIL;
	}

	if (initFromSetup(fileSetup) == AF_FAIL)
		return AF_FAIL;

	TrackSetup *trackSetup = fileSetup->getTrack();
	if (!trackSetup)
		return AF_FAIL;

	Track *track = getTrack();

	/* Set the track's data offset. */
	if (trackSetup->dataOffsetSet)
		track->fpos_first_frame = trackSetup->dataOffset;
	else
		track->fpos_first_frame = 0;

	/* Set the track's frame count. */
	if (trackSetup->frameCountSet)
	{
		track->totalfframes = trackSetup->frameCount;
	}
	else
	{
		AFfileoffset filesize = m_fh->length();
		if (filesize == -1)
			track->totalfframes = -1;
		else
		{
			/* Ensure that the data offset is valid. */
			if (track->fpos_first_frame > filesize)
			{
				_af_error(AF_BAD_FILESETUP, "data offset is larger than file size");
				return AF_FAIL;
			}

			filesize -= track->fpos_first_frame;
			track->totalfframes = filesize / (int) _af_format_frame_size(&track->f, false);
		}
		track->data_size = filesize;
	}

	return AF_SUCCEED;
}
Beispiel #6
0
status _af_wave_update (AFfilehandle file)
{
	_Track		*track;
	_WAVEInfo	*wave = (_WAVEInfo *) file->formatSpecific;

	track = _af_filehandle_get_track(file, AF_DEFAULT_TRACK);

	if (track->fpos_first_frame != 0)
	{
		u_int32_t	dataLength, fileLength;

		/* Update the frame count chunk if present. */
		WriteFrameCount(file);

		/* Update the length of the data chunk. */
		af_fseek(file->fh, wave->dataSizeOffset, SEEK_SET);

		/*
			We call _af_format_frame_size to calculate the
			frame size of normal PCM data or compressed data.
		*/
		dataLength = (u_int32_t) track->totalfframes *
			_af_format_frame_size(&track->f, AF_FALSE);
		dataLength = HOST_TO_LENDIAN_INT32(dataLength);
		af_fwrite(&dataLength, 4, 1, file->fh);

		/* Update the length of the RIFF chunk. */
		fileLength = (u_int32_t) af_flength(file->fh);
		fileLength -= 8;
		fileLength = HOST_TO_LENDIAN_INT32(fileLength);

		af_fseek(file->fh, 4, SEEK_SET);
		af_fwrite(&fileLength, 4, 1, file->fh);
	}

	/*
		Write the actual data that was set after initializing
		the miscellaneous IDs.	The size of the data will be
		unchanged.
	*/
	WriteMiscellaneous(file);

	/* Write the new positions; the size of the data will be unchanged. */
	WriteCues(file);

	return AF_SUCCEED;
}
Beispiel #7
0
static status WriteData (AFfilehandle file)
{
	_Track		*track;
	uint32_t	chunkSize;
	_WAVEInfo	*waveinfo;

	assert(file);

	waveinfo = file->formatSpecific;
	track = _af_filehandle_get_track(file, AF_DEFAULT_TRACK);

	af_fwrite("data", 4, 1, file->fh);
	waveinfo->dataSizeOffset = af_ftell(file->fh);

	chunkSize = (int) _af_format_frame_size(&track->f, false) *
		track->totalfframes;

	af_write_uint32_le(&chunkSize, file->fh);
	track->fpos_first_frame = af_ftell(file->fh);

	return AF_SUCCEED;
}
Beispiel #8
0
static status WriteData (AFfilehandle file)
{
	_Track		*track;
	u_int32_t	frameSize, chunkSize;
	_WAVEInfo	*waveinfo;

	assert(file);

	waveinfo = file->formatSpecific;
	track = _af_filehandle_get_track(file, AF_DEFAULT_TRACK);

	af_fwrite("data", 4, 1, file->fh);
	waveinfo->dataSizeOffset = af_ftell(file->fh);

	frameSize = _af_format_frame_size(&track->f, AF_FALSE);
	chunkSize = frameSize * track->totalfframes;
	chunkSize = HOST_TO_LENDIAN_INT32(chunkSize);
	af_fwrite(&chunkSize, 4, 1, file->fh);
	track->fpos_first_frame = af_ftell(file->fh);

	return AF_SUCCEED;
}
Beispiel #9
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;
}
Beispiel #10
0
status WAVEFile::writeFormat()
{
	uint16_t	formatTag, channelCount;
	uint32_t	sampleRate, averageBytesPerSecond;
	uint16_t	blockAlign;
	uint32_t	chunkSize;
	uint16_t	bitsPerSample;

	Track *track = getTrack();

	fh->write("fmt ", 4);

	switch (track->f.compressionType)
	{
		case AF_COMPRESSION_NONE:
			chunkSize = 16;
			if (track->f.sampleFormat == AF_SAMPFMT_FLOAT ||
				track->f.sampleFormat == AF_SAMPFMT_DOUBLE)
			{
				formatTag = WAVE_FORMAT_IEEE_FLOAT;
			}
			else if (track->f.sampleFormat == AF_SAMPFMT_TWOSCOMP ||
				track->f.sampleFormat == AF_SAMPFMT_UNSIGNED)
			{
				formatTag = WAVE_FORMAT_PCM;
			}
			else
			{
				_af_error(AF_BAD_COMPTYPE, "bad sample format");
				return AF_FAIL;
			}

			blockAlign = _af_format_frame_size(&track->f, false);
			bitsPerSample = 8 * _af_format_sample_size(&track->f, false);
			break;

		/*
			G.711 compression uses eight bits per sample.
		*/
		case AF_COMPRESSION_G711_ULAW:
			chunkSize = 18;
			formatTag = IBM_FORMAT_MULAW;
			blockAlign = track->f.channelCount;
			bitsPerSample = 8;
			break;

		case AF_COMPRESSION_G711_ALAW:
			chunkSize = 18;
			formatTag = IBM_FORMAT_ALAW;
			blockAlign = track->f.channelCount;
			bitsPerSample = 8;
			break;

		default:
			_af_error(AF_BAD_COMPTYPE, "bad compression type");
			return AF_FAIL;
	}

	writeU32(&chunkSize);
	writeU16(&formatTag);

	channelCount = track->f.channelCount;
	writeU16(&channelCount);

	sampleRate = track->f.sampleRate;
	writeU32(&sampleRate);

	averageBytesPerSecond =
		track->f.sampleRate * _af_format_frame_size(&track->f, false);
	writeU32(&averageBytesPerSecond);

	blockAlign = _af_format_frame_size(&track->f, false);
	writeU16(&blockAlign);

	writeU16(&bitsPerSample);

	if (track->f.compressionType == AF_COMPRESSION_G711_ULAW ||
		track->f.compressionType == AF_COMPRESSION_G711_ALAW)
	{
		uint16_t zero = 0;
		writeU16(&zero);
	}

	return AF_SUCCEED;
}
Beispiel #11
0
static status WriteFormat (AFfilehandle file)
{
	_Track		*track = NULL;

	uint16_t	formatTag, channelCount;
	uint32_t	sampleRate, averageBytesPerSecond;
	uint16_t	blockAlign;
	uint32_t	chunkSize;
	uint16_t	bitsPerSample;

	assert(file != NULL);

	track = _af_filehandle_get_track(file, AF_DEFAULT_TRACK);

	af_fwrite("fmt ", 4, 1, file->fh);

	switch (track->f.compressionType)
	{
		case AF_COMPRESSION_NONE:
			chunkSize = 16;
			if (track->f.sampleFormat == AF_SAMPFMT_FLOAT ||
				track->f.sampleFormat == AF_SAMPFMT_DOUBLE)
			{
				formatTag = WAVE_FORMAT_IEEE_FLOAT;
			}
			else if (track->f.sampleFormat == AF_SAMPFMT_TWOSCOMP ||
				track->f.sampleFormat == AF_SAMPFMT_UNSIGNED)
			{
				formatTag = WAVE_FORMAT_PCM;
			}
			else
			{
				_af_error(AF_BAD_COMPTYPE, "bad sample format");
				return AF_FAIL;
			}

			blockAlign = _af_format_frame_size(&track->f, false);
			bitsPerSample = 8 * _af_format_sample_size(&track->f, false);
			break;

		/*
			G.711 compression uses eight bits per sample.
		*/
		case AF_COMPRESSION_G711_ULAW:
			chunkSize = 18;
			formatTag = IBM_FORMAT_MULAW;
			blockAlign = track->f.channelCount;
			bitsPerSample = 8;
			break;

		case AF_COMPRESSION_G711_ALAW:
			chunkSize = 18;
			formatTag = IBM_FORMAT_ALAW;
			blockAlign = track->f.channelCount;
			bitsPerSample = 8;
			break;

		default:
			_af_error(AF_BAD_COMPTYPE, "bad compression type");
			return AF_FAIL;
	}

	af_write_uint32_le(&chunkSize, file->fh);
	af_write_uint16_le(&formatTag, file->fh);

	channelCount = track->f.channelCount;
	af_write_uint16_le(&channelCount, file->fh);

	sampleRate = track->f.sampleRate;
	af_write_uint32_le(&sampleRate, file->fh);

	averageBytesPerSecond =
		track->f.sampleRate * _af_format_frame_size(&track->f, false);
	af_write_uint32_le(&averageBytesPerSecond, file->fh);

	blockAlign = _af_format_frame_size(&track->f, false);
	af_write_uint16_le(&blockAlign, file->fh);

	af_write_uint16_le(&bitsPerSample, file->fh);

	if (track->f.compressionType == AF_COMPRESSION_G711_ULAW ||
		track->f.compressionType == AF_COMPRESSION_G711_ALAW)
	{
		uint16_t	zero = 0;
		af_write_uint16_le(&zero, file->fh);
	}

	return AF_SUCCEED;
}
Beispiel #12
0
int afWriteFrames (AFfilehandle file, int trackid, const void *samples,
	int nvframes2write)
{
	_AFmoduleinst	*firstmod;
	_AFchunk	*userc;
	_Track		*track;
	int		bytes_per_vframe;
	AFframecount	vframe;

	if (!_af_filehandle_ok(file))
		return -1;

	if (!_af_filehandle_can_write(file))
		return -1;

	if ((track = _af_filehandle_get_track(file, trackid)) == NULL)
		return -1;

	if (track->ms.modulesdirty)
	{
		if (_AFsetupmodules(file, track) != AF_SUCCEED)
			return -1;
	}

	/*if (file->seekok) {*/

	if (af_fseek(file->fh, track->fpos_next_frame, SEEK_SET) < 0)
	{
		_af_error(AF_BAD_LSEEK, "unable to position write pointer at next frame");
		return -1;
	}

	/* } */

	bytes_per_vframe = _af_format_frame_size(&track->v, AF_TRUE);

	firstmod = &track->ms.module[0];
	userc = &track->ms.chunk[0];

	track->filemodhappy = AF_TRUE;

	vframe = 0;
#ifdef UNLIMITED_CHUNK_NVFRAMES
	/*
		OPTIMIZATION: see the comment at the very end of
		arrangemodules() in modules.c for an explanation of this:
	*/
	if (!trk->ms.mustuseatomicnvframes)
	{
		userc->buf = (char *)buf;
		userc->nframes = nvframes2write;

		(*firstmod->mod->run_push)(firstmod);

		/* Count this chunk if there was no i/o error. */
		if (trk->filemodhappy)
			vframe += userc->nframes;
	}
	else
#else
	/* Optimization must be off. */
	assert(track->ms.mustuseatomicnvframes);
#endif
	{
		while (vframe < nvframes2write)
		{
			userc->buf = (char *) samples + bytes_per_vframe * vframe;
			if (vframe <= nvframes2write - _AF_ATOMIC_NVFRAMES)
				userc->nframes = _AF_ATOMIC_NVFRAMES;
			else
				userc->nframes = nvframes2write - vframe;

			(*firstmod->mod->run_push)(firstmod);

			if (track->filemodhappy == AF_FALSE)
				break;

			vframe += userc->nframes;
		}
	}

	track->nextvframe += vframe;
	track->totalvframes += vframe;

	return vframe;
}
Beispiel #13
0
int afReadFrames (AFfilehandle file, int trackid, void *samples,
	int nvframeswanted)
{
	_Track	*track;
	_AFmoduleinst	*firstmod;
	_AFchunk	*userc;
	AFframecount	nvframesleft, nvframes2read;
	int		bytes_per_vframe;
	AFframecount	vframe;

	if (!_af_filehandle_ok(file))
		return -1;

	if (!_af_filehandle_can_read(file))
		return -1;

	if ((track = _af_filehandle_get_track(file, trackid)) == NULL)
		return -1;

	if (track->ms.modulesdirty)
	{
		if (_AFsetupmodules(file, track) != AF_SUCCEED)
			return -1;
	}

	/*if (file->seekok) {*/

	if (af_fseek(file->fh, track->fpos_next_frame, SEEK_SET) < 0)
	{
		_af_error(AF_BAD_LSEEK, "unable to position read pointer at next frame");
		return -1;
	}

	/* } */

	if (track->totalvframes == -1)
		nvframes2read = nvframeswanted;
	else
	{
		nvframesleft = track->totalvframes - track->nextvframe;
		nvframes2read = (nvframeswanted > nvframesleft) ?
			nvframesleft : nvframeswanted;
	}
	bytes_per_vframe = _af_format_frame_size(&track->v, AF_TRUE);

	firstmod = &track->ms.module[track->ms.nmodules-1];
	userc = &track->ms.chunk[track->ms.nmodules];

	track->filemodhappy = AF_TRUE;

	vframe = 0;

	if (!track->ms.mustuseatomicnvframes)
	{
		assert(track->frames2ignore == 0);
		userc->buf = samples;
		userc->nframes = nvframes2read;

		(*firstmod->mod->run_pull)(firstmod);
		if (track->filemodhappy)
			vframe += userc->nframes;
	}
	else
	{
		bool	eof = AF_FALSE;

		if (track->frames2ignore != 0)
		{
			userc->nframes = track->frames2ignore;
			userc->buf = _af_malloc(track->frames2ignore * bytes_per_vframe);
			if (userc->buf == AF_NULL)
				return 0;

			(*firstmod->mod->run_pull)(firstmod);

			/* Have we hit EOF? */
			if (userc->nframes < track->frames2ignore)
				eof = AF_TRUE;

			track->frames2ignore = 0;

			free(userc->buf);
			userc->buf = NULL;
		}

		/*
			Now start reading useful frames, until EOF or
			premature EOF.
		*/

		while (track->filemodhappy && !eof && vframe < nvframes2read)
		{
			AFframecount	nvframes2pull;
			userc->buf = (char *) samples + bytes_per_vframe * vframe;

			if (vframe <= nvframes2read - _AF_ATOMIC_NVFRAMES)
				nvframes2pull = _AF_ATOMIC_NVFRAMES;
			else
				nvframes2pull = nvframes2read - vframe;

			userc->nframes = nvframes2pull;

			(*firstmod->mod->run_pull)(firstmod);

			if (track->filemodhappy)
			{
				vframe += userc->nframes;
				if (userc->nframes < nvframes2pull)
					eof = AF_TRUE;
			}
		}
	}

	track->nextvframe += vframe;

	return vframe;
}
Beispiel #14
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;
}
Beispiel #15
0
static status WriteFormat (AFfilehandle file)
{
	_Track		*track = NULL;
	u_int16_t	formatTag, channelCount;
	u_int32_t	sampleRate, averageBytesPerSecond;
	u_int16_t	blockAlign;
	u_int32_t	chunkSize;
	u_int16_t	bitsPerSample;
	_WAVEInfo	*waveinfo = NULL;

	assert(file != NULL);

	track = _af_filehandle_get_track(file, AF_DEFAULT_TRACK);
	waveinfo = (_WAVEInfo *) file->formatSpecific;

	af_fwrite("fmt ", 4, 1, file->fh);

	switch (track->f.compressionType)
	{
		case AF_COMPRESSION_NONE:
			chunkSize = 16;
			formatTag = WAVE_FORMAT_PCM;
			blockAlign = _af_format_frame_size(&track->f, AF_FALSE);
			bitsPerSample = 8 * _af_format_sample_size(&track->f, AF_FALSE);
			break;
		case AF_COMPRESSION_G711_ULAW:
			chunkSize = 18;
			formatTag = IBM_FORMAT_MULAW;
			blockAlign = _af_format_frame_size(&track->f, AF_FALSE);
			bitsPerSample = 8 * _af_format_sample_size(&track->f, AF_FALSE);
			break;
		case AF_COMPRESSION_G711_ALAW:
			chunkSize = 18;
			formatTag = IBM_FORMAT_ALAW;
			blockAlign = _af_format_frame_size(&track->f, AF_FALSE);
			bitsPerSample = 8 * _af_format_sample_size(&track->f, AF_FALSE);
			break;
		default:
			_af_error(AF_BAD_COMPTYPE, "bad compression type");
			return AF_FAIL;
	}

	chunkSize = HOST_TO_LENDIAN_INT32(chunkSize);
	af_fwrite(&chunkSize, 4, 1, file->fh);

	formatTag = HOST_TO_LENDIAN_INT16(formatTag);
	af_fwrite(&formatTag, 2, 1, file->fh);
	formatTag = LENDIAN_TO_HOST_INT16(formatTag);

	channelCount = track->f.channelCount;
	channelCount = HOST_TO_LENDIAN_INT16(channelCount);
	af_fwrite(&channelCount, 2, 1, file->fh);

	sampleRate = track->f.sampleRate;
	sampleRate = HOST_TO_LENDIAN_INT32(sampleRate);
	af_fwrite(&sampleRate, 4, 1, file->fh);

	averageBytesPerSecond =
		track->f.sampleRate * _af_format_frame_size(&track->f, AF_FALSE);
	averageBytesPerSecond = HOST_TO_LENDIAN_INT32(averageBytesPerSecond);
	af_fwrite(&averageBytesPerSecond, 4, 1, file->fh);

	blockAlign = _af_format_frame_size(&track->f, AF_FALSE);
	blockAlign = HOST_TO_LENDIAN_INT16(blockAlign);
	af_fwrite(&blockAlign, 2, 1, file->fh);

	bitsPerSample = HOST_TO_LENDIAN_INT16(bitsPerSample);
	af_fwrite(&bitsPerSample, 2, 1, file->fh);

	/*
		If the data is compressed we have additional
		format-specific information to write as well as the
		'fact' (frame count) chunk.
	*/
	if (track->f.compressionType != AF_COMPRESSION_NONE)
	{
		u_int32_t	factSize = 4;
		u_int32_t	totalFrameCount = 0;

		if (track->f.compressionType == AF_COMPRESSION_G711_ULAW ||
			track->f.compressionType == AF_COMPRESSION_G711_ALAW)
		{
			u_int16_t	zero = 0;
			af_fwrite(&zero, 2, 1, file->fh);
		}

		af_fwrite("fact", 4, 1, file->fh);
		factSize = HOST_TO_LENDIAN_INT32(factSize);
		af_fwrite(&factSize, 4, 1, file->fh);

		waveinfo->fileSizeOffset = af_ftell(file->fh);

		totalFrameCount = HOST_TO_LENDIAN_INT32(totalFrameCount);
		af_fwrite(&totalFrameCount, 4, 1, file->fh);
	}

	return AF_SUCCEED;
}