/** * Convert to 24 bit packed samples (aka S24_3LE / S24_3BE). */ static const void * pcm_convert_24_packed(struct pcm_convert_state *state, const struct audio_format *src_format, const void *src_buffer, size_t src_size, const struct audio_format *dest_format, size_t *dest_size_r, GError **error_r) { assert(dest_format->format == SAMPLE_FORMAT_S24); /* use the normal 24 bit conversion first */ struct audio_format audio_format; audio_format_init(&audio_format, dest_format->sample_rate, SAMPLE_FORMAT_S24_P32, dest_format->channels); const int32_t *buffer; size_t buffer_size; buffer = pcm_convert_24(state, src_format, src_buffer, src_size, &audio_format, &buffer_size, error_r); if (buffer == NULL) return NULL; /* now convert to packed 24 bit */ unsigned num_samples = buffer_size / 4; size_t dest_size = num_samples * 3; uint8_t *dest = pcm_buffer_get(&state->pack_buffer, dest_size); pcm_pack_24(dest, buffer, num_samples, dest_format->reverse_endian); *dest_size_r = dest_size; return dest; }
void test_pcm_pack_24(void) { enum { N = 256 }; int32_t src[N * 3]; for (unsigned i = 0; i < N; ++i) src[i] = random24(); uint8_t dest[N * 3]; pcm_pack_24(dest, src, src + N); for (unsigned i = 0; i < N; ++i) { int32_t d; if (G_BYTE_ORDER == G_BIG_ENDIAN) d = (dest[i * 3] << 16) | (dest[i * 3 + 1] << 8) | dest[i * 3 + 2]; else d = (dest[i * 3 + 2] << 16) | (dest[i * 3 + 1] << 8) | dest[i * 3]; if (d & 0x800000) d |= 0xff000000; g_assert_cmpint(d, ==, src[i]); } }