status af_read_uint16_le (uint16_t *value, AFvirtualfile *vf) { uint16_t v; if (af_fread(&v, sizeof (v), 1, vf) != 1) return AF_FAIL; *value = LENDIAN_TO_HOST_INT16(v); return AF_SUCCEED; }
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; 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) { 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, AF_FALSE); bitsPerSample = 8 * _af_format_sample_size(&track->f, AF_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; } 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 (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); } return AF_SUCCEED; }
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; }