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:
...
@@ -12,7 +12,7 @@ install MPD. If more information is desired, read the user manual:
Dependencies
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/
clang 3.2 or later - http://clang.llvm.org/
Any other C++11 compliant compiler should also work.
Any other C++11 compliant compiler should also work.
...
...
NEWS
View file @
2777a236
...
@@ -59,6 +59,13 @@ ver 0.19.18 (not yet released)
...
@@ -59,6 +59,13 @@ ver 0.19.18 (not yet released)
- ffmpeg: fix crash with older FFmpeg versions (< 3.0)
- ffmpeg: fix crash with older FFmpeg versions (< 3.0)
- ffmpeg: log detailed error message
- ffmpeg: log detailed error message
- ffmpeg: support FFmpeg 3.1
- 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)
ver 0.19.17 (2016/07/09)
* decoder
* decoder
...
...
configure.ac
View file @
2777a236
...
@@ -979,31 +979,36 @@ AM_CONDITIONAL(ENABLE_VORBIS_DECODER, test x$enable_vorbis = xyes || test x$enab
...
@@ -979,31 +979,36 @@ AM_CONDITIONAL(ENABLE_VORBIS_DECODER, test x$enable_vorbis = xyes || test x$enab
dnl --------------------------------- sidplay ---------------------------------
dnl --------------------------------- sidplay ---------------------------------
if test x$enable_sidplay != xno; then
if test x$enable_sidplay != xno; then
# we're not using pkg-config here
dnl Check for libsidplayfp first
# because libsidplay2's .pc file requires libtool
PKG_CHECK_MODULES([SIDPLAY], [libsidplayfp libsidutils],
AC_CHECK_LIB([sidplay2],[main],[found_sidplay=yes],[found_sidplay=no],[])
[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],
MPD_AUTO_PRE(sidplay, [sidplay decoder plugin],
[libsidplay2 not found])
[libsidplay2 not found])
fi
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],
AC_CHECK_LIB([resid-builder], [main],
[found_sidplay=yes], [found_sidplay=no])
[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],
MPD_AUTO_RESULT(sidplay, [sidplay decoder plugin],
[libresid-builder
or libsidutils
not found])
[libresid-builder not found])
fi
fi
if test x$enable_sidplay = xyes; then
if test x$enable_sidplay = xyes; then
AC_SUBST(SIDPLAY_LIBS,"-lsidplay2 -lresid-builder -lsidutils")
SIDPLAY_LIBS="$SIDPLAY_LIBS -lresid-builder"
AC_SUBST(SIDPLAY_CFLAGS,)
AC_DEFINE(ENABLE_SIDPLAY, 1, [Define for libsidplay2 support])
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
fi
AM_CONDITIONAL(ENABLE_SIDPLAY, test x$enable_sidplay = xyes)
AM_CONDITIONAL(ENABLE_SIDPLAY, test x$enable_sidplay = xyes)
...
...
doc/developer.xml
View file @
2777a236
...
@@ -41,7 +41,7 @@
...
@@ -41,7 +41,7 @@
<listitem>
<listitem>
<para>
<para>
the code should be C++11 compliant, and must compile with
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
<application>
clang
</application>
3.2
</para>
</para>
</listitem>
</listitem>
...
...
doc/mpdconf.example
View file @
2777a236
...
@@ -232,7 +232,7 @@ input {
...
@@ -232,7 +232,7 @@ input {
#
#
#audio_output {
#audio_output {
# type "shout"
# type "shout"
# encod
ing "ogg"
# optional
# encod
er "vorbis"
# optional
# name "My Shout Stream"
# name "My Shout Stream"
# host "localhost"
# host "localhost"
# port "8000"
# port "8000"
...
...
src/Compiler.h
View file @
2777a236
...
@@ -57,7 +57,7 @@
...
@@ -57,7 +57,7 @@
# error Sorry, your clang version is too old. You need at least version 3.1.
# error Sorry, your clang version is too old. You need at least version 3.1.
# endif
# endif
#elif defined(__GNUC__)
#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.
# error Sorry, your gcc version is too old. You need at least version 4.6.
# endif
# endif
#else
#else
...
...
src/decoder/plugins/FfmpegDecoderPlugin.cxx
View file @
2777a236
...
@@ -38,6 +38,7 @@
...
@@ -38,6 +38,7 @@
#include "tag/MixRamp.hxx"
#include "tag/MixRamp.hxx"
#include "input/InputStream.hxx"
#include "input/InputStream.hxx"
#include "CheckAudioFormat.hxx"
#include "CheckAudioFormat.hxx"
#include "util/ScopeExit.hxx"
#include "util/ConstBuffer.hxx"
#include "util/ConstBuffer.hxx"
#include "util/Error.hxx"
#include "util/Error.hxx"
#include "LogV.hxx"
#include "LogV.hxx"
...
@@ -59,15 +60,24 @@ extern "C" {
...
@@ -59,15 +60,24 @@ extern "C" {
static
AVFormatContext
*
static
AVFormatContext
*
FfmpegOpenInput
(
AVIOContext
*
pb
,
FfmpegOpenInput
(
AVIOContext
*
pb
,
const
char
*
filename
,
const
char
*
filename
,
AVInputFormat
*
fmt
)
AVInputFormat
*
fmt
,
Error
&
error
)
{
{
AVFormatContext
*
context
=
avformat_alloc_context
();
AVFormatContext
*
context
=
avformat_alloc_context
();
if
(
context
==
nullptr
)
if
(
context
==
nullptr
)
{
error
.
Set
(
ffmpeg_domain
,
"Out of memory"
);
return
nullptr
;
return
nullptr
;
}
context
->
pb
=
pb
;
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
;
return
context
;
}
}
...
@@ -252,6 +262,54 @@ FfmpegSendFrame(Decoder &decoder, InputStream &is,
...
@@ -252,6 +262,54 @@ FfmpegSendFrame(Decoder &decoder, InputStream &is,
codec_context
.
bit_rate
/
1000
);
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
* Decode an #AVPacket and send the resulting PCM data to the decoder
* API.
* API.
...
@@ -284,6 +342,36 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is,
...
@@ -284,6 +342,36 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is,
stream
.
time_base
));
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
;
DecoderCommand
cmd
=
DecoderCommand
::
NONE
;
while
(
packet
.
size
>
0
&&
cmd
==
DecoderCommand
::
NONE
)
{
while
(
packet
.
size
>
0
&&
cmd
==
DecoderCommand
::
NONE
)
{
int
got_frame
=
0
;
int
got_frame
=
0
;
...
@@ -306,6 +394,7 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is,
...
@@ -306,6 +394,7 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is,
frame
,
skip_bytes
,
frame
,
skip_bytes
,
buffer
);
buffer
);
}
}
#endif
return
cmd
;
return
cmd
;
}
}
...
@@ -529,7 +618,10 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
...
@@ -529,7 +618,10 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
AVStream
&
av_stream
=
*
format_context
.
streams
[
audio_stream
];
AVStream
&
av_stream
=
*
format_context
.
streams
[
audio_stream
];
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(57, 5, 0)
AVCodecContext
*
codec_context
=
av_stream
.
codec
;
AVCodecContext
*
codec_context
=
av_stream
.
codec
;
#endif
const
auto
&
codec_params
=
GetCodecParameters
(
av_stream
);
const
auto
&
codec_params
=
GetCodecParameters
(
av_stream
);
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 25, 0)
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 25, 0)
...
@@ -551,6 +643,18 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
...
@@ -551,6 +643,18 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
return
;
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
=
const
SampleFormat
sample_format
=
ffmpeg_sample_format
(
GetSampleFormat
(
codec_params
));
ffmpeg_sample_format
(
GetSampleFormat
(
codec_params
));
if
(
sample_format
==
SampleFormat
::
UNDEFINED
)
{
if
(
sample_format
==
SampleFormat
::
UNDEFINED
)
{
...
@@ -579,6 +683,12 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
...
@@ -579,6 +683,12 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
return
;
return
;
}
}
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(57, 5, 0)
AtScopeExit
(
codec_context
)
{
avcodec_close
(
codec_context
);
};
#endif
const
SignedSongTime
total_time
=
const
SignedSongTime
total_time
=
FromFfmpegTimeChecked
(
av_stream
.
duration
,
av_stream
.
time_base
);
FromFfmpegTimeChecked
(
av_stream
.
duration
,
av_stream
.
time_base
);
...
@@ -597,6 +707,16 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
...
@@ -597,6 +707,16 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
return
;
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
;
FfmpegBuffer
interleaved_buffer
;
uint64_t
min_frame
=
0
;
uint64_t
min_frame
=
0
;
...
@@ -649,16 +769,6 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
...
@@ -649,16 +769,6 @@ FfmpegDecode(Decoder &decoder, InputStream &input,
av_free_packet
(
&
packet
);
av_free_packet
(
&
packet
);
#endif
#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
static
void
...
@@ -677,16 +787,19 @@ ffmpeg_decode(Decoder &decoder, InputStream &input)
...
@@ -677,16 +787,19 @@ ffmpeg_decode(Decoder &decoder, InputStream &input)
return
;
return
;
}
}
Error
error
;
AVFormatContext
*
format_context
=
AVFormatContext
*
format_context
=
FfmpegOpenInput
(
stream
.
io
,
input
.
GetURI
(),
input_format
);
FfmpegOpenInput
(
stream
.
io
,
input
.
GetURI
(),
input_format
,
error
);
if
(
format_context
==
nullptr
)
{
if
(
format_context
==
nullptr
)
{
LogError
(
ffmpeg_domain
,
"Open failed"
);
LogError
(
error
);
return
;
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
static
bool
...
@@ -726,13 +839,16 @@ ffmpeg_scan_stream(InputStream &is,
...
@@ -726,13 +839,16 @@ ffmpeg_scan_stream(InputStream &is,
return
false
;
return
false
;
AVFormatContext
*
f
=
AVFormatContext
*
f
=
FfmpegOpenInput
(
stream
.
io
,
is
.
GetURI
(),
input_format
);
FfmpegOpenInput
(
stream
.
io
,
is
.
GetURI
(),
input_format
,
IgnoreError
());
if
(
f
==
nullptr
)
if
(
f
==
nullptr
)
return
false
;
return
false
;
bool
result
=
FfmpegScanStream
(
*
f
,
handler
,
handler_ctx
);
AtScopeExit
(
&
f
)
{
avformat_close_input
(
&
f
);
avformat_close_input
(
&
f
);
return
result
;
};
return
FfmpegScanStream
(
*
f
,
handler
,
handler_ctx
);
}
}
/**
/**
...
...
src/decoder/plugins/SidplayDecoderPlugin.cxx
View file @
2777a236
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
#include "tag/TagHandler.hxx"
#include "tag/TagHandler.hxx"
#include "fs/Path.hxx"
#include "fs/Path.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/AllocatedPath.hxx"
#include "util/Macros.hxx"
#include "util/FormatString.hxx"
#include "util/FormatString.hxx"
#include "util/AllocatedString.hxx"
#include "util/AllocatedString.hxx"
#include "util/Domain.hxx"
#include "util/Domain.hxx"
...
@@ -33,10 +34,21 @@
...
@@ -33,10 +34,21 @@
#include <string.h>
#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/sidplay2.h>
#include <sidplay/builders/resid.h>
#include <sidplay/builders/resid.h>
#include <sidplay/utils/SidTuneMod.h>
#include <sidplay/utils/SidTuneMod.h>
#include <sidplay/utils/SidDatabase.h>
#include <sidplay/utils/SidDatabase.h>
#endif
#define SUBTUNE_PREFIX "tune_"
#define SUBTUNE_PREFIX "tune_"
...
@@ -53,7 +65,12 @@ static SidDatabase *
...
@@ -53,7 +65,12 @@ static SidDatabase *
sidplay_load_songlength_db
(
const
Path
path
)
sidplay_load_songlength_db
(
const
Path
path
)
{
{
SidDatabase
*
db
=
new
SidDatabase
();
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
,
FormatError
(
sidplay_domain
,
"unable to read songlengths file %s: %s"
,
"unable to read songlengths file %s: %s"
,
path
.
c_str
(),
db
->
error
());
path
.
c_str
(),
db
->
error
());
...
@@ -129,7 +146,25 @@ ParseContainerPath(Path path_fs)
...
@@ -129,7 +146,25 @@ ParseContainerPath(Path path_fs)
return
{
path_fs
.
GetDirectoryName
(),
track
};
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
static
SignedSongTime
get_song_length
(
SidTuneMod
&
tune
)
get_song_length
(
SidTuneMod
&
tune
)
{
{
...
@@ -145,6 +180,8 @@ get_song_length(SidTuneMod &tune)
...
@@ -145,6 +180,8 @@ get_song_length(SidTuneMod &tune)
return
SignedSongTime
::
FromS
(
length
);
return
SignedSongTime
::
FromS
(
length
);
}
}
#endif
static
void
static
void
sidplay_file_decode
(
Decoder
&
decoder
,
Path
path_fs
)
sidplay_file_decode
(
Decoder
&
decoder
,
Path
path_fs
)
{
{
...
@@ -153,9 +190,19 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
...
@@ -153,9 +190,19 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
/* load the tune */
/* load the tune */
const
auto
container
=
ParseContainerPath
(
path_fs
);
const
auto
container
=
ParseContainerPath
(
path_fs
);
#ifdef HAVE_SIDPLAYFP
SidTune
tune
(
container
.
path
.
c_str
());
#else
SidTuneMod
tune
(
container
.
path
.
c_str
());
SidTuneMod
tune
(
container
.
path
.
c_str
());
if
(
!
tune
)
{
#endif
LogWarning
(
sidplay_domain
,
"failed to load file"
);
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
;
return
;
}
}
...
@@ -168,9 +215,17 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
...
@@ -168,9 +215,17 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
/* initialize the player */
/* initialize the player */
#ifdef HAVE_SIDPLAYFP
sidplayfp
player
;
#else
sidplay2
player
;
sidplay2
player
;
int
iret
=
player
.
load
(
&
tune
);
#endif
if
(
iret
!=
0
)
{
#ifdef HAVE_SIDPLAYFP
bool
error
=
!
player
.
load
(
&
tune
);
#else
bool
error
=
player
.
load
(
&
tune
)
<
0
;
#endif
if
(
error
)
{
FormatWarning
(
sidplay_domain
,
FormatWarning
(
sidplay_domain
,
"sidplay2.load() failed: %s"
,
player
.
error
());
"sidplay2.load() failed: %s"
,
player
.
error
());
return
;
return
;
...
@@ -178,53 +233,104 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
...
@@ -178,53 +233,104 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
/* initialize the builder */
/* initialize the builder */
ReSIDBuilder
builder
(
"ReSID"
);
#ifdef HAVE_SIDPLAYFP
if
(
!
builder
)
{
ReSIDfpBuilder
builder
(
"ReSID"
);
LogWarning
(
sidplay_domain
,
if
(
!
builder
.
getStatus
())
{
"failed to initialize ReSIDBuilder"
);
FormatWarning
(
sidplay_domain
,
"failed to initialize ReSIDfpBuilder: %s"
,
builder
.
error
());
return
;
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
);
builder
.
create
(
player
.
info
().
maxsids
);
if
(
!
builder
)
{
if
(
!
builder
)
{
LogWarning
(
sidplay_domain
,
"ReSIDBuilder.create() failed"
);
FormatWarning
(
sidplay_domain
,
"ReSIDBuilder.create() failed: %s"
,
builder
.
error
());
return
;
return
;
}
}
#endif
builder
.
filter
(
filter_setting
);
builder
.
filter
(
filter_setting
);
#ifdef HAVE_SIDPLAYFP
if
(
!
builder
.
getStatus
())
{
FormatWarning
(
sidplay_domain
,
"ReSIDfpBuilder.filter() failed: %s"
,
builder
.
error
());
return
;
}
#else
if
(
!
builder
)
{
if
(
!
builder
)
{
LogWarning
(
sidplay_domain
,
"ReSIDBuilder.filter() failed"
);
FormatWarning
(
sidplay_domain
,
"ReSIDBuilder.filter() failed: %s"
,
builder
.
error
());
return
;
return
;
}
}
#endif
/* configure the player */
/* configure the player */
sid2_config_t
config
=
player
.
config
();
auto
config
=
player
.
config
();
#ifndef HAVE_SIDPLAYFP
config
.
clockDefault
=
SID2_CLOCK_PAL
;
config
.
clockDefault
=
SID2_CLOCK_PAL
;
config
.
clockForced
=
true
;
config
.
clockForced
=
true
;
config
.
clockSpeed
=
SID2_CLOCK_CORRECT
;
config
.
clockSpeed
=
SID2_CLOCK_CORRECT
;
#endif
config
.
frequency
=
48000
;
config
.
frequency
=
48000
;
#ifndef HAVE_SIDPLAYFP
config
.
optimisation
=
SID2_DEFAULT_OPTIMISATION
;
config
.
optimisation
=
SID2_DEFAULT_OPTIMISATION
;
config
.
precision
=
16
;
config
.
precision
=
16
;
config
.
sidDefault
=
SID2_MOS6581
;
config
.
sidDefault
=
SID2_MOS6581
;
#endif
config
.
sidEmulation
=
&
builder
;
config
.
sidEmulation
=
&
builder
;
#ifdef HAVE_SIDPLAYFP
config
.
samplingMethod
=
SidConfig
::
INTERPOLATE
;
config
.
fastSampling
=
false
;
#else
config
.
sidModel
=
SID2_MODEL_CORRECT
;
config
.
sidModel
=
SID2_MODEL_CORRECT
;
config
.
sidSamples
=
true
;
config
.
sidSamples
=
true
;
config
.
sampleFormat
=
IsLittleEndian
()
config
.
sampleFormat
=
IsLittleEndian
()
?
SID2_LITTLE_SIGNED
?
SID2_LITTLE_SIGNED
:
SID2_BIG_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
;
config
.
playback
=
sid2_stereo
;
#endif
channels
=
2
;
channels
=
2
;
}
else
{
}
else
{
#ifdef HAVE_SIDPLAYFP
config
.
playback
=
SidConfig
::
MONO
;
#else
config
.
playback
=
sid2_mono
;
config
.
playback
=
sid2_mono
;
#endif
channels
=
1
;
channels
=
1
;
}
}
iret
=
player
.
config
(
config
);
#ifdef HAVE_SIDPLAYFP
if
(
iret
!=
0
)
{
error
=
!
player
.
config
(
config
);
#else
error
=
player
.
config
(
config
)
<
0
;
#endif
if
(
error
)
{
FormatWarning
(
sidplay_domain
,
FormatWarning
(
sidplay_domain
,
"sidplay2.config() failed: %s"
,
player
.
error
());
"sidplay2.config() failed: %s"
,
player
.
error
());
return
;
return
;
...
@@ -239,17 +345,21 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
...
@@ -239,17 +345,21 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
/* .. and play */
/* .. and play */
#ifdef HAVE_SIDPLAYFP
constexpr
unsigned
timebase
=
1
;
#else
const
unsigned
timebase
=
player
.
timebase
();
const
unsigned
timebase
=
player
.
timebase
();
#endif
const
unsigned
end
=
duration
.
IsNegative
()
const
unsigned
end
=
duration
.
IsNegative
()
?
0u
?
0u
:
duration
.
ToScale
<
uint64_t
>
(
timebase
);
:
duration
.
ToScale
<
uint64_t
>
(
timebase
);
DecoderCommand
cmd
;
DecoderCommand
cmd
;
do
{
do
{
char
buffer
[
4096
];
short
buffer
[
4096
];
size_t
nbytes
;
size_t
nbytes
;
nbytes
=
player
.
play
(
buffer
,
sizeof
(
buffer
));
nbytes
=
player
.
play
(
buffer
,
ARRAY_SIZE
(
buffer
));
if
(
nbytes
==
0
)
if
(
nbytes
==
0
)
break
;
break
;
...
@@ -270,7 +380,7 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
...
@@ -270,7 +380,7 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
/* ignore data until target time is reached */
/* ignore data until target time is reached */
while
(
data_time
<
target_time
)
{
while
(
data_time
<
target_time
)
{
nbytes
=
player
.
play
(
buffer
,
sizeof
(
buffer
));
nbytes
=
player
.
play
(
buffer
,
ARRAY_SIZE
(
buffer
));
if
(
nbytes
==
0
)
if
(
nbytes
==
0
)
break
;
break
;
data_time
=
player
.
time
();
data_time
=
player
.
time
();
...
@@ -285,6 +395,21 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
...
@@ -285,6 +395,21 @@ sidplay_file_decode(Decoder &decoder, Path path_fs)
}
while
(
cmd
!=
DecoderCommand
::
STOP
);
}
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
static
bool
sidplay_scan_file
(
Path
path_fs
,
sidplay_scan_file
(
Path
path_fs
,
const
TagHandler
&
handler
,
void
*
handler_ctx
)
const
TagHandler
&
handler
,
void
*
handler_ctx
)
...
@@ -292,35 +417,50 @@ sidplay_scan_file(Path path_fs,
...
@@ -292,35 +417,50 @@ sidplay_scan_file(Path path_fs,
const
auto
container
=
ParseContainerPath
(
path_fs
);
const
auto
container
=
ParseContainerPath
(
path_fs
);
const
unsigned
song_num
=
container
.
track
;
const
unsigned
song_num
=
container
.
track
;
#ifdef HAVE_SIDPLAYFP
SidTune
tune
(
container
.
path
.
c_str
());
#else
SidTuneMod
tune
(
container
.
path
.
c_str
());
SidTuneMod
tune
(
container
.
path
.
c_str
());
if
(
!
tune
)
#endif
if
(
!
tune
.
getStatus
())
return
false
;
return
false
;
tune
.
selectSong
(
song_num
);
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
SidTuneInfo
&
info
=
tune
.
getInfo
();
const
unsigned
n_tracks
=
info
.
songs
;
#endif
/* title */
/* title */
const
char
*
title
;
const
char
*
title
=
GetInfoString
(
info
,
0
);
if
(
info
.
numberOfInfoStrings
>
0
&&
info
.
infoString
[
0
]
!=
nullptr
)
if
(
title
==
nullptr
)
title
=
info
.
infoString
[
0
];
title
=
""
;
else
title
=
""
;
if
(
info
.
songs
>
1
)
{
if
(
n_tracks
>
1
)
{
char
tag_title
[
1024
];
char
tag_title
[
1024
];
snprintf
(
tag_title
,
sizeof
(
tag_title
),
snprintf
(
tag_title
,
sizeof
(
tag_title
),
"%s (%d/%
d
)"
,
"%s (%d/%
u
)"
,
title
,
song_num
,
info
.
song
s
);
title
,
song_num
,
n_track
s
);
tag_handler_invoke_tag
(
handler
,
handler_ctx
,
tag_handler_invoke_tag
(
handler
,
handler_ctx
,
TAG_TITLE
,
tag_title
);
TAG_TITLE
,
tag_title
);
}
else
}
else
tag_handler_invoke_tag
(
handler
,
handler_ctx
,
TAG_TITLE
,
title
);
tag_handler_invoke_tag
(
handler
,
handler_ctx
,
TAG_TITLE
,
title
);
/* artist */
/* 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
,
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 */
/* track */
char
track
[
16
];
char
track
[
16
];
...
@@ -340,19 +480,25 @@ static AllocatedString<>
...
@@ -340,19 +480,25 @@ static AllocatedString<>
sidplay_container_scan
(
Path
path_fs
,
const
unsigned
int
tnum
)
sidplay_container_scan
(
Path
path_fs
,
const
unsigned
int
tnum
)
{
{
SidTune
tune
(
path_fs
.
c_str
(),
nullptr
,
true
);
SidTune
tune
(
path_fs
.
c_str
(),
nullptr
,
true
);
if
(
!
tune
)
if
(
!
tune
.
getStatus
()
)
return
nullptr
;
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
/* Don't treat sids containing a single tune
as containers */
as containers */
if
(
!
all_files_are_containers
&&
info
.
songs
<
2
)
if
(
!
all_files_are_containers
&&
n_tracks
<
2
)
return
nullptr
;
return
nullptr
;
/* Construct container/tune path names, eg.
/* Construct container/tune path names, eg.
Delta.sid/tune_001.sid */
Delta.sid/tune_001.sid */
if
(
tnum
<=
info
.
song
s
)
{
if
(
tnum
<=
n_track
s
)
{
return
FormatString
(
SUBTUNE_PREFIX
"%03u.sid"
,
tnum
);
return
FormatString
(
SUBTUNE_PREFIX
"%03u.sid"
,
tnum
);
}
else
}
else
return
nullptr
;
return
nullptr
;
...
...
src/output/plugins/ShoutOutputPlugin.cxx
View file @
2777a236
...
@@ -183,7 +183,9 @@ ShoutOutput::Configure(const ConfigBlock &block, Error &error)
...
@@ -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
);
const
auto
encoder_plugin
=
shout_encoder_plugin_get
(
encoding
);
if
(
encoder_plugin
==
nullptr
)
{
if
(
encoder_plugin
==
nullptr
)
{
error
.
Format
(
config_domain
,
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