Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2950a7e4d | ||
|
|
4b4aa64261 | ||
|
|
26735390ff | ||
|
|
9402b23dd5 | ||
|
|
246db3d565 | ||
|
|
eaf414cbc8 | ||
|
|
327d41c00f | ||
|
|
05d8ce3bcd | ||
|
|
def2fe8805 | ||
|
|
f680b0a431 | ||
|
|
d4b00ff11c | ||
|
|
532f94a187 | ||
|
|
87ad2f8542 | ||
|
|
a8f891efcd | ||
|
|
b5fc2419e8 | ||
|
|
fe588a255b | ||
|
|
1fc571088b | ||
|
|
8d83914f05 | ||
|
|
0fdcd381bc | ||
|
|
4f293ecd6f | ||
|
|
b6303313f0 | ||
|
|
a28449a123 | ||
|
|
6dcec36621 | ||
|
|
84d0fd39a3 | ||
|
|
4d4b7e3de0 | ||
|
|
e2aea6bce5 | ||
|
|
5779146a7f | ||
|
|
a1d1c2beaa | ||
|
|
ee9c60fad4 | ||
|
|
1674a4ec82 | ||
|
|
ce370bee60 | ||
|
|
e257484870 | ||
|
|
2a1f4539f6 | ||
|
|
906efdd320 | ||
|
|
948b8f35e6 | ||
|
|
e776c605ad | ||
|
|
8b2f4fc823 | ||
|
|
03018611f8 | ||
|
|
8f99c954ad | ||
|
|
5735c9efc1 | ||
|
|
e6c3acaa6f | ||
|
|
44b4b50949 |
@@ -859,6 +859,7 @@ test_run_input_LDADD = $(MPD_LIBS) \
|
||||
$(INPUT_LIBS) \
|
||||
$(GLIB_LIBS)
|
||||
test_run_input_SOURCES = test/run_input.c \
|
||||
test/stdbin.h \
|
||||
src/conf.c src/tokenizer.c src/utils.c \
|
||||
src/tag.c src/tag_pool.c src/tag_save.c \
|
||||
src/fd_util.c \
|
||||
@@ -906,6 +907,7 @@ test_run_decoder_LDADD = $(MPD_LIBS) \
|
||||
$(INPUT_LIBS) $(DECODER_LIBS) \
|
||||
$(GLIB_LIBS)
|
||||
test_run_decoder_SOURCES = test/run_decoder.c \
|
||||
test/stdbin.h \
|
||||
src/conf.c src/tokenizer.c src/utils.c src/log.c \
|
||||
src/tag.c src/tag_pool.c \
|
||||
src/replay_gain_info.c \
|
||||
@@ -946,6 +948,7 @@ test_run_filter_LDADD = $(MPD_LIBS) \
|
||||
$(SAMPLERATE_LIBS) \
|
||||
$(GLIB_LIBS)
|
||||
test_run_filter_SOURCES = test/run_filter.c \
|
||||
test/stdbin.h \
|
||||
src/filter_plugin.c \
|
||||
src/filter_registry.c \
|
||||
src/conf.c src/tokenizer.c src/utils.c \
|
||||
@@ -968,6 +971,7 @@ endif
|
||||
if ENABLE_ENCODER
|
||||
noinst_PROGRAMS += test/run_encoder
|
||||
test_run_encoder_SOURCES = test/run_encoder.c \
|
||||
test/stdbin.h \
|
||||
src/conf.c src/tokenizer.c \
|
||||
src/utils.c \
|
||||
src/tag.c src/tag_pool.c \
|
||||
@@ -975,12 +979,15 @@ test_run_encoder_SOURCES = test/run_encoder.c \
|
||||
src/audio_format.c \
|
||||
src/audio_parser.c \
|
||||
$(ENCODER_SRC)
|
||||
test_run_encoder_CPPFLAGS = $(AM_CPPFLAGS) \
|
||||
$(ENCODER_CFLAGS)
|
||||
test_run_encoder_LDADD = $(MPD_LIBS) \
|
||||
$(ENCODER_LIBS) \
|
||||
$(GLIB_LIBS)
|
||||
endif
|
||||
|
||||
test_software_volume_SOURCES = test/software_volume.c \
|
||||
test/stdbin.h \
|
||||
src/audio_check.c \
|
||||
src/audio_parser.c \
|
||||
src/pcm_volume.c
|
||||
@@ -988,6 +995,7 @@ test_software_volume_LDADD = \
|
||||
$(GLIB_LIBS)
|
||||
|
||||
test_run_normalize_SOURCES = test/run_normalize.c \
|
||||
test/stdbin.h \
|
||||
src/audio_check.c \
|
||||
src/audio_parser.c \
|
||||
src/AudioCompress/compress.c
|
||||
@@ -1025,6 +1033,7 @@ test_run_output_LDADD = $(MPD_LIBS) \
|
||||
$(OUTPUT_LIBS) \
|
||||
$(GLIB_LIBS)
|
||||
test_run_output_SOURCES = test/run_output.c \
|
||||
test/stdbin.h \
|
||||
src/conf.c src/tokenizer.c src/utils.c src/log.c \
|
||||
src/audio_check.c \
|
||||
src/audio_format.c \
|
||||
|
||||
39
NEWS
39
NEWS
@@ -1,4 +1,28 @@
|
||||
ver 0.16.1 (2010/01/09)
|
||||
ver 0.16.3 (2011/06/04)
|
||||
* fix assertion failure in audio format mask parser
|
||||
* fix NULL pointer dereference in playlist parser
|
||||
* fix playlist files in base music directory
|
||||
* database: allow directories with just playlists
|
||||
* decoder:
|
||||
- ffmpeg: support libavcodec 0.7
|
||||
|
||||
|
||||
ver 0.16.2 (2011/03/18)
|
||||
* configure.ac:
|
||||
- fix bashism in tremor test
|
||||
* decoder:
|
||||
- tremor: fix configure test
|
||||
- gme: detect end of song
|
||||
* encoder:
|
||||
- vorbis: reset the Ogg stream after flush
|
||||
* output:
|
||||
- httpd: fix uninitialized variable
|
||||
- httpd: include sys/socket.h
|
||||
- oss: AFMT_S24_PACKED is little-endian
|
||||
- oss: disable 24 bit playback on FreeBSD
|
||||
|
||||
|
||||
ver 0.16.1 (2011/01/09)
|
||||
* audio_check: fix parameter in prototype
|
||||
* add void casts to suppress "result unused" warnings (clang)
|
||||
* input:
|
||||
@@ -128,9 +152,20 @@ ver 0.16 (2010/12/11)
|
||||
* make single mode 'sticky'
|
||||
|
||||
|
||||
ver 0.15.16 (2010/??/??)
|
||||
ver 0.15.17 (2011/??/??)
|
||||
* encoder:
|
||||
- vorbis: reset the Ogg stream after flush
|
||||
* decoders:
|
||||
- vorbis: fix tremor support
|
||||
|
||||
|
||||
ver 0.15.16 (2011/03/13)
|
||||
* output:
|
||||
- ao: initialize the ao_sample_format struct
|
||||
- jack: fix crash with mono playback
|
||||
* encoders:
|
||||
- lame: explicitly configure the output sample rate
|
||||
* update: log all file permission problems
|
||||
|
||||
|
||||
ver 0.15.15 (2010/11/08)
|
||||
|
||||
16
configure.ac
16
configure.ac
@@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT(mpd, 0.16.1, musicpd-dev-team@lists.sourceforge.net)
|
||||
AC_INIT(mpd, 0.16.3, musicpd-dev-team@lists.sourceforge.net)
|
||||
AC_CONFIG_SRCDIR([src/main.c])
|
||||
AM_INIT_AUTOMAKE([foreign 1.10 dist-bzip2 subdir-objects])
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
@@ -635,7 +635,7 @@ fi
|
||||
AM_CONDITIONAL(ENABLE_LASTFM, test x$enable_lastfm = xyes)
|
||||
|
||||
dnl ---------------------------------- libogg ---------------------------------
|
||||
if test x$with_tremor == xno || test -z $with_tremor; then
|
||||
if test x$with_tremor = xno || test -z $with_tremor; then
|
||||
PKG_CHECK_MODULES(OGG, [ogg], enable_ogg=yes, enable_ogg=no)
|
||||
fi
|
||||
|
||||
@@ -934,13 +934,19 @@ if test x$enable_tremor = xyes; then
|
||||
ac_save_LIBS="$LIBS"
|
||||
CFLAGS="$CFLAGS $TREMOR_CFLAGS"
|
||||
LIBS="$LIBS $TREMOR_LIBS"
|
||||
AC_CHECK_LIB(vorbisidec,ov_read,enable_vorbis=yes,enable_vorbis=no;
|
||||
AC_CHECK_LIB(vorbisidec,ov_read,,enable_tremor=no;
|
||||
AC_MSG_WARN([vorbisidec lib needed for ogg support with tremor -- disabling ogg support]))
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
|
||||
if test x$enable_tremor = xyes; then
|
||||
AC_DEFINE(HAVE_TREMOR,1,
|
||||
[Define to use tremor (libvorbisidec) for ogg support])
|
||||
AC_DEFINE(ENABLE_VORBIS_DECODER, 1, [Define for Ogg Vorbis support]),
|
||||
else
|
||||
TREMOR_CFLAGS=
|
||||
TREMOR_LIBS=
|
||||
fi
|
||||
|
||||
AC_SUBST(TREMOR_CFLAGS)
|
||||
@@ -980,7 +986,7 @@ if test x$enable_vorbis = xyes; then
|
||||
fi
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(ENABLE_VORBIS_DECODER, test x$enable_vorbis = xyes)
|
||||
AM_CONDITIONAL(ENABLE_VORBIS_DECODER, test x$enable_vorbis = xyes || test x$enable_tremor = xyes)
|
||||
|
||||
dnl --------------------------------- sidplay ---------------------------------
|
||||
found_sidplay=$HAVE_CXX
|
||||
@@ -1075,7 +1081,7 @@ if
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_OGG_COMMON,
|
||||
test x$enable_vorbis = xyes || test x$enable_oggflac = xyes || test x$enable_flac = xyes)
|
||||
test x$enable_vorbis = xyes || test x$enable_tremor = xyes || test x$enable_oggflac = xyes || test x$enable_flac = xyes)
|
||||
|
||||
AM_CONDITIONAL(HAVE_FLAC_COMMON,
|
||||
test x$enable_flac = xyes || test x$enable_oggflac = xyes)
|
||||
|
||||
@@ -16,16 +16,16 @@
|
||||
struct Compressor {
|
||||
//! The compressor's preferences
|
||||
struct CompressorConfig prefs;
|
||||
|
||||
|
||||
//! History of the peak values
|
||||
int *peaks;
|
||||
|
||||
|
||||
//! History of the gain values
|
||||
int *gain;
|
||||
|
||||
|
||||
//! History of clip amounts
|
||||
int *clipped;
|
||||
|
||||
|
||||
unsigned int pos;
|
||||
unsigned int bufsz;
|
||||
};
|
||||
@@ -41,9 +41,9 @@ struct Compressor *Compressor_new(unsigned int history)
|
||||
obj->peaks = obj->gain = obj->clipped = NULL;
|
||||
obj->bufsz = 0;
|
||||
obj->pos = 0;
|
||||
|
||||
|
||||
Compressor_setHistory(obj, history);
|
||||
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ void Compressor_setHistory(struct Compressor *obj, unsigned int history)
|
||||
{
|
||||
if (!history)
|
||||
history = BUCKETS;
|
||||
|
||||
|
||||
obj->peaks = resizeArray(obj->peaks, history, obj->bufsz);
|
||||
obj->gain = resizeArray(obj->gain, history, obj->bufsz);
|
||||
obj->clipped = resizeArray(obj->clipped, history, obj->bufsz);
|
||||
@@ -82,7 +82,7 @@ struct CompressorConfig *Compressor_getConfig(struct Compressor *obj)
|
||||
return &obj->prefs;
|
||||
}
|
||||
|
||||
void Compressor_Process_int16(struct Compressor *obj, int16_t *audio,
|
||||
void Compressor_Process_int16(struct Compressor *obj, int16_t *audio,
|
||||
unsigned int count)
|
||||
{
|
||||
struct CompressorConfig *prefs = Compressor_getConfig(obj);
|
||||
@@ -97,7 +97,7 @@ void Compressor_Process_int16(struct Compressor *obj, int16_t *audio,
|
||||
int *clipped = obj->clipped + slot;
|
||||
unsigned int ramp = count;
|
||||
int delta;
|
||||
|
||||
|
||||
ap = audio;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
@@ -124,15 +124,15 @@ void Compressor_Process_int16(struct Compressor *obj, int16_t *audio,
|
||||
|
||||
//! Determine target gain
|
||||
newGain = (1 << 10)*prefs->target/peakVal;
|
||||
|
||||
|
||||
//! Adjust the gain with inertia from the previous gain value
|
||||
newGain = (curGain*((1 << prefs->smooth) - 1) + newGain)
|
||||
newGain = (curGain*((1 << prefs->smooth) - 1) + newGain)
|
||||
>> prefs->smooth;
|
||||
|
||||
|
||||
//! Make sure it's no more than the maximum gain value
|
||||
if (newGain > (prefs->maxgain << 10))
|
||||
newGain = prefs->maxgain << 10;
|
||||
|
||||
|
||||
//! Make sure it's no less than 1:1
|
||||
if (newGain < (1 << 10))
|
||||
newGain = 1 << 10;
|
||||
@@ -144,7 +144,7 @@ void Compressor_Process_int16(struct Compressor *obj, int16_t *audio,
|
||||
//! Truncate the ramp time
|
||||
ramp = peakPos;
|
||||
}
|
||||
|
||||
|
||||
//! Record the new gain
|
||||
obj->gain[slot] = newGain;
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
enum sample_format {
|
||||
SAMPLE_FORMAT_UNDEFINED = 0,
|
||||
@@ -219,6 +220,9 @@ static inline void
|
||||
audio_format_mask_apply(struct audio_format *af,
|
||||
const struct audio_format *mask)
|
||||
{
|
||||
assert(audio_format_valid(af));
|
||||
assert(audio_format_mask_valid(mask));
|
||||
|
||||
if (mask->sample_rate != 0)
|
||||
af->sample_rate = mask->sample_rate;
|
||||
|
||||
@@ -227,6 +231,8 @@ audio_format_mask_apply(struct audio_format *af,
|
||||
|
||||
if (mask->channels != 0)
|
||||
af->channels = mask->channels;
|
||||
|
||||
assert(audio_format_valid(af));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -192,6 +192,8 @@ audio_format_parse(struct audio_format *dest, const char *src,
|
||||
}
|
||||
|
||||
audio_format_init(dest, rate, sample_format, channels);
|
||||
assert(mask ? audio_format_mask_valid(dest)
|
||||
: audio_format_valid(dest));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -464,7 +464,7 @@ handle_currentsong(struct client *client,
|
||||
G_GNUC_UNUSED int argc, G_GNUC_UNUSED char *argv[])
|
||||
{
|
||||
playlist_print_current(client, &g_playlist);
|
||||
return PLAYLIST_RESULT_SUCCESS;
|
||||
return COMMAND_RETURN_OK;
|
||||
}
|
||||
|
||||
static enum command_return
|
||||
@@ -749,7 +749,7 @@ handle_load(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
|
||||
|
||||
result = playlist_open_into_queue(argv[1], &g_playlist);
|
||||
if (result != PLAYLIST_RESULT_NO_SUCH_LIST)
|
||||
return result;
|
||||
return print_playlist_result(client, result);
|
||||
|
||||
result = playlist_load_spl(&g_playlist, argv[1]);
|
||||
return print_playlist_result(client, result);
|
||||
|
||||
@@ -244,7 +244,7 @@ static const char *const audiofile_suffixes[] = {
|
||||
static const char *const audiofile_mime_types[] = {
|
||||
"audio/x-wav",
|
||||
"audio/x-aiff",
|
||||
NULL
|
||||
NULL
|
||||
};
|
||||
|
||||
const struct decoder_plugin audiofile_decoder_plugin = {
|
||||
|
||||
@@ -81,6 +81,10 @@ mpd_ffmpeg_log_callback(G_GNUC_UNUSED void *ptr, int level,
|
||||
|
||||
#endif /* !OLD_FFMPEG_INCLUDES */
|
||||
|
||||
#ifndef AV_VERSION_INT
|
||||
#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c)
|
||||
#endif
|
||||
|
||||
struct mpd_ffmpeg_stream {
|
||||
struct decoder *decoder;
|
||||
struct input_stream *input;
|
||||
@@ -102,13 +106,11 @@ static int64_t
|
||||
mpd_ffmpeg_stream_seek(void *opaque, int64_t pos, int whence)
|
||||
{
|
||||
struct mpd_ffmpeg_stream *stream = opaque;
|
||||
bool ret;
|
||||
|
||||
if (whence == AVSEEK_SIZE)
|
||||
return stream->input->size;
|
||||
|
||||
ret = input_stream_seek(stream->input, pos, whence, NULL);
|
||||
if (!ret)
|
||||
if (!input_stream_seek(stream->input, pos, whence, NULL))
|
||||
return -1;
|
||||
|
||||
return stream->input->offset;
|
||||
@@ -156,7 +158,11 @@ ffmpeg_find_audio_stream(const AVFormatContext *format_context)
|
||||
{
|
||||
for (unsigned i = 0; i < format_context->nb_streams; ++i)
|
||||
if (format_context->streams[i]->codec->codec_type ==
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 64, 0)
|
||||
AVMEDIA_TYPE_AUDIO)
|
||||
#else
|
||||
CODEC_TYPE_AUDIO)
|
||||
#endif
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
@@ -183,30 +189,40 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
|
||||
AVCodecContext *codec_context,
|
||||
const AVRational *time_base)
|
||||
{
|
||||
enum decoder_command cmd = DECODE_COMMAND_NONE;
|
||||
uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2 + 16];
|
||||
int16_t *aligned_buffer;
|
||||
size_t buffer_size;
|
||||
int len, audio_size;
|
||||
uint8_t *packet_data;
|
||||
int packet_size;
|
||||
|
||||
if (packet->pts != (int64_t)AV_NOPTS_VALUE)
|
||||
decoder_timestamp(decoder,
|
||||
av_rescale_q(packet->pts, *time_base,
|
||||
(AVRational){1, 1}));
|
||||
|
||||
packet_data = packet->data;
|
||||
packet_size = packet->size;
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0)
|
||||
AVPacket packet2 = *packet;
|
||||
#else
|
||||
const uint8_t *packet_data = packet->data;
|
||||
int packet_size = packet->size;
|
||||
#endif
|
||||
|
||||
buffer_size = sizeof(audio_buf);
|
||||
aligned_buffer = align16(audio_buf, &buffer_size);
|
||||
uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2 + 16];
|
||||
size_t buffer_size = sizeof(audio_buf);
|
||||
int16_t *aligned_buffer = align16(audio_buf, &buffer_size);
|
||||
|
||||
while ((packet_size > 0) && (cmd == DECODE_COMMAND_NONE)) {
|
||||
audio_size = buffer_size;
|
||||
len = avcodec_decode_audio2(codec_context,
|
||||
aligned_buffer, &audio_size,
|
||||
packet_data, packet_size);
|
||||
enum decoder_command cmd = DECODE_COMMAND_NONE;
|
||||
while (
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0)
|
||||
packet2.size > 0 &&
|
||||
#else
|
||||
packet_size > 0 &&
|
||||
#endif
|
||||
cmd == DECODE_COMMAND_NONE) {
|
||||
int audio_size = buffer_size;
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0)
|
||||
int len = avcodec_decode_audio3(codec_context,
|
||||
aligned_buffer, &audio_size,
|
||||
&packet2);
|
||||
#else
|
||||
int len = avcodec_decode_audio2(codec_context,
|
||||
aligned_buffer, &audio_size,
|
||||
packet_data, packet_size);
|
||||
#endif
|
||||
|
||||
if (len < 0) {
|
||||
/* if error, we skip the frame */
|
||||
@@ -214,8 +230,13 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
|
||||
break;
|
||||
}
|
||||
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0)
|
||||
packet2.data += len;
|
||||
packet2.size -= len;
|
||||
#else
|
||||
packet_data += len;
|
||||
packet_size -= len;
|
||||
#endif
|
||||
|
||||
if (audio_size <= 0)
|
||||
continue;
|
||||
@@ -230,7 +251,7 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is,
|
||||
static enum sample_format
|
||||
ffmpeg_sample_format(G_GNUC_UNUSED const AVCodecContext *codec_context)
|
||||
{
|
||||
#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(41<<8)+0)
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(51, 41, 0)
|
||||
switch (codec_context->sample_fmt) {
|
||||
case SAMPLE_FMT_S16:
|
||||
return SAMPLE_FORMAT_S16;
|
||||
@@ -299,12 +320,8 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
|
||||
return;
|
||||
}
|
||||
|
||||
AVFormatContext *format_context;
|
||||
AVCodecContext *codec_context;
|
||||
AVCodec *codec;
|
||||
int audio_stream;
|
||||
|
||||
//ffmpeg works with ours "fileops" helper
|
||||
AVFormatContext *format_context;
|
||||
if (av_open_input_stream(&format_context, stream->io, input->uri,
|
||||
input_format, NULL) != 0) {
|
||||
g_warning("Open failed\n");
|
||||
@@ -319,7 +336,7 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
|
||||
return;
|
||||
}
|
||||
|
||||
audio_stream = ffmpeg_find_audio_stream(format_context);
|
||||
int audio_stream = ffmpeg_find_audio_stream(format_context);
|
||||
if (audio_stream == -1) {
|
||||
g_warning("No audio stream inside\n");
|
||||
av_close_input_stream(format_context);
|
||||
@@ -327,11 +344,12 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
|
||||
return;
|
||||
}
|
||||
|
||||
codec_context = format_context->streams[audio_stream]->codec;
|
||||
AVCodecContext *codec_context =
|
||||
format_context->streams[audio_stream]->codec;
|
||||
if (codec_context->codec_name[0] != 0)
|
||||
g_debug("codec '%s'", codec_context->codec_name);
|
||||
|
||||
codec = avcodec_find_decoder(codec_context->codec_id);
|
||||
AVCodec *codec = avcodec_find_decoder(codec_context->codec_id);
|
||||
|
||||
if (!codec) {
|
||||
g_warning("Unsupported audio codec\n");
|
||||
|
||||
@@ -81,7 +81,7 @@ flac_tell_cb(G_GNUC_UNUSED const FLAC__StreamDecoder *fd,
|
||||
struct flac_data *data = (struct flac_data *) fdata;
|
||||
|
||||
if (!data->input_stream->seekable)
|
||||
return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
|
||||
return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
|
||||
|
||||
*offset = (long)(data->input_stream->offset);
|
||||
|
||||
|
||||
@@ -153,6 +153,9 @@ gme_file_decode(struct decoder *decoder, const char *path_fs)
|
||||
if((gme_err = gme_start_track(emu, song_num)) != NULL)
|
||||
g_warning("%s", gme_err);
|
||||
|
||||
if(ti->length > 0)
|
||||
gme_set_fade(emu, ti->length);
|
||||
|
||||
/* play */
|
||||
do {
|
||||
gme_err = gme_play(emu, GME_BUFFER_SAMPLES, buf);
|
||||
|
||||
@@ -62,7 +62,8 @@ directory_free(struct directory *directory);
|
||||
static inline bool
|
||||
directory_is_empty(const struct directory *directory)
|
||||
{
|
||||
return directory->children.nr == 0 && directory->songs.nr == 0;
|
||||
return directory->children.nr == 0 && directory->songs.nr == 0 &&
|
||||
playlist_vector_is_empty(&directory->playlists);
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
|
||||
@@ -55,7 +55,7 @@ static bool
|
||||
flac_encoder_configure(struct flac_encoder *encoder,
|
||||
const struct config_param *param, G_GNUC_UNUSED GError **error)
|
||||
{
|
||||
encoder->compression = config_get_block_unsigned(param,
|
||||
encoder->compression = config_get_block_unsigned(param,
|
||||
"compression", 5);
|
||||
|
||||
return true;
|
||||
@@ -218,7 +218,7 @@ flac_encoder_open(struct encoder *_encoder, struct audio_format *audio_format,
|
||||
|
||||
if (init_status != FLAC__STREAM_ENCODER_OK) {
|
||||
g_set_error(error, flac_encoder_quark(), 0,
|
||||
"failed to initialize encoder: %s\n",
|
||||
"failed to initialize encoder: %s\n",
|
||||
FLAC__StreamEncoderStateString[init_status]);
|
||||
flac_encoder_close(_encoder);
|
||||
return false;
|
||||
@@ -234,7 +234,7 @@ flac_encoder_open(struct encoder *_encoder, struct audio_format *audio_format,
|
||||
|
||||
if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
|
||||
g_set_error(error, flac_encoder_quark(), 0,
|
||||
"failed to initialize encoder: %s\n",
|
||||
"failed to initialize encoder: %s\n",
|
||||
FLAC__StreamEncoderInitStatusString[init_status]);
|
||||
flac_encoder_close(_encoder);
|
||||
return false;
|
||||
|
||||
@@ -276,6 +276,8 @@ vorbis_encoder_flush(struct encoder *_encoder, G_GNUC_UNUSED GError **error)
|
||||
vorbis_analysis_init(&encoder->vd, &encoder->vi);
|
||||
vorbis_block_init(&encoder->vd, &encoder->vb);
|
||||
|
||||
ogg_stream_reset(&encoder->os);
|
||||
|
||||
encoder->flush = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ wave_encoder_quark(void)
|
||||
}
|
||||
|
||||
static void
|
||||
fill_wave_header(struct wave_header *header, int channels, int bits,
|
||||
fill_wave_header(struct wave_header *header, int channels, int bits,
|
||||
int freq, int block_size)
|
||||
{
|
||||
int data_size = 0x0FFFFFFF;
|
||||
@@ -142,7 +142,7 @@ wave_encoder_open(struct encoder *_encoder,
|
||||
buffer = pcm_buffer_get(&encoder->buffer, sizeof(struct wave_header) );
|
||||
|
||||
/* create PCM wave header in initial buffer */
|
||||
fill_wave_header((struct wave_header *) buffer,
|
||||
fill_wave_header((struct wave_header *) buffer,
|
||||
audio_format->channels,
|
||||
encoder->bits,
|
||||
audio_format->sample_rate,
|
||||
|
||||
@@ -58,11 +58,11 @@ winmm_mixer_init(void *ao, G_GNUC_UNUSED const struct config_param *param,
|
||||
G_GNUC_UNUSED GError **error_r)
|
||||
{
|
||||
assert(ao != NULL);
|
||||
|
||||
|
||||
struct winmm_mixer *wm = g_new(struct winmm_mixer, 1);
|
||||
mixer_init(&wm->base, &winmm_mixer_plugin);
|
||||
wm->output = (struct winmm_output *) ao;
|
||||
|
||||
|
||||
return &wm->base;
|
||||
}
|
||||
|
||||
@@ -79,13 +79,13 @@ winmm_mixer_get_volume(struct mixer *mixer, GError **error_r)
|
||||
DWORD volume;
|
||||
HWAVEOUT handle = winmm_output_get_handle(wm->output);
|
||||
MMRESULT result = waveOutGetVolume(handle, &volume);
|
||||
|
||||
|
||||
if (result != MMSYSERR_NOERROR) {
|
||||
g_set_error(error_r, 0, winmm_mixer_quark(),
|
||||
"Failed to get winmm volume");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return winmm_volume_decode(volume);
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ winmm_mixer_set_volume(struct mixer *mixer, unsigned volume, GError **error_r)
|
||||
"Failed to set winmm volume");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "ao"
|
||||
|
||||
/* An ao_sample_format, with all fields set to zero: */
|
||||
static const ao_sample_format OUR_AO_FORMAT_INITIALIZER;
|
||||
|
||||
static unsigned ao_output_ref;
|
||||
|
||||
struct ao_data {
|
||||
@@ -167,7 +170,7 @@ static bool
|
||||
ao_output_open(void *data, struct audio_format *audio_format,
|
||||
GError **error)
|
||||
{
|
||||
ao_sample_format format;
|
||||
ao_sample_format format = OUR_AO_FORMAT_INITIALIZER;
|
||||
struct ao_data *ad = (struct ao_data *)data;
|
||||
|
||||
switch (audio_format->format) {
|
||||
|
||||
@@ -111,7 +111,7 @@ struct httpd_output {
|
||||
char buffer[32768];
|
||||
|
||||
/**
|
||||
* The maximum and current number of clients connected
|
||||
* The maximum and current number of clients connected
|
||||
* at the same time.
|
||||
*/
|
||||
guint clients_max, clients_cnt;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_LIBWRAP
|
||||
#include <sys/socket.h> /* needed for AF_UNIX */
|
||||
#include <tcpd.h>
|
||||
#endif
|
||||
|
||||
@@ -123,6 +124,7 @@ httpd_output_init(G_GNUC_UNUSED const struct audio_format *audio_format,
|
||||
|
||||
/* initialize metadata */
|
||||
httpd->metadata = NULL;
|
||||
httpd->unflushed_input = 0;
|
||||
|
||||
/* initialize encoder */
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ enum {
|
||||
MAX_PORTS = 16,
|
||||
};
|
||||
|
||||
static const size_t sample_size = sizeof(jack_default_audio_sample_t);
|
||||
static const size_t jack_sample_size = sizeof(jack_default_audio_sample_t);
|
||||
|
||||
struct jack_data {
|
||||
/**
|
||||
@@ -103,9 +103,9 @@ mpd_jack_available(const struct jack_data *jd)
|
||||
min = current;
|
||||
}
|
||||
|
||||
assert(min % sample_size == 0);
|
||||
assert(min % jack_sample_size == 0);
|
||||
|
||||
return min / sample_size;
|
||||
return min / jack_sample_size;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -123,7 +123,7 @@ mpd_jack_process(jack_nframes_t nframes, void *arg)
|
||||
const jack_nframes_t available = mpd_jack_available(jd);
|
||||
for (unsigned i = 0; i < jd->audio_format.channels; ++i)
|
||||
jack_ringbuffer_read_advance(jd->ringbuffer[i],
|
||||
available * sample_size);
|
||||
available * jack_sample_size);
|
||||
|
||||
/* generate silence while MPD is paused */
|
||||
|
||||
@@ -144,7 +144,7 @@ mpd_jack_process(jack_nframes_t nframes, void *arg)
|
||||
for (unsigned i = 0; i < jd->audio_format.channels; ++i) {
|
||||
out = jack_port_get_buffer(jd->ports[i], nframes);
|
||||
jack_ringbuffer_read(jd->ringbuffer[i],
|
||||
(char *)out, available * sample_size);
|
||||
(char *)out, available * jack_sample_size);
|
||||
|
||||
for (jack_nframes_t f = available; f < nframes; ++f)
|
||||
/* ringbuffer underrun, fill with silence */
|
||||
@@ -675,7 +675,7 @@ mpd_jack_play(void *data, const void *chunk, size_t size, GError **error_r)
|
||||
space = space1;
|
||||
}
|
||||
|
||||
if (space >= frame_size)
|
||||
if (space >= jack_sample_size)
|
||||
break;
|
||||
|
||||
/* XXX do something more intelligent to
|
||||
@@ -683,7 +683,7 @@ mpd_jack_play(void *data, const void *chunk, size_t size, GError **error_r)
|
||||
g_usleep(1000);
|
||||
}
|
||||
|
||||
space /= sample_size;
|
||||
space /= jack_sample_size;
|
||||
if (space < size)
|
||||
size = space;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Media MVP audio output based on code from MVPMC project:
|
||||
* http://mvpmc.sourceforge.net/
|
||||
*/
|
||||
|
||||
@@ -41,6 +41,15 @@
|
||||
# include <sys/soundcard.h>
|
||||
#endif /* !(defined(__OpenBSD__) || defined(__NetBSD__) */
|
||||
|
||||
/* We got bug reports from FreeBSD users who said that the two 24 bit
|
||||
formats generate white noise on FreeBSD, but 32 bit works. This is
|
||||
a workaround until we know what exactly is expected by the kernel
|
||||
audio drivers. */
|
||||
#ifndef __linux__
|
||||
#undef AFMT_S24_PACKED
|
||||
#undef AFMT_S24_NE
|
||||
#endif
|
||||
|
||||
struct oss_data {
|
||||
int fd;
|
||||
const char *device;
|
||||
@@ -347,7 +356,7 @@ oss_setup_sample_rate(int fd, struct audio_format *audio_format,
|
||||
case SUCCESS:
|
||||
if (!audio_valid_sample_rate(sample_rate))
|
||||
break;
|
||||
|
||||
|
||||
audio_format->sample_rate = sample_rate;
|
||||
return true;
|
||||
|
||||
@@ -461,6 +470,12 @@ oss_setup_sample_format(int fd, struct audio_format *audio_format,
|
||||
break;
|
||||
|
||||
audio_format->format = mpd_format;
|
||||
|
||||
#ifdef AFMT_S24_PACKED
|
||||
if (oss_format == AFMT_S24_PACKED)
|
||||
audio_format->reverse_endian =
|
||||
G_BYTE_ORDER != G_LITTLE_ENDIAN;
|
||||
#endif
|
||||
return true;
|
||||
|
||||
case ERROR:
|
||||
@@ -502,6 +517,12 @@ oss_setup_sample_format(int fd, struct audio_format *audio_format,
|
||||
break;
|
||||
|
||||
audio_format->format = mpd_format;
|
||||
|
||||
#ifdef AFMT_S24_PACKED
|
||||
if (oss_format == AFMT_S24_PACKED)
|
||||
audio_format->reverse_endian =
|
||||
G_BYTE_ORDER != G_LITTLE_ENDIAN;
|
||||
#endif
|
||||
return true;
|
||||
|
||||
case ERROR:
|
||||
|
||||
@@ -115,6 +115,7 @@ audio_output_open(struct audio_output *ao,
|
||||
{
|
||||
bool open;
|
||||
|
||||
assert(audio_format_valid(audio_format));
|
||||
assert(mp != NULL);
|
||||
|
||||
if (ao->fail_timer != NULL) {
|
||||
|
||||
@@ -95,6 +95,8 @@ ao_filter_open(struct audio_output *ao,
|
||||
struct audio_format *audio_format,
|
||||
GError **error_r)
|
||||
{
|
||||
assert(audio_format_valid(audio_format));
|
||||
|
||||
/* the replay_gain filter cannot fail here */
|
||||
if (ao->replay_gain_filter != NULL)
|
||||
filter_open(ao->replay_gain_filter, audio_format, error_r);
|
||||
@@ -136,6 +138,7 @@ ao_open(struct audio_output *ao)
|
||||
assert(!ao->open);
|
||||
assert(ao->pipe != NULL);
|
||||
assert(ao->chunk == NULL);
|
||||
assert(audio_format_valid(&ao->in_audio_format));
|
||||
|
||||
if (ao->fail_timer != NULL) {
|
||||
/* this can only happen when this
|
||||
@@ -164,6 +167,8 @@ ao_open(struct audio_output *ao)
|
||||
return;
|
||||
}
|
||||
|
||||
assert(audio_format_valid(filter_audio_format));
|
||||
|
||||
ao->out_audio_format = *filter_audio_format;
|
||||
audio_format_mask_apply(&ao->out_audio_format,
|
||||
&ao->config_audio_format);
|
||||
|
||||
@@ -49,7 +49,7 @@ const int16_t *pcm_byteswap_16(struct pcm_buffer *buffer,
|
||||
|
||||
static inline uint32_t swab32(uint32_t x)
|
||||
{
|
||||
return (x << 24) |
|
||||
return (x << 24) |
|
||||
((x & 0xff00) << 8) |
|
||||
((x & 0xff0000) >> 8) |
|
||||
(x >> 24);
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
#ifndef MPD_PIPE_H
|
||||
#define MPD_PIPE_H
|
||||
|
||||
#ifndef NDEBUG
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef NDEBUG
|
||||
struct audio_format;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -105,6 +105,13 @@ playlist_check_translate_song(struct song *song, const char *base_uri)
|
||||
}
|
||||
}
|
||||
|
||||
if (base_uri != NULL && strcmp(base_uri, ".") == 0)
|
||||
/* g_path_get_dirname() returns "." when there is no
|
||||
directory name in the given path; clear that now,
|
||||
because it would break the database lookup
|
||||
functions */
|
||||
base_uri = NULL;
|
||||
|
||||
if (g_path_is_absolute(uri)) {
|
||||
/* XXX fs_charset vs utf8? */
|
||||
char *prefix = base_uri != NULL
|
||||
@@ -129,7 +136,7 @@ playlist_check_translate_song(struct song *song, const char *base_uri)
|
||||
else
|
||||
uri = g_strdup(uri);
|
||||
|
||||
if (uri_has_scheme(base_uri)) {
|
||||
if (uri_has_scheme(uri)) {
|
||||
dest = song_remote_new(uri);
|
||||
g_free(uri);
|
||||
} else {
|
||||
|
||||
@@ -51,6 +51,12 @@ playlist_vector_init(struct playlist_vector *pv)
|
||||
void
|
||||
playlist_vector_deinit(struct playlist_vector *pv);
|
||||
|
||||
static inline bool
|
||||
playlist_vector_is_empty(const struct playlist_vector *pv)
|
||||
{
|
||||
return pv->head == NULL;
|
||||
}
|
||||
|
||||
struct playlist_metadata *
|
||||
playlist_vector_find(struct playlist_vector *pv, const char *name);
|
||||
|
||||
|
||||
@@ -300,6 +300,9 @@ stat_directory(const struct directory *directory, struct stat *st)
|
||||
if (path_fs == NULL)
|
||||
return -1;
|
||||
ret = stat(path_fs, st);
|
||||
if (ret < 0)
|
||||
g_warning("Failed to stat %s: %s", path_fs, g_strerror(errno));
|
||||
|
||||
g_free(path_fs);
|
||||
return ret;
|
||||
}
|
||||
@@ -316,6 +319,9 @@ stat_directory_child(const struct directory *parent, const char *name,
|
||||
return -1;
|
||||
|
||||
ret = stat(path_fs, st);
|
||||
if (ret < 0)
|
||||
g_warning("Failed to stat %s: %s", path_fs, g_strerror(errno));
|
||||
|
||||
g_free(path_fs);
|
||||
return ret;
|
||||
}
|
||||
@@ -557,6 +563,7 @@ directory_child_access(const struct directory *directory,
|
||||
/* access() is useless on WIN32 */
|
||||
(void)directory;
|
||||
(void)name;
|
||||
(void)mode;
|
||||
return true;
|
||||
#else
|
||||
char *path = map_directory_child_fs(directory, name);
|
||||
|
||||
Reference in New Issue
Block a user