decoder: use audio_format_init_checked()
Let the audio_check library verify the audio format in all (relevant, i.e. non-hardcoded) plugins.
This commit is contained in:
		| @@ -789,6 +789,7 @@ test_run_decoder_SOURCES = test/run_decoder.c \ | ||||
| 	src/replay_gain.c \ | ||||
| 	src/uri.c \ | ||||
| 	src/fd_util.c \ | ||||
| 	src/audio_check.c \ | ||||
| 	$(ARCHIVE_SRC) \ | ||||
| 	$(INPUT_SRC) \ | ||||
| 	$(TAG_SRC) \ | ||||
| @@ -809,6 +810,7 @@ test_read_tags_SOURCES = test/read_tags.c \ | ||||
| 	src/replay_gain.c \ | ||||
| 	src/uri.c \ | ||||
| 	src/fd_util.c \ | ||||
| 	src/audio_check.c \ | ||||
| 	$(ARCHIVE_SRC) \ | ||||
| 	$(INPUT_SRC) \ | ||||
| 	$(TAG_SRC) \ | ||||
|   | ||||
| @@ -25,6 +25,7 @@ | ||||
| #include "_flac_common.h" | ||||
| #include "flac_metadata.h" | ||||
| #include "flac_pcm.h" | ||||
| #include "audio_check.h" | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| @@ -63,20 +64,19 @@ bool | ||||
| flac_data_get_audio_format(struct flac_data *data, | ||||
| 			   struct audio_format *audio_format) | ||||
| { | ||||
| 	GError *error = NULL; | ||||
|  | ||||
| 	if (!data->have_stream_info) { | ||||
| 		g_warning("no STREAMINFO packet found"); | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	audio_format_init(audio_format, data->stream_info.sample_rate, | ||||
| 			  data->stream_info.bits_per_sample, | ||||
| 			  data->stream_info.channels); | ||||
|  | ||||
| 	if (!audio_format_valid(audio_format)) { | ||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", | ||||
| 			  audio_format->sample_rate, | ||||
| 			  audio_format->bits, | ||||
| 			  audio_format->channels); | ||||
| 	if (!audio_format_init_checked(audio_format, | ||||
| 				       data->stream_info.sample_rate, | ||||
| 				       data->stream_info.bits_per_sample, | ||||
| 				       data->stream_info.channels, &error)) { | ||||
| 		g_warning("%s", error->message); | ||||
| 		g_error_free(error); | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "decoder_api.h" | ||||
| #include "audio_check.h" | ||||
|  | ||||
| #include <audiofile.h> | ||||
| #include <af_vfs.h> | ||||
| @@ -103,6 +104,7 @@ setup_virtual_fops(struct input_stream *stream) | ||||
| static void | ||||
| audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) | ||||
| { | ||||
| 	GError *error = NULL; | ||||
| 	AFvirtualfile *vf; | ||||
| 	int fs, frame_count; | ||||
| 	AFfilehandle af_fp; | ||||
| @@ -138,13 +140,13 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) | ||||
| 	                         AF_SAMPFMT_TWOSCOMP, bits); | ||||
| 	afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); | ||||
|  | ||||
| 	audio_format_init(&audio_format, afGetRate(af_fp, AF_DEFAULT_TRACK), | ||||
| 			  bits, afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK));  | ||||
|  | ||||
| 	if (!audio_format_valid(&audio_format)) { | ||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", | ||||
| 			  audio_format.sample_rate, audio_format.bits, | ||||
| 			  audio_format.channels); | ||||
| 	if (!audio_format_init_checked(&audio_format, | ||||
| 				       afGetRate(af_fp, AF_DEFAULT_TRACK), | ||||
| 				       bits, | ||||
| 				       afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK), | ||||
| 				       &error)) { | ||||
| 		g_warning("%s", error->message); | ||||
| 		g_error_free(error); | ||||
| 		afCloseFile(af_fp); | ||||
| 		return; | ||||
| 	} | ||||
|   | ||||
| @@ -20,6 +20,7 @@ | ||||
| #include "config.h" | ||||
| #include "decoder_api.h" | ||||
| #include "decoder_buffer.h" | ||||
| #include "audio_check.h" | ||||
|  | ||||
| #define AAC_MAX_CHANNELS	6 | ||||
|  | ||||
| @@ -36,6 +37,15 @@ static const unsigned adts_sample_rates[] = | ||||
| 	16000, 12000, 11025, 8000, 7350, 0, 0, 0 | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * The GLib quark used for errors reported by this plugin. | ||||
|  */ | ||||
| static inline GQuark | ||||
| faad_decoder_quark(void) | ||||
| { | ||||
| 	return g_quark_from_static_string("faad"); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Check whether the buffer head is an AAC frame, and return the frame | ||||
|  * length.  Returns 0 if it is not a frame. | ||||
| @@ -232,7 +242,7 @@ faad_song_duration(struct decoder_buffer *buffer, struct input_stream *is) | ||||
|  */ | ||||
| static bool | ||||
| faad_decoder_init(faacDecHandle decoder, struct decoder_buffer *buffer, | ||||
| 		  struct audio_format *audio_format) | ||||
| 		  struct audio_format *audio_format, GError **error_r) | ||||
| { | ||||
| 	union { | ||||
| 		/* deconst hack for libfaad */ | ||||
| @@ -247,28 +257,33 @@ faad_decoder_init(faacDecHandle decoder, struct decoder_buffer *buffer, | ||||
| 	/* neaacdec.h declares all arguments as "unsigned long", but | ||||
| 	   internally expects uint32_t pointers.  To avoid gcc | ||||
| 	   warnings, use this workaround. */ | ||||
| 	unsigned long *sample_rate_r = (unsigned long *)(void *)&sample_rate; | ||||
| 	unsigned long *sample_rate_p = (unsigned long *)(void *)&sample_rate; | ||||
| #else | ||||
| 	uint32_t *sample_rate_r = &sample_rate; | ||||
| 	uint32_t *sample_rate_p = &sample_rate; | ||||
| #endif | ||||
|  | ||||
| 	u.in = decoder_buffer_read(buffer, &length); | ||||
| 	if (u.in == NULL) | ||||
| 	if (u.in == NULL) { | ||||
| 		g_set_error(error_r, faad_decoder_quark(), 0, | ||||
| 			    "Empty file"); | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	nbytes = faacDecInit(decoder, u.out, | ||||
| #ifdef HAVE_FAAD_BUFLEN_FUNCS | ||||
| 			     length, | ||||
| #endif | ||||
| 			     sample_rate_r, &channels); | ||||
| 	if (nbytes < 0) | ||||
| 			     sample_rate_p, &channels); | ||||
| 	if (nbytes < 0) { | ||||
| 		g_set_error(error_r, faad_decoder_quark(), 0, | ||||
| 			    "Not an AAC stream"); | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	decoder_buffer_consume(buffer, nbytes); | ||||
|  | ||||
| 	audio_format_init(audio_format, sample_rate, 16, channels); | ||||
|  | ||||
| 	return true; | ||||
| 	return audio_format_init_checked(audio_format, sample_rate, | ||||
| 					 16, channels, error_r); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -334,8 +349,8 @@ faad_get_file_time_float(const char *file) | ||||
|  | ||||
| 		decoder_buffer_fill(buffer); | ||||
|  | ||||
| 		ret = faad_decoder_init(decoder, buffer, &audio_format); | ||||
| 		if (ret && audio_format_valid(&audio_format)) | ||||
| 		ret = faad_decoder_init(decoder, buffer, &audio_format, NULL); | ||||
| 		if (ret) | ||||
| 			length = 0; | ||||
|  | ||||
| 		faacDecClose(decoder); | ||||
| @@ -367,6 +382,7 @@ faad_get_file_time(const char *file) | ||||
| static void | ||||
| faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is) | ||||
| { | ||||
| 	GError *error = NULL; | ||||
| 	float file_time; | ||||
| 	float total_time = 0; | ||||
| 	faacDecHandle decoder; | ||||
| @@ -404,15 +420,10 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is) | ||||
|  | ||||
| 	/* initialize it */ | ||||
|  | ||||
| 	ret = faad_decoder_init(decoder, buffer, &audio_format); | ||||
| 	ret = faad_decoder_init(decoder, buffer, &audio_format, &error); | ||||
| 	if (!ret) { | ||||
| 		g_warning("Error not a AAC stream.\n"); | ||||
| 		faacDecClose(decoder); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (!audio_format_valid(&audio_format)) { | ||||
| 		g_warning("invalid audio format\n"); | ||||
| 		g_warning("%s", error->message); | ||||
| 		g_error_free(error); | ||||
| 		faacDecClose(decoder); | ||||
| 		return; | ||||
| 	} | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "decoder_api.h" | ||||
| #include "audio_check.h" | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| @@ -260,6 +261,7 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, | ||||
| static bool | ||||
| ffmpeg_decode_internal(struct ffmpeg_context *ctx) | ||||
| { | ||||
| 	GError *error = NULL; | ||||
| 	struct decoder *decoder = ctx->decoder; | ||||
| 	AVCodecContext *codec_context = ctx->codec_context; | ||||
| 	AVFormatContext *format_context = ctx->format_context; | ||||
| @@ -281,13 +283,11 @@ ffmpeg_decode_internal(struct ffmpeg_context *ctx) | ||||
| 	/* XXX fixme 16-bit for older ffmpeg (13 Aug 2007) */ | ||||
| 	bits = (uint8_t) 16; | ||||
| #endif | ||||
| 	audio_format_init(&audio_format, codec_context->sample_rate, bits, | ||||
| 			  codec_context->channels); | ||||
|  | ||||
| 	if (!audio_format_valid(&audio_format)) { | ||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", | ||||
| 			  audio_format.sample_rate, audio_format.bits, | ||||
| 			  audio_format.channels); | ||||
| 	if (!audio_format_init_checked(&audio_format, | ||||
| 				       codec_context->sample_rate, bits, | ||||
| 				       codec_context->channels, &error)) { | ||||
| 		g_warning("%s", error->message); | ||||
| 		g_error_free(error); | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -21,6 +21,7 @@ | ||||
| #include "decoder_api.h" | ||||
| #include "conf.h" | ||||
| #include "tag_id3.h" | ||||
| #include "audio_check.h" | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <unistd.h> | ||||
| @@ -1174,6 +1175,7 @@ static void | ||||
| mp3_decode(struct decoder *decoder, struct input_stream *input_stream) | ||||
| { | ||||
| 	struct mp3_data data; | ||||
| 	GError *error = NULL; | ||||
| 	struct tag *tag = NULL; | ||||
| 	struct replay_gain_info *replay_gain_info = NULL; | ||||
| 	struct audio_format audio_format; | ||||
| @@ -1185,8 +1187,20 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream) | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	audio_format_init(&audio_format, data.frame.header.samplerate, 24, | ||||
| 			  MAD_NCHANNELS(&data.frame.header)); | ||||
| 	if (!audio_format_init_checked(&audio_format, | ||||
| 				       data.frame.header.samplerate, 24, | ||||
| 				       MAD_NCHANNELS(&data.frame.header), | ||||
| 				       &error)) { | ||||
| 		g_warning("%s", error->message); | ||||
| 		g_error_free(error); | ||||
|  | ||||
| 		if (tag != NULL) | ||||
| 			tag_free(tag); | ||||
| 		if (replay_gain_info != NULL) | ||||
| 			replay_gain_info_free(replay_gain_info); | ||||
| 		mp3_data_finish(&data); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	decoder_initialized(decoder, &audio_format, | ||||
| 			    data.input_stream->seekable, data.total_time); | ||||
|   | ||||
| @@ -22,6 +22,7 @@ | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <mikmod.h> | ||||
| #include <assert.h> | ||||
|  | ||||
| #undef G_LOG_DOMAIN | ||||
| #define G_LOG_DOMAIN "mikmod" | ||||
| @@ -177,6 +178,7 @@ mod_decode(struct decoder *decoder, const char *path) | ||||
| 	} | ||||
|  | ||||
| 	audio_format_init(&audio_format, 44100, 16, 2); | ||||
| 	assert(audio_format_valid(&audio_format)); | ||||
|  | ||||
| 	secPerByte = | ||||
| 	    1.0 / ((audio_format.bits * audio_format.channels / 8.0) * | ||||
|   | ||||
| @@ -22,6 +22,7 @@ | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <modplug.h> | ||||
| #include <assert.h> | ||||
|  | ||||
| #undef G_LOG_DOMAIN | ||||
| #define G_LOG_DOMAIN "modplug" | ||||
| @@ -123,6 +124,7 @@ mod_decode(struct decoder *decoder, struct input_stream *is) | ||||
| 	} | ||||
|  | ||||
| 	audio_format_init(&audio_format, 44100, 16, 2); | ||||
| 	assert(audio_format_valid(&audio_format)); | ||||
|  | ||||
| 	sec_perbyte = | ||||
| 	    1.0 / ((audio_format.bits * audio_format.channels / 8.0) * | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "decoder_api.h" | ||||
| #include "audio_check.h" | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| @@ -110,6 +111,7 @@ mp4_faad_new(mp4ff_t *mp4fh, int *track_r, struct audio_format *audio_format) | ||||
| 	int track; | ||||
| 	uint32_t sample_rate; | ||||
| 	unsigned char channels; | ||||
| 	GError *error = NULL; | ||||
|  | ||||
| 	decoder = faacDecOpen(); | ||||
|  | ||||
| @@ -130,18 +132,16 @@ mp4_faad_new(mp4ff_t *mp4fh, int *track_r, struct audio_format *audio_format) | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	*track_r = track; | ||||
| 	audio_format_init(audio_format, sample_rate, 16, channels); | ||||
|  | ||||
| 	if (!audio_format_valid(audio_format)) { | ||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", | ||||
| 			  audio_format->sample_rate, | ||||
| 			  audio_format->bits, | ||||
| 			  audio_format->channels); | ||||
| 	if (!audio_format_init_checked(audio_format, sample_rate, 16, channels, | ||||
| 				       &error)) { | ||||
| 		g_warning("%s", error->message); | ||||
| 		g_error_free(error); | ||||
| 		faacDecClose(decoder); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	*track_r = track; | ||||
|  | ||||
| 	return decoder; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "decoder_api.h" | ||||
| #include "audio_check.h" | ||||
|  | ||||
| #ifdef MPC_IS_OLD_API | ||||
| #include <mpcdec/mpcdec.h> | ||||
| @@ -27,6 +28,7 @@ | ||||
| #endif | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <assert.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #undef G_LOG_DOMAIN | ||||
| @@ -140,6 +142,7 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is) | ||||
| #endif | ||||
| 	mpc_reader reader; | ||||
| 	mpc_streaminfo info; | ||||
| 	GError *error = NULL; | ||||
| 	struct audio_format audio_format; | ||||
|  | ||||
| 	struct mpc_decoder_data data; | ||||
| @@ -193,16 +196,13 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is) | ||||
| 	mpc_demux_get_info(demux, &info); | ||||
| #endif | ||||
|  | ||||
| 	audio_format_init(&audio_format, info.sample_freq, 24, info.channels); | ||||
|  | ||||
| 	if (!audio_format_valid(&audio_format)) { | ||||
| 	if (!audio_format_init_checked(&audio_format, info.sample_freq, 16, | ||||
| 				       info.channels, &error)) { | ||||
| 		g_warning("%s", error->message); | ||||
| 		g_error_free(error); | ||||
| #ifndef MPC_IS_OLD_API | ||||
| 		mpc_demux_exit(demux); | ||||
| #endif | ||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", | ||||
| 			  audio_format.sample_rate, | ||||
| 			  audio_format.bits, | ||||
| 			  audio_format.channels); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|  | ||||
| #include "config.h" /* must be first for large file support */ | ||||
| #include "decoder_api.h" | ||||
| #include "audio_check.h" | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| @@ -54,6 +55,7 @@ static bool | ||||
| mpd_mpg123_open(mpg123_handle *handle, const char *path_fs, | ||||
| 		struct audio_format *audio_format) | ||||
| { | ||||
| 	GError *gerror = NULL; | ||||
| 	char *path_dup; | ||||
| 	int error; | ||||
| 	int channels, encoding; | ||||
| @@ -85,9 +87,10 @@ mpd_mpg123_open(mpg123_handle *handle, const char *path_fs, | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	audio_format_init(audio_format, rate, 16, channels); | ||||
| 	if (!audio_format_valid(audio_format)) { | ||||
| 		g_warning("invalid audio format"); | ||||
| 	if (!audio_format_init_checked(audio_format, rate, 16, | ||||
| 				       channels, &gerror)) { | ||||
| 		g_warning("%s", gerror->message); | ||||
| 		g_error_free(gerror); | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -278,6 +278,7 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs) | ||||
|  | ||||
| 	struct audio_format audio_format; | ||||
| 	audio_format_init(&audio_format, 48000, 16, 2); | ||||
| 	assert(audio_format_valid(&audio_format)); | ||||
|  | ||||
| 	decoder_initialized(decoder, &audio_format, true, (float)song_len); | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "decoder_api.h" | ||||
| #include "audio_check.h" | ||||
|  | ||||
| #include <sndfile.h> | ||||
|  | ||||
| @@ -109,6 +110,7 @@ time_to_frame(float t, const struct audio_format *audio_format) | ||||
| static void | ||||
| sndfile_stream_decode(struct decoder *decoder, struct input_stream *is) | ||||
| { | ||||
| 	GError *error = NULL; | ||||
| 	SNDFILE *sf; | ||||
| 	SF_INFO info; | ||||
| 	struct audio_format audio_format; | ||||
| @@ -128,10 +130,10 @@ 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. */ | ||||
| 	audio_format_init(&audio_format, info.samplerate, 32, info.channels); | ||||
|  | ||||
| 	if (!audio_format_valid(&audio_format)) { | ||||
| 		g_warning("invalid audio format"); | ||||
| 	if (!audio_format_init_checked(&audio_format, info.samplerate, 32, | ||||
| 				       info.channels, &error)) { | ||||
| 		g_warning("%s", error->message); | ||||
| 		g_error_free(error); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "_ogg_common.h" | ||||
| #include "audio_check.h" | ||||
| #include "uri.h" | ||||
|  | ||||
| #ifndef HAVE_TREMOR | ||||
| @@ -264,6 +265,7 @@ static void | ||||
| vorbis_stream_decode(struct decoder *decoder, | ||||
| 		     struct input_stream *input_stream) | ||||
| { | ||||
| 	GError *error = NULL; | ||||
| 	OggVorbis_File vf; | ||||
| 	ov_callbacks callbacks; | ||||
| 	struct vorbis_decoder_data data; | ||||
| @@ -309,13 +311,10 @@ vorbis_stream_decode(struct decoder *decoder, | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	audio_format_init(&audio_format, vi->rate, 16, vi->channels); | ||||
|  | ||||
| 	if (!audio_format_valid(&audio_format)) { | ||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", | ||||
| 			  audio_format.sample_rate, | ||||
| 			  audio_format.bits, | ||||
| 			  audio_format.channels); | ||||
| 	if (!audio_format_init_checked(&audio_format, vi->rate, 16, | ||||
| 				       vi->channels, &error)) { | ||||
| 		g_warning("%s", error->message); | ||||
| 		g_error_free(error); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "decoder_api.h" | ||||
| #include "audio_check.h" | ||||
| #include "path.h" | ||||
| #include "utils.h" | ||||
|  | ||||
| @@ -130,6 +131,8 @@ static void | ||||
| wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek, | ||||
| 	       struct replay_gain_info *replay_gain_info) | ||||
| { | ||||
| 	GError *error = NULL; | ||||
| 	unsigned bits; | ||||
| 	struct audio_format audio_format; | ||||
| 	format_samples_t format_samples; | ||||
| 	char chunk[CHUNK_SIZE]; | ||||
| @@ -138,24 +141,22 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek, | ||||
| 	int bytes_per_sample, output_sample_size; | ||||
| 	int position; | ||||
|  | ||||
| 	audio_format_init(&audio_format, WavpackGetSampleRate(wpc), | ||||
| 			  WavpackGetBitsPerSample(wpc),  | ||||
| 			  WavpackGetNumChannels(wpc)); | ||||
| 	bits = WavpackGetBitsPerSample(wpc); | ||||
|  | ||||
| 	/* round bitwidth to 8-bit units */ | ||||
| 	audio_format.bits = (audio_format.bits + 7) & (~7); | ||||
| 	bits = (bits + 7) & (~7); | ||||
| 	/* MPD handles max 32-bit samples */ | ||||
| 	if (audio_format.bits > 32) | ||||
| 		audio_format.bits = 32; | ||||
| 	if (bits > 32) | ||||
| 		bits = 32; | ||||
|  | ||||
| 	if ((WavpackGetMode(wpc) & MODE_FLOAT) == MODE_FLOAT) | ||||
| 		audio_format.bits = 24; | ||||
| 		bits = 24; | ||||
|  | ||||
| 	if (!audio_format_valid(&audio_format)) { | ||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", | ||||
| 			  audio_format.sample_rate, | ||||
| 			  audio_format.bits, | ||||
| 			  audio_format.channels); | ||||
| 	if (!audio_format_init_checked(&audio_format, | ||||
| 				       WavpackGetSampleRate(wpc), bits, | ||||
| 				       WavpackGetNumChannels(wpc), &error)) { | ||||
| 		g_warning("%s", error->message); | ||||
| 		g_error_free(error); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann