HelenOS sources
This source file includes following definitions.
- wav_parse_header
- wav_init_header
#include <byteorder.h>
#include <str.h>
#include <errno.h>
#include "wave.h"
errno_t wav_parse_header(const void *hdata, const void **data, size_t *data_size,
unsigned *channels, unsigned *sampling_rate, pcm_sample_format_t *format,
const char **error)
{
if (!hdata) {
if (error)
*error = "no header";
return EINVAL;
}
const wave_header_t *header = hdata;
if (str_lcmp(header->chunk_id, CHUNK_ID, 4) != 0) {
if (error)
*error = "invalid chunk id";
return EINVAL;
}
if (str_lcmp(header->format, FORMAT_STR, 4) != 0) {
if (error)
*error = "invalid format string";
return EINVAL;
}
if (str_lcmp(header->subchunk1_id, SUBCHUNK1_ID, 4) != 0) {
if (error)
*error = "invalid subchunk1 id";
return EINVAL;
}
if (uint32_t_le2host(header->subchunk1_size) != PCM_SUBCHUNK1_SIZE) {
if (error)
*error = "invalid subchunk1 size";
return EINVAL;
}
if (uint16_t_le2host(header->audio_format) != FORMAT_LINEAR_PCM) {
if (error)
*error = "unknown format";
return ENOTSUP;
}
if (str_lcmp(header->subchunk2_id, SUBCHUNK2_ID, 4) != 0) {
if (error)
*error = "invalid subchunk2 id";
return EINVAL;
}
if (data)
*data = header->data;
if (data_size)
*data_size = uint32_t_le2host(header->subchunk2_size);
if (sampling_rate)
*sampling_rate = uint32_t_le2host(header->sampling_rate);
if (channels)
*channels = uint16_t_le2host(header->channels);
if (format) {
const unsigned size = uint16_t_le2host(header->sample_size);
switch (size) {
case 8:
*format = PCM_SAMPLE_UINT8;
break;
case 16:
*format = PCM_SAMPLE_SINT16_LE;
break;
case 24:
*format = PCM_SAMPLE_SINT24_LE;
break;
case 32:
*format = PCM_SAMPLE_SINT32_LE;
break;
default:
*error = "Unknown format";
return ENOTSUP;
}
}
if (error)
*error = "no error";
return EOK;
}
void wav_init_header(wave_header_t *header, pcm_format_t format, size_t size)
{
assert(header);
#define COPY_STR(dst, src) memcpy(dst, src, str_size(src))
COPY_STR(&header->chunk_id, CHUNK_ID);
COPY_STR(&header->format, FORMAT_STR);
COPY_STR(&header->subchunk1_id, SUBCHUNK1_ID);
header->subchunk1_size = host2uint16_t_le(PCM_SUBCHUNK1_SIZE);
header->audio_format = host2uint16_t_le(FORMAT_LINEAR_PCM);
COPY_STR(&header->subchunk2_id, SUBCHUNK2_ID);
header->subchunk2_size = host2uint32_t_le(size);
header->sampling_rate = host2uint32_t_le(format.sampling_rate);
header->channels = host2uint32_t_le(format.channels);
header->sample_size =
host2uint16_t_le(pcm_sample_format_size(format.sample_format) * 8);
}
HelenOS homepage, sources at GitHub