audio_format: changed "bits" to "enum sample_format"
This patch prepares support for floating point samples (and probably other formats). It changes the meaning of the "bits" attribute from a bit count to a symbolic value.
This commit is contained in:
@@ -60,6 +60,27 @@ flac_data_deinit(struct flac_data *data)
|
||||
tag_free(data->tag);
|
||||
}
|
||||
|
||||
static enum sample_format
|
||||
flac_sample_format(const FLAC__StreamMetadata_StreamInfo *si)
|
||||
{
|
||||
switch (si->bits_per_sample) {
|
||||
case 8:
|
||||
return SAMPLE_FORMAT_S8;
|
||||
|
||||
case 16:
|
||||
return SAMPLE_FORMAT_S16;
|
||||
|
||||
case 24:
|
||||
return SAMPLE_FORMAT_S24_P32;
|
||||
|
||||
case 32:
|
||||
return SAMPLE_FORMAT_S32;
|
||||
|
||||
default:
|
||||
return SAMPLE_FORMAT_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
flac_data_get_audio_format(struct flac_data *data,
|
||||
struct audio_format *audio_format)
|
||||
@@ -71,9 +92,11 @@ flac_data_get_audio_format(struct flac_data *data,
|
||||
return false;
|
||||
}
|
||||
|
||||
data->sample_format = flac_sample_format(&data->stream_info);
|
||||
|
||||
if (!audio_format_init_checked(audio_format,
|
||||
data->stream_info.sample_rate,
|
||||
data->stream_info.bits_per_sample,
|
||||
data->sample_format,
|
||||
data->stream_info.channels, &error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
@@ -144,7 +167,7 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
|
||||
buffer = pcm_buffer_get(&data->buffer, buffer_size);
|
||||
|
||||
flac_convert(buffer, frame->header.channels,
|
||||
frame->header.bits_per_sample, buf,
|
||||
data->sample_format, buf,
|
||||
0, frame->header.blocksize);
|
||||
|
||||
if (data->next_frame >= data->first_frame)
|
||||
|
@@ -38,6 +38,8 @@
|
||||
struct flac_data {
|
||||
struct pcm_buffer buffer;
|
||||
|
||||
enum sample_format sample_format;
|
||||
|
||||
/**
|
||||
* The size of one frame in the output buffer.
|
||||
*/
|
||||
|
@@ -101,13 +101,33 @@ setup_virtual_fops(struct input_stream *stream)
|
||||
return vf;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
static enum sample_format
|
||||
audiofile_bits_to_sample_format(int bits)
|
||||
{
|
||||
switch (bits) {
|
||||
case 8:
|
||||
return SAMPLE_FORMAT_S8;
|
||||
|
||||
case 16:
|
||||
return SAMPLE_FORMAT_S16;
|
||||
|
||||
case 24:
|
||||
return SAMPLE_FORMAT_S24_P32;
|
||||
|
||||
case 32:
|
||||
return SAMPLE_FORMAT_S32;
|
||||
}
|
||||
|
||||
return SAMPLE_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
static enum sample_format
|
||||
audiofile_setup_sample_format(AFfilehandle af_fp)
|
||||
{
|
||||
int fs, bits;
|
||||
|
||||
afGetSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
|
||||
if (!audio_valid_sample_format(bits)) {
|
||||
if (!audio_valid_sample_format(audiofile_bits_to_sample_format(bits))) {
|
||||
g_debug("input file has %d bit samples, converting to 16",
|
||||
bits);
|
||||
bits = 16;
|
||||
@@ -117,7 +137,7 @@ audiofile_setup_sample_format(AFfilehandle af_fp)
|
||||
AF_SAMPFMT_TWOSCOMP, bits);
|
||||
afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
|
||||
|
||||
return bits;
|
||||
return audiofile_bits_to_sample_format(bits);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -283,7 +283,7 @@ faad_decoder_init(faacDecHandle decoder, struct decoder_buffer *buffer,
|
||||
decoder_buffer_consume(buffer, nbytes);
|
||||
|
||||
return audio_format_init_checked(audio_format, sample_rate,
|
||||
16, channels, error_r);
|
||||
SAMPLE_FORMAT_S16, channels, error_r);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -277,6 +277,26 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static enum sample_format
|
||||
ffmpeg_sample_format(G_GNUC_UNUSED const AVCodecContext *codec_context)
|
||||
{
|
||||
#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(41<<8)+0)
|
||||
int bits = (uint8_t) av_get_bits_per_sample_format(codec_context->sample_fmt);
|
||||
|
||||
/* XXX implement & test other sample formats */
|
||||
|
||||
switch (bits) {
|
||||
case 16:
|
||||
return SAMPLE_FORMAT_S16;
|
||||
}
|
||||
|
||||
return SAMPLE_FORMAT_UNDEFINED;
|
||||
#else
|
||||
/* XXX fixme 16-bit for older ffmpeg (13 Aug 2007) */
|
||||
return SAMPLE_FORMAT_S16;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
ffmpeg_decode_internal(struct ffmpeg_context *ctx)
|
||||
{
|
||||
@@ -288,7 +308,6 @@ ffmpeg_decode_internal(struct ffmpeg_context *ctx)
|
||||
struct audio_format audio_format;
|
||||
enum decoder_command cmd;
|
||||
int total_time;
|
||||
uint8_t bits;
|
||||
|
||||
total_time = 0;
|
||||
|
||||
@@ -296,14 +315,9 @@ ffmpeg_decode_internal(struct ffmpeg_context *ctx)
|
||||
codec_context->channels = 2;
|
||||
}
|
||||
|
||||
#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(41<<8)+0)
|
||||
bits = (uint8_t) av_get_bits_per_sample_format(codec_context->sample_fmt);
|
||||
#else
|
||||
/* XXX fixme 16-bit for older ffmpeg (13 Aug 2007) */
|
||||
bits = (uint8_t) 16;
|
||||
#endif
|
||||
if (!audio_format_init_checked(&audio_format,
|
||||
codec_context->sample_rate, bits,
|
||||
codec_context->sample_rate,
|
||||
ffmpeg_sample_format(codec_context),
|
||||
codec_context->channels, &error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
|
@@ -20,6 +20,8 @@
|
||||
#include "config.h"
|
||||
#include "flac_pcm.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
static void flac_convert_stereo16(int16_t *dest,
|
||||
const FLAC__int32 * const buf[],
|
||||
unsigned int position, unsigned int end)
|
||||
@@ -74,12 +76,12 @@ flac_convert_8(int8_t *dest,
|
||||
|
||||
void
|
||||
flac_convert(void *dest,
|
||||
unsigned int num_channels, unsigned sample_format,
|
||||
unsigned int num_channels, enum sample_format sample_format,
|
||||
const FLAC__int32 *const buf[],
|
||||
unsigned int position, unsigned int end)
|
||||
{
|
||||
switch (sample_format) {
|
||||
case 16:
|
||||
case SAMPLE_FORMAT_S16:
|
||||
if (num_channels == 2)
|
||||
flac_convert_stereo16((int16_t*)dest, buf,
|
||||
position, end);
|
||||
@@ -88,15 +90,19 @@ flac_convert(void *dest,
|
||||
position, end);
|
||||
break;
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
case SAMPLE_FORMAT_S24_P32:
|
||||
case SAMPLE_FORMAT_S32:
|
||||
flac_convert_32((int32_t*)dest, num_channels, buf,
|
||||
position, end);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
case SAMPLE_FORMAT_S8:
|
||||
flac_convert_8((int8_t*)dest, num_channels, buf,
|
||||
position, end);
|
||||
break;
|
||||
|
||||
case SAMPLE_FORMAT_UNDEFINED:
|
||||
/* unreachable */
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
@@ -20,11 +20,13 @@
|
||||
#ifndef MPD_FLAC_PCM_H
|
||||
#define MPD_FLAC_PCM_H
|
||||
|
||||
#include "audio_format.h"
|
||||
|
||||
#include <FLAC/ordinals.h>
|
||||
|
||||
void
|
||||
flac_convert(void *dest,
|
||||
unsigned int num_channels, unsigned sample_format,
|
||||
unsigned int num_channels, enum sample_format sample_format,
|
||||
const FLAC__int32 *const buf[],
|
||||
unsigned int position, unsigned int end);
|
||||
|
||||
|
@@ -88,7 +88,7 @@ fluidsynth_file_decode(struct decoder *decoder, const char *path_fs)
|
||||
{
|
||||
static const struct audio_format audio_format = {
|
||||
.sample_rate = 48000,
|
||||
.bits = 16,
|
||||
.format = SAMPLE_FORMAT_S16,
|
||||
.channels = 2,
|
||||
};
|
||||
char setting_sample_rate[] = "synth.sample-rate";
|
||||
|
@@ -1188,7 +1188,8 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
|
||||
}
|
||||
|
||||
if (!audio_format_init_checked(&audio_format,
|
||||
data.frame.header.samplerate, 24,
|
||||
data.frame.header.samplerate,
|
||||
SAMPLE_FORMAT_S24_P32,
|
||||
MAD_NCHANNELS(&data.frame.header),
|
||||
&error)) {
|
||||
g_warning("%s", error->message);
|
||||
|
@@ -163,7 +163,7 @@ mikmod_decoder_file_decode(struct decoder *decoder, const char *path_fs)
|
||||
/* Prevent module from looping forever */
|
||||
handle->loop = 0;
|
||||
|
||||
audio_format_init(&audio_format, mikmod_sample_rate, 16, 2);
|
||||
audio_format_init(&audio_format, mikmod_sample_rate, SAMPLE_FORMAT_S16, 2);
|
||||
assert(audio_format_valid(&audio_format));
|
||||
|
||||
decoder_initialized(decoder, &audio_format, false, 0);
|
||||
|
@@ -122,7 +122,7 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
|
||||
return;
|
||||
}
|
||||
|
||||
audio_format_init(&audio_format, 44100, 16, 2);
|
||||
audio_format_init(&audio_format, 44100, SAMPLE_FORMAT_S16, 2);
|
||||
assert(audio_format_valid(&audio_format));
|
||||
|
||||
decoder_initialized(decoder, &audio_format,
|
||||
|
@@ -132,7 +132,8 @@ mp4_faad_new(mp4ff_t *mp4fh, int *track_r, struct audio_format *audio_format)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!audio_format_init_checked(audio_format, sample_rate, 16, channels,
|
||||
if (!audio_format_init_checked(audio_format, sample_rate,
|
||||
SAMPLE_FORMAT_S16, channels,
|
||||
&error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
|
@@ -196,7 +196,8 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
|
||||
mpc_demux_get_info(demux, &info);
|
||||
#endif
|
||||
|
||||
if (!audio_format_init_checked(&audio_format, info.sample_freq, 24,
|
||||
if (!audio_format_init_checked(&audio_format, info.sample_freq,
|
||||
SAMPLE_FORMAT_S24_P32,
|
||||
info.channels, &error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
|
@@ -87,7 +87,7 @@ mpd_mpg123_open(mpg123_handle *handle, const char *path_fs,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!audio_format_init_checked(audio_format, rate, 16,
|
||||
if (!audio_format_init_checked(audio_format, rate, SAMPLE_FORMAT_S16,
|
||||
channels, &gerror)) {
|
||||
g_warning("%s", gerror->message);
|
||||
g_error_free(gerror);
|
||||
|
@@ -277,7 +277,7 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs)
|
||||
/* initialize the MPD decoder */
|
||||
|
||||
struct audio_format audio_format;
|
||||
audio_format_init(&audio_format, 48000, 16, 2);
|
||||
audio_format_init(&audio_format, 48000, SAMPLE_FORMAT_S16, 2);
|
||||
assert(audio_format_valid(&audio_format));
|
||||
|
||||
decoder_initialized(decoder, &audio_format, true, (float)song_len);
|
||||
|
@@ -130,7 +130,8 @@ sndfile_stream_decode(struct decoder *decoder, struct input_stream *is)
|
||||
/* for now, always read 32 bit samples. Later, we could lower
|
||||
MPD's CPU usage by reading 16 bit samples with
|
||||
sf_readf_short() on low-quality source files. */
|
||||
if (!audio_format_init_checked(&audio_format, info.samplerate, 32,
|
||||
if (!audio_format_init_checked(&audio_format, info.samplerate,
|
||||
SAMPLE_FORMAT_S32,
|
||||
info.channels, &error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
|
@@ -311,7 +311,8 @@ vorbis_stream_decode(struct decoder *decoder,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!audio_format_init_checked(&audio_format, vi->rate, 16,
|
||||
if (!audio_format_init_checked(&audio_format, vi->rate,
|
||||
SAMPLE_FORMAT_S16,
|
||||
vi->channels, &error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
|
@@ -123,6 +123,33 @@ format_samples_float(G_GNUC_UNUSED int bytes_per_sample, void *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose a MPD sample format from libwavpacks' number of bits.
|
||||
*/
|
||||
static enum sample_format
|
||||
wavpack_bits_to_sample_format(bool is_float, int bytes_per_sample)
|
||||
{
|
||||
if (is_float)
|
||||
return SAMPLE_FORMAT_S24_P32;
|
||||
|
||||
switch (bytes_per_sample) {
|
||||
case 1:
|
||||
return SAMPLE_FORMAT_S8;
|
||||
|
||||
case 2:
|
||||
return SAMPLE_FORMAT_S16;
|
||||
|
||||
case 3:
|
||||
return SAMPLE_FORMAT_S24_P32;
|
||||
|
||||
case 4:
|
||||
return SAMPLE_FORMAT_S32;
|
||||
|
||||
default:
|
||||
return SAMPLE_FORMAT_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This does the main decoding thing.
|
||||
* Requires an already opened WavpackContext.
|
||||
@@ -132,7 +159,8 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek,
|
||||
struct replay_gain_info *replay_gain_info)
|
||||
{
|
||||
GError *error = NULL;
|
||||
unsigned bits;
|
||||
bool is_float;
|
||||
enum sample_format sample_format;
|
||||
struct audio_format audio_format;
|
||||
format_samples_t format_samples;
|
||||
char chunk[CHUNK_SIZE];
|
||||
@@ -141,19 +169,14 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek,
|
||||
int bytes_per_sample, output_sample_size;
|
||||
int position;
|
||||
|
||||
bits = WavpackGetBitsPerSample(wpc);
|
||||
|
||||
/* round bitwidth to 8-bit units */
|
||||
bits = (bits + 7) & (~7);
|
||||
/* MPD handles max 32-bit samples */
|
||||
if (bits > 32)
|
||||
bits = 32;
|
||||
|
||||
if ((WavpackGetMode(wpc) & MODE_FLOAT) == MODE_FLOAT)
|
||||
bits = 24;
|
||||
is_float = (WavpackGetMode(wpc) & MODE_FLOAT) != 0;
|
||||
sample_format =
|
||||
wavpack_bits_to_sample_format(is_float,
|
||||
WavpackGetBytesPerSample(wpc));
|
||||
|
||||
if (!audio_format_init_checked(&audio_format,
|
||||
WavpackGetSampleRate(wpc), bits,
|
||||
WavpackGetSampleRate(wpc),
|
||||
sample_format,
|
||||
WavpackGetNumChannels(wpc), &error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
|
@@ -59,7 +59,7 @@ wildmidi_file_decode(struct decoder *decoder, const char *path_fs)
|
||||
{
|
||||
static const struct audio_format audio_format = {
|
||||
.sample_rate = WILDMIDI_SAMPLE_RATE,
|
||||
.bits = 16,
|
||||
.format = SAMPLE_FORMAT_S16,
|
||||
.channels = 2,
|
||||
};
|
||||
midi *wm;
|
||||
|
Reference in New Issue
Block a user