Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
2777a236
Commit
2777a236
authored
Jul 29, 2016
by
Max Kellermann
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'v0.19.x'
parents
32afd92d
762f3afb
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
348 additions
and
72 deletions
+348
-72
INSTALL
INSTALL
+1
-1
NEWS
NEWS
+7
-0
configure.ac
configure.ac
+17
-12
developer.xml
doc/developer.xml
+1
-1
mpdconf.example
doc/mpdconf.example
+1
-1
Compiler.h
src/Compiler.h
+1
-1
FfmpegDecoderPlugin.cxx
src/decoder/plugins/FfmpegDecoderPlugin.cxx
+137
-21
SidplayDecoderPlugin.cxx
src/decoder/plugins/SidplayDecoderPlugin.cxx
+180
-34
ShoutOutputPlugin.cxx
src/output/plugins/ShoutOutputPlugin.cxx
+3
-1
No files found.
INSTALL
View file @
2777a236
...
...
@@ -12,7 +12,7 @@ install MPD. If more information is desired, read the user manual:
Dependencies
------------
gcc 4.
6
or later - http://gcc.gnu.org/
gcc 4.
7
or later - http://gcc.gnu.org/
clang 3.2 or later - http://clang.llvm.org/
Any other C++11 compliant compiler should also work.
...
...
NEWS
View file @
2777a236
...
...
@@ -59,6 +59,13 @@ ver 0.19.18 (not yet released)
- ffmpeg: fix crash with older FFmpeg versions (< 3.0)
- ffmpeg: log detailed error message
- ffmpeg: support FFmpeg 3.1
- sidplay: detect libsidplay2 with pkg-config
- sidplay: log detailed error message
- sidplay: read the "date" tag
- sidplay: allow building with libsidplayfp instead of libsidplay2
* output
- shout: recognize setting "encoder" instead of "encoding"
* require gcc 4.7 or newer
ver 0.19.17 (2016/07/09)
* decoder
...
...
configure.ac
View file @
2777a236
...
...
@@ -979,31 +979,36 @@ AM_CONDITIONAL(ENABLE_VORBIS_DECODER, test x$enable_vorbis = xyes || test x$enab
dnl --------------------------------- sidplay ---------------------------------
if test x$enable_sidplay != xno; then
# we're not using pkg-config here
# because libsidplay2's .pc file requires libtool
AC_CHECK_LIB([sidplay2],[main],[found_sidplay=yes],[found_sidplay=no],[])
dnl Check for libsidplayfp first
PKG_CHECK_MODULES([SIDPLAY], [libsidplayfp libsidutils],
[found_sidplayfp=yes],
[found_sidplayfp=no])
found_sidplay=$found_sidplayfp
fi
if test x$enable_sidplay != xno && test x$found_sidplayfp = xno; then
PKG_CHECK_MODULES([SIDPLAY], [libsidplay2 libsidutils],
[found_sidplay=yes],
[found_sidplay=no])
MPD_AUTO_PRE(sidplay, [sidplay decoder plugin],
[libsidplay2 not found])
fi
if test x$enable_sidplay != xno; then
if test x$enable_sidplay != xno
&& test x$found_sidplayfp = xno
; then
AC_CHECK_LIB([resid-builder], [main],
[found_sidplay=yes], [found_sidplay=no])
if test x$found_sidplay = xyes; then
AC_CHECK_LIB([sidutils],[main],[:],[found_sidplay=no],[])
fi
MPD_AUTO_RESULT(sidplay, [sidplay decoder plugin],
[libresid-builder
or libsidutils
not found])
[libresid-builder not found])
fi
if test x$enable_sidplay = xyes; then
AC_SUBST(SIDPLAY_LIBS,"-lsidplay2 -lresid-builder -lsidutils")
AC_SUBST(SIDPLAY_CFLAGS,)
SIDPLAY_LIBS="$SIDPLAY_LIBS -lresid-builder"
AC_DEFINE(ENABLE_SIDPLAY, 1, [Define for libsidplay2 support])
if test x$found_sidplayfp = xyes; then
AC_DEFINE(HAVE_SIDPLAYFP, 1, [Define if libsidplayfp is used instead of libsidplay2])
fi
fi
AM_CONDITIONAL(ENABLE_SIDPLAY, test x$enable_sidplay = xyes)
...
...
doc/developer.xml
View file @
2777a236
...
...
@@ -41,7 +41,7 @@
<listitem>
<para>
the code should be C++11 compliant, and must compile with
<application>
GCC
</application>
4.
6
and
<application>
GCC
</application>
4.
7
and
<application>
clang
</application>
3.2
</para>
</listitem>
...
...
doc/mpdconf.example
View file @
2777a236
...
...
@@ -232,7 +232,7 @@ input {
#
#audio_output {
# type "shout"
# encod
ing "ogg"
# optional
# encod
er "vorbis"
# optional
# name "My Shout Stream"
# host "localhost"
# port "8000"
...
...
src/Compiler.h
View file @
2777a236
...
...
@@ -57,7 +57,7 @@
# error Sorry, your clang version is too old. You need at least version 3.1.
# endif
#elif defined(__GNUC__)
# if GCC_OLDER_THAN(4,
6
)
# if GCC_OLDER_THAN(4,
7
)
# error Sorry, your gcc version is too old. You need at least version 4.6.
# endif
#else
...
...
src/decoder/plugins/FfmpegDecoderPlugin.cxx
View file @
2777a236
...
...
@@ -38,6 +38,7 @@
#include "tag/MixRamp.hxx"
#include "input/InputStream.hxx"
#include "CheckAudioFormat.hxx"
#include "util/ScopeExit.hxx"
#include "util/ConstBuffer.hxx"
#include "util/Error.hxx"
#include "LogV.hxx"
...
...
@@ -59,15 +60,24 @@ extern "C" {
static
AVFormatContext
*
FfmpegOpenInput
(
AVIOContext
*
pb
,
const
char
*
filename
,
AVInputFormat
*
fmt
)
AVInputFormat
*
fmt
,
Error
&
error
)
{
AVFormatContext
*
context
=
avformat_alloc_context
();
if
(
context
==
nullptr
)
if
(
context
==
nullptr
)
{
error
.
Set
(
ffmpeg_domain
,
"Out of memory"
);
return
nullptr
;
}
context
->
pb
=
pb
;
avformat_open_input
(
&
context
,
filename
,
fmt
,
nullptr
);
int
err
=
avformat_open_input
(
&
context
,
filename
,
fmt
,
nullptr
);
if
(
err
<
0
)
{
avformat_free_context
(
context
);
SetFfmpegError
(
error
,
err
,
"avformat_open_input() failed"
);
return
nullptr
;
}
return
context
;
}
...
...
@@ -252,6 +262,54 @@ FfmpegSendFrame(Decoder &decoder, InputStream &is,
codec_context
.
bit_rate
/
1000
);
}
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 0)
static
DecoderCommand
FfmpegReceiveFrames
(
Decoder
&
decoder
,
InputStream
&
is
,
AVCodecContext
&
codec_context
,
AVFrame
&
frame
,
size_t
&
skip_bytes
,
FfmpegBuffer
&
buffer
,
bool
&
eof
)
{
while
(
true
)
{
DecoderCommand
cmd
;
int
err
=
avcodec_receive_frame
(
&
codec_context
,
&
frame
);
switch
(
err
)
{
case
0
:
cmd
=
FfmpegSendFrame
(
decoder
,
is
,
codec_context
,
frame
,
skip_bytes
,
buffer
);
if
(
cmd
!=
DecoderCommand
::
NONE
)
return
cmd
;
break
;
case
AVERROR_EOF
:
eof
=
true
;
return
DecoderCommand
::
NONE
;
case
AVERROR
(
EAGAIN
):
/* need to call avcodec_send_packet() */
return
DecoderCommand
::
NONE
;
default
:
{
char
msg
[
256
];
av_strerror
(
err
,
msg
,
sizeof
(
msg
));
FormatWarning
(
ffmpeg_domain
,
"avcodec_send_packet() failed: %s"
,
msg
);
}
return
DecoderCommand
::
STOP
;
}
}
}
#endif
/**
* Decode an #AVPacket and send the resulting PCM data to the decoder
* API.
...
...
@@ -284,6 +342,36 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is,
stream
.
time_base
));
}
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 0)
bool
eof
=
false
;
int
err
=
avcodec_send_packet
(
&
codec_context
,
&
packet
);
switch
(
err
)
{
case
0
:
break
;
case
AVERROR_EOF
:
eof
=
true
;
break
;
default
:
{
char
msg
[
256
];
av_strerror
(
err
,
msg
,
sizeof
(
msg
));
FormatWarning
(
ffmpeg_domain
,
"avcodec_send_packet() failed: %s"
,
msg
);
}
return
DecoderCommand
::
NONE
;
}
auto
cmd
=
FfmpegReceiveFrames
(
decoder
,
is
,
codec_context
,
frame
,
skip_bytes
,
buffer
,
eof
);
if
(
eof
)
cmd
=
DecoderCommand
::
STOP
;
#else
DecoderCommand
cmd
=
DecoderCommand
::
NONE
;
while
(
packet
.
size
>
0
&&
cmd
==
DecoderCommand
::
NONE
)
{
int
got_frame
=
0
;
...
...
@@ -306,6 +394,7 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is,
frame
,
skip_bytes
,
buffer
);
}
#endif
return
cmd
;
}
...
...
@@ -529,7 +618,10 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
AVStream
&
av_stream
=
*
format_context
.
streams
[
audio_stream
];
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(57, 5, 0)
AVCodecContext
*
codec_context
=
av_stream
.
codec
;
#endif
const
auto
&
codec_params
=
GetCodecParameters
(
av_stream
);
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 25, 0)
...
...
@@ -551,6 +643,18 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
return
;
}
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 5, 0)
AVCodecContext
*
codec_context
=
avcodec_alloc_context3
(
codec
);
if
(
codec_context
==
nullptr
)
{
LogError
(
ffmpeg_domain
,
"avcodec_alloc_context3() failed"
);
return
;
}
AtScopeExit
(
&
codec_context
)
{
avcodec_free_context
(
&
codec_context
);
};
#endif
const
SampleFormat
sample_format
=
ffmpeg_sample_format
(
GetSampleFormat
(
codec_params
));
if
(
sample_format
==
SampleFormat
::
UNDEFINED
)
{
...
...
@@ -579,6 +683,12 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
return
;
}
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(57, 5, 0)
AtScopeExit
(
codec_context
)
{
avcodec_close
(
codec_context
);
};
#endif
const
SignedSongTime
total_time
=
FromFfmpegTimeChecked
(
av_stream
.
duration
,
av_stream
.
time_base
);
...
...
@@ -597,6 +707,16 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
return
;
}
AtScopeExit
(
&
frame
)
{
#if LIBAVUTIL_VERSION_MAJOR >= 53
av_frame_free
(
&
frame
);
#elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 28, 0)
avcodec_free_frame
(
&
frame
);
#else
av_free
(
frame
);
#endif
};
FfmpegBuffer
interleaved_buffer
;
uint64_t
min_frame
=
0
;
...
...
@@ -649,16 +769,6 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
av_free_packet
(
&
packet
);
#endif
}
#if LIBAVUTIL_VERSION_MAJOR >= 53
av_frame_free
(
&
frame
);
#elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 28, 0)
avcodec_free_frame
(
&
frame
);
#else
av_free
(
frame
);
#endif
avcodec_close
(
codec_context
);
}
static
void
...
...
@@ -677,16 +787,19 @@ ffmpeg_decode(Decoder &decoder, InputStream &input)
return
;
}
Error
error
;
AVFormatContext
*
format_context
=
FfmpegOpenInput
(
stream
.
io
,
input
.
GetURI
(),
input_format
);
FfmpegOpenInput
(
stream
.
io
,
input
.
GetURI
(),
input_format
,
error
);
if
(
format_context
==
nullptr
)
{
LogError
(
ffmpeg_domain
,
"Open failed"
);
LogError
(
error
);
return
;
}
FfmpegDecode
(
decoder
,
input
,
*
format_context
);
AtScopeExit
(
&
format_context
)
{
avformat_close_input
(
&
format_context
);
};
avformat_close_input
(
&
format_context
);
FfmpegDecode
(
decoder
,
input
,
*
format_context
);
}
static
bool
...
...
@@ -726,13 +839,16 @@ ffmpeg_scan_stream(InputStream &is,
return
false
;
AVFormatContext
*
f
=
FfmpegOpenInput
(
stream
.
io
,
is
.
GetURI
(),
input_format
);
FfmpegOpenInput
(
stream
.
io
,
is
.
GetURI
(),
input_format
,
IgnoreError
());
if
(
f
==
nullptr
)
return
false
;
bool
result
=
FfmpegScanStream
(
*
f
,
handler
,
handler_ctx
);
avformat_close_input
(
&
f
);
return
result
;
AtScopeExit
(
&
f
)
{
avformat_close_input
(
&
f
);
};
return
FfmpegScanStream
(
*
f
,
handler
,
handler_ctx
);
}
/**
...
...
src/decoder/plugins/SidplayDecoderPlugin.cxx
View file @
2777a236
...
...
@@ -23,6 +23,7 @@
#include "tag/TagHandler.hxx"
#include "fs/Path.hxx"
#include "fs/AllocatedPath.hxx"
#include "util/Macros.hxx"
#include "util/FormatString.hxx"
#include "util/AllocatedString.hxx"
#include "util/Domain.hxx"
...
...
@@ -33,10 +34,21 @@
#include <string.h>
#ifdef HAVE_SIDPLAYFP
#include <sidplayfp/sidplayfp.h>
#include <sidplayfp/SidInfo.h>
#include <sidplayfp/SidConfig.h>
#include <sidplayfp/SidTune.h>
#include <sidplayfp/SidTuneInfo.h>
#include <sidplayfp/builders/resid.h>
#include <sidplayfp/builders/residfp.h>
#include <sidplayfp/SidDatabase.h>
#else
#include <sidplay/sidplay2.h>
#include <sidplay/builders/resid.h>
#include <sidplay/utils/SidTuneMod.h>
#include <sidplay/utils/SidDatabase.h>
#endif
#define SUBTUNE_PREFIX "tune_"
...
...
@@ -53,7 +65,12 @@ static SidDatabase *
sidplay_load_songlength_db
(
const
Path
path
)
{
SidDatabase
*
db
=
new
SidDatabase
();
if
(
db
->
open
(
path
.
c_str
())
<
0
)
{
#ifdef HAVE_SIDPLAYFP
bool
error
=
!
db
->
open
(
path
.
c_str
());
#else
bool
error
=
db
->
open
(
path
.
c_str
())
<
0
;
#endif
if
(
error
)
{
FormatError
(
sidplay_domain
,
"unable to read songlengths file %s: %s"
,
path
.
c_str
(),
db
->
error
());
...
...
@@ -129,7 +146,25 @@ ParseContainerPath(Path path_fs)
return
{
path_fs
.
GetDirectoryName
(),
track
};
}
/* get the song length in seconds */
#ifdef HAVE_SIDPLAYFP
static
SignedSongTime
get_song_length
(
SidTune
&
tune
)
{
assert
(
tune
.
getStatus
());
if
(
songlength_database
==
nullptr
)
return
SignedSongTime
::
Negative
();
const
auto
length
=
songlength_database
->
length
(
tune
);
if
(
length
<
0
)
return
SignedSongTime
::
Negative
();
return
SignedSongTime
::
FromS
(
length
);
}
#else
static
SignedSongTime
get_song_length
(
SidTuneMod
&
tune
)
{
...
...
@@ -145,6 +180,8 @@ get_song_length(SidTuneMod &tune)
return
SignedSongTime
::
FromS
(
length
);
}
#endif
static
void
sidplay_file_decode
(
Decoder
&
decoder
,
Path
path_fs
)
{
...
...
@@ -153,9 +190,19 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
/* load the tune */
const
auto
container
=
ParseContainerPath
(
path_fs
);
#ifdef HAVE_SIDPLAYFP
SidTune
tune
(
container
.
path
.
c_str
());
#else
SidTuneMod
tune
(
container
.
path
.
c_str
());
if
(
!
tune
)
{
LogWarning
(
sidplay_domain
,
"failed to load file"
);
#endif
if
(
!
tune
.
getStatus
())
{
#ifdef HAVE_SIDPLAYFP
const
char
*
error
=
tune
.
statusString
();
#else
const
char
*
error
=
tune
.
getInfo
().
statusString
;
#endif
FormatWarning
(
sidplay_domain
,
"failed to load file: %s"
,
error
);
return
;
}
...
...
@@ -168,9 +215,17 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
/* initialize the player */
#ifdef HAVE_SIDPLAYFP
sidplayfp
player
;
#else
sidplay2
player
;
int
iret
=
player
.
load
(
&
tune
);
if
(
iret
!=
0
)
{
#endif
#ifdef HAVE_SIDPLAYFP
bool
error
=
!
player
.
load
(
&
tune
);
#else
bool
error
=
player
.
load
(
&
tune
)
<
0
;
#endif
if
(
error
)
{
FormatWarning
(
sidplay_domain
,
"sidplay2.load() failed: %s"
,
player
.
error
());
return
;
...
...
@@ -178,53 +233,104 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
/* initialize the builder */
ReSIDBuilder
builder
(
"ReSID"
);
if
(
!
builder
)
{
LogWarning
(
sidplay_domain
,
"failed to initialize ReSIDBuilder"
);
#ifdef HAVE_SIDPLAYFP
ReSIDfpBuilder
builder
(
"ReSID"
);
if
(
!
builder
.
getStatus
())
{
FormatWarning
(
sidplay_domain
,
"failed to initialize ReSIDfpBuilder: %s"
,
builder
.
error
());
return
;
}
builder
.
create
(
player
.
info
().
maxsids
());
if
(
!
builder
.
getStatus
())
{
FormatWarning
(
sidplay_domain
,
"ReSIDfpBuilder.create() failed: %s"
,
builder
.
error
());
return
;
}
#else
ReSIDBuilder
builder
(
"ReSID"
);
builder
.
create
(
player
.
info
().
maxsids
);
if
(
!
builder
)
{
LogWarning
(
sidplay_domain
,
"ReSIDBuilder.create() failed"
);
FormatWarning
(
sidplay_domain
,
"ReSIDBuilder.create() failed: %s"
,
builder
.
error
());
return
;
}
#endif
builder
.
filter
(
filter_setting
);
#ifdef HAVE_SIDPLAYFP
if
(
!
builder
.
getStatus
())
{
FormatWarning
(
sidplay_domain
,
"ReSIDfpBuilder.filter() failed: %s"
,
builder
.
error
());
return
;
}
#else
if
(
!
builder
)
{
LogWarning
(
sidplay_domain
,
"ReSIDBuilder.filter() failed"
);
FormatWarning
(
sidplay_domain
,
"ReSIDBuilder.filter() failed: %s"
,
builder
.
error
());
return
;
}
#endif
/* configure the player */
sid2_config_t
config
=
player
.
config
();
auto
config
=
player
.
config
();
#ifndef HAVE_SIDPLAYFP
config
.
clockDefault
=
SID2_CLOCK_PAL
;
config
.
clockForced
=
true
;
config
.
clockSpeed
=
SID2_CLOCK_CORRECT
;
#endif
config
.
frequency
=
48000
;
#ifndef HAVE_SIDPLAYFP
config
.
optimisation
=
SID2_DEFAULT_OPTIMISATION
;
config
.
precision
=
16
;
config
.
sidDefault
=
SID2_MOS6581
;
#endif
config
.
sidEmulation
=
&
builder
;
#ifdef HAVE_SIDPLAYFP
config
.
samplingMethod
=
SidConfig
::
INTERPOLATE
;
config
.
fastSampling
=
false
;
#else
config
.
sidModel
=
SID2_MODEL_CORRECT
;
config
.
sidSamples
=
true
;
config
.
sampleFormat
=
IsLittleEndian
()
?
SID2_LITTLE_SIGNED
:
SID2_BIG_SIGNED
;
if
(
tune
.
isStereo
())
{
#endif
#ifdef HAVE_SIDPLAYFP
const
bool
stereo
=
tune
.
getInfo
()
->
sidChips
()
>=
2
;
#else
const
bool
stereo
=
tune
.
isStereo
();
#endif
if
(
stereo
)
{
#ifdef HAVE_SIDPLAYFP
config
.
playback
=
SidConfig
::
STEREO
;
#else
config
.
playback
=
sid2_stereo
;
#endif
channels
=
2
;
}
else
{
#ifdef HAVE_SIDPLAYFP
config
.
playback
=
SidConfig
::
MONO
;
#else
config
.
playback
=
sid2_mono
;
#endif
channels
=
1
;
}
iret
=
player
.
config
(
config
);
if
(
iret
!=
0
)
{
#ifdef HAVE_SIDPLAYFP
error
=
!
player
.
config
(
config
);
#else
error
=
player
.
config
(
config
)
<
0
;
#endif
if
(
error
)
{
FormatWarning
(
sidplay_domain
,
"sidplay2.config() failed: %s"
,
player
.
error
());
return
;
...
...
@@ -239,17 +345,21 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
/* .. and play */
#ifdef HAVE_SIDPLAYFP
constexpr
unsigned
timebase
=
1
;
#else
const
unsigned
timebase
=
player
.
timebase
();
#endif
const
unsigned
end
=
duration
.
IsNegative
()
?
0u
:
duration
.
ToScale
<
uint64_t
>
(
timebase
);
DecoderCommand
cmd
;
do
{
char
buffer
[
4096
];
short
buffer
[
4096
];
size_t
nbytes
;
nbytes
=
player
.
play
(
buffer
,
sizeof
(
buffer
));
nbytes
=
player
.
play
(
buffer
,
ARRAY_SIZE
(
buffer
));
if
(
nbytes
==
0
)
break
;
...
...
@@ -270,7 +380,7 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
/* ignore data until target time is reached */
while
(
data_time
<
target_time
)
{
nbytes
=
player
.
play
(
buffer
,
sizeof
(
buffer
));
nbytes
=
player
.
play
(
buffer
,
ARRAY_SIZE
(
buffer
));
if
(
nbytes
==
0
)
break
;
data_time
=
player
.
time
();
...
...
@@ -285,6 +395,21 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
}
while
(
cmd
!=
DecoderCommand
::
STOP
);
}
gcc_pure
static
const
char
*
GetInfoString
(
const
SidTuneInfo
&
info
,
unsigned
i
)
{
#ifdef HAVE_SIDPLAYFP
return
info
.
numberOfInfoStrings
()
>
i
?
info
.
infoString
(
i
)
:
nullptr
;
#else
return
info
.
numberOfInfoStrings
>
i
?
info
.
infoString
[
i
]
:
nullptr
;
#endif
}
static
bool
sidplay_scan_file
(
Path
path_fs
,
const
TagHandler
&
handler
,
void
*
handler_ctx
)
...
...
@@ -292,35 +417,50 @@ sidplay_scan_file(Path path_fs,
const
auto
container
=
ParseContainerPath
(
path_fs
);
const
unsigned
song_num
=
container
.
track
;
#ifdef HAVE_SIDPLAYFP
SidTune
tune
(
container
.
path
.
c_str
());
#else
SidTuneMod
tune
(
container
.
path
.
c_str
());
if
(
!
tune
)
#endif
if
(
!
tune
.
getStatus
())
return
false
;
tune
.
selectSong
(
song_num
);
#ifdef HAVE_SIDPLAYFP
const
SidTuneInfo
&
info
=
*
tune
.
getInfo
();
const
unsigned
n_tracks
=
info
.
songs
();
#else
const
SidTuneInfo
&
info
=
tune
.
getInfo
();
const
unsigned
n_tracks
=
info
.
songs
;
#endif
/* title */
const
char
*
title
;
if
(
info
.
numberOfInfoStrings
>
0
&&
info
.
infoString
[
0
]
!=
nullptr
)
title
=
info
.
infoString
[
0
];
else
title
=
""
;
const
char
*
title
=
GetInfoString
(
info
,
0
);
if
(
title
==
nullptr
)
title
=
""
;
if
(
info
.
songs
>
1
)
{
if
(
n_tracks
>
1
)
{
char
tag_title
[
1024
];
snprintf
(
tag_title
,
sizeof
(
tag_title
),
"%s (%d/%
d
)"
,
title
,
song_num
,
info
.
song
s
);
"%s (%d/%
u
)"
,
title
,
song_num
,
n_track
s
);
tag_handler_invoke_tag
(
handler
,
handler_ctx
,
TAG_TITLE
,
tag_title
);
}
else
tag_handler_invoke_tag
(
handler
,
handler_ctx
,
TAG_TITLE
,
title
);
/* artist */
if
(
info
.
numberOfInfoStrings
>
1
&&
info
.
infoString
[
1
]
!=
nullptr
)
const
char
*
artist
=
GetInfoString
(
info
,
1
);
if
(
artist
!=
nullptr
)
tag_handler_invoke_tag
(
handler
,
handler_ctx
,
TAG_ARTIST
,
info
.
infoString
[
1
]);
artist
);
/* date */
const
char
*
date
=
GetInfoString
(
info
,
2
);
if
(
date
!=
nullptr
)
tag_handler_invoke_tag
(
handler
,
handler_ctx
,
TAG_DATE
,
date
);
/* track */
char
track
[
16
];
...
...
@@ -340,19 +480,25 @@ static AllocatedString<>
sidplay_container_scan
(
Path
path_fs
,
const
unsigned
int
tnum
)
{
SidTune
tune
(
path_fs
.
c_str
(),
nullptr
,
true
);
if
(
!
tune
)
if
(
!
tune
.
getStatus
()
)
return
nullptr
;
const
SidTuneInfo
&
info
=
tune
.
getInfo
();
#ifdef HAVE_SIDPLAYFP
const
SidTuneInfo
&
info
=
*
tune
.
getInfo
();
const
unsigned
n_tracks
=
info
.
songs
();
#else
const
SidTuneInfo
&
info
=
tune
.
getInfo
();
const
unsigned
n_tracks
=
info
.
songs
;
#endif
/* Don't treat sids containing a single tune
as containers */
if
(
!
all_files_are_containers
&&
info
.
songs
<
2
)
if
(
!
all_files_are_containers
&&
n_tracks
<
2
)
return
nullptr
;
/* Construct container/tune path names, eg.
Delta.sid/tune_001.sid */
if
(
tnum
<=
info
.
song
s
)
{
if
(
tnum
<=
n_track
s
)
{
return
FormatString
(
SUBTUNE_PREFIX
"%03u.sid"
,
tnum
);
}
else
return
nullptr
;
...
...
src/output/plugins/ShoutOutputPlugin.cxx
View file @
2777a236
...
...
@@ -183,7 +183,9 @@ ShoutOutput::Configure(const ConfigBlock &block, Error &error)
}
}
const
char
*
encoding
=
block
.
GetBlockValue
(
"encoding"
,
"ogg"
);
const
char
*
encoding
=
block
.
GetBlockValue
(
"encoder"
,
nullptr
);
if
(
encoding
==
nullptr
)
encoding
=
block
.
GetBlockValue
(
"encoding"
,
"vorbis"
);
const
auto
encoder_plugin
=
shout_encoder_plugin_get
(
encoding
);
if
(
encoder_plugin
==
nullptr
)
{
error
.
Format
(
config_domain
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment