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
db47ab16
Commit
db47ab16
authored
Jun 24, 2007
by
J. Alexander Treuman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding WavPack support. Patch courtesy Kodest.
git-svn-id:
https://svn.musicpd.org/mpd/trunk@6651
09075e82-0dd4-0310-85a5-a0d7c8717e4f
parent
df32eed2
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
446 additions
and
2 deletions
+446
-2
AUTHORS
AUTHORS
+3
-0
ChangeLog
ChangeLog
+1
-0
configure.ac
configure.ac
+16
-1
Makefile.am
src/Makefile.am
+2
-1
inputPlugin.c
src/inputPlugin.c
+1
-0
inputPlugin.h
src/inputPlugin.h
+1
-0
wavpack_plugin.c
src/inputPlugins/wavpack_plugin.c
+422
-0
No files found.
AUTHORS
View file @
db47ab16
...
...
@@ -24,6 +24,9 @@ Qball Cow <qballcow@gmail.com>
Patrik Weiskircher <pat@icore.at>
Stored playlist commands
Kodest <kodest at gmail dot com>
WavPack support
Former Developers
-----------------
tw-nym
...
...
ChangeLog
View file @
db47ab16
...
...
@@ -9,6 +9,7 @@ ver 0.14.0 (????/??/??)
* Make the shout output block while trying to connect instead of failing
* New timeout parameter for shout outputs to define a connection timeout
* New FIFO audio output
* Support for WavPack files
ver 0.13.0 (2007/5/28)
* New JACK audio output
...
...
configure.ac
View file @
db47ab16
...
...
@@ -79,6 +79,7 @@ AC_ARG_ENABLE(aac,[ --disable-aac disable AAC support (default: enabl
AC_ARG_ENABLE(audiofile,[ --disable-audiofile disable audiofile support, disables wave support (default: enable)],[enable_audiofile=$enableval],[enable_audiofile=yes])
AC_ARG_ENABLE(mod,[ --enable-mod enable MOD support (default: disable],[enable_mod=$enableval],[enable_mod=yes])
AC_ARG_ENABLE(mpc,[ --disable-mpc disable musepack (MPC) support (default: enable)],[enable_mpc=$enableval],[enable_mpc=yes])
AC_ARG_ENABLE(wavpack,[ --disable-wavpack disable wavpack support (default: enable)],[enable_wavpack=$enableval],[enable_wavpack=yes])
AC_ARG_ENABLE(id3,[ --disable-id3 disable id3 support (default: enable)],[enable_id3=$enableval],[enable_id3=yes])
AC_ARG_ENABLE(lsr,[ --disable-lsr disable libsamplerate support (default: enable)],[enable_lsr=$enableval],[enable_lsr=yes])
...
...
@@ -182,7 +183,8 @@ if test x$enable_oss = xyes; then
fi
if test x$enable_pulse = xyes || test x$enable_jack = xyes ||
test x$enable_lsr = xyes || test x$with_zeroconf != xno; then
test x$enable_lsr = xyes || test x$with_zeroconf != xno ||
test x$enable_wavpack = xyes; then
PKG_PROG_PKG_CONFIG
fi
...
...
@@ -368,6 +370,12 @@ if test x$enable_mpc = xyes; then
CPPFLAGS=$oldcppflags
fi
if test x$enable_wavpack = xyes; then
PKG_CHECK_MODULES([WAVPACK], [wavpack],
[enable_wavpack=yes;AC_DEFINE([HAVE_WAVPACK], 1, [Define to enable WavPack support])] MPD_LIBS="$MPD_LIBS $WAVPACK_LIBS" MPD_CFLAGS="$MPD_CFLAGS $WAVPACK_CFLAGS",
[enable_wavpack=no;AC_MSG_WARN([WavPack not found -- disabling])])
fi
MP4FF_SUBDIR=""
if test x$enable_aac = xyes; then
...
...
@@ -764,6 +772,12 @@ else
echo " Musepack (MPC) support ........disabled"
fi
if test x$enable_wavpack = xyes; then
echo " WavPack support ...............enabled"
else
echo " WavPack support ...............disabled"
fi
if test x$enable_mod = xyes; then
echo " MOD support ...................enabled"
else
...
...
@@ -778,6 +792,7 @@ if
test x$enable_audiofile = xno &&
test x$enable_aac = xno &&
test x$enable_mpc = xno &&
test x$enable_wavpack = xno &&
test x$enable_mod = xno; then
AC_MSG_ERROR([No input plugins supported!])
fi
...
...
src/Makefile.am
View file @
db47ab16
...
...
@@ -24,7 +24,8 @@ mpd_inputPlugins = \
inputPlugins/mod_plugin.c
\
inputPlugins/mp3_plugin.c
\
inputPlugins/mp4_plugin.c
\
inputPlugins/mpc_plugin.c
inputPlugins/mpc_plugin.c
\
inputPlugins/wavpack_plugin.c
mpd_headers
=
\
...
...
src/inputPlugin.c
View file @
db47ab16
...
...
@@ -150,6 +150,7 @@ void initInputPlugins(void)
loadInputPlugin
(
&
mp4Plugin
);
loadInputPlugin
(
&
aacPlugin
);
loadInputPlugin
(
&
mpcPlugin
);
loadInputPlugin
(
&
wavpackPlugin
);
loadInputPlugin
(
&
modPlugin
);
}
...
...
src/inputPlugin.h
View file @
db47ab16
...
...
@@ -104,6 +104,7 @@ extern InputPlugin audiofilePlugin;
extern
InputPlugin
mp4Plugin
;
extern
InputPlugin
aacPlugin
;
extern
InputPlugin
mpcPlugin
;
extern
InputPlugin
wavpackPlugin
;
extern
InputPlugin
modPlugin
;
#endif
src/inputPlugins/wavpack_plugin.c
0 → 100644
View file @
db47ab16
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
*
* WavPack support added by Kodest <kodest at gmail dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../inputPlugin.h"
#ifdef HAVE_WAVPACK
#include "../utils.h"
#include "../audio.h"
#include "../log.h"
#include "../pcm_utils.h"
#include "../playerData.h"
#include "../outputBuffer.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <wavpack/wavpack.h>
#include <math.h>
#define ERRORLEN 80
static
struct
{
const
char
*
name
;
int
type
;
}
tagtypes
[]
=
{
{
"artist"
,
TAG_ITEM_ARTIST
},
{
"album"
,
TAG_ITEM_ALBUM
},
{
"title"
,
TAG_ITEM_TITLE
},
{
"track"
,
TAG_ITEM_TRACK
},
{
"name"
,
TAG_ITEM_NAME
},
{
"genre"
,
TAG_ITEM_GENRE
},
{
"date"
,
TAG_ITEM_DATE
},
{
"composer"
,
TAG_ITEM_COMPOSER
},
{
"performer"
,
TAG_ITEM_PERFORMER
},
{
"comment"
,
TAG_ITEM_COMMENT
},
{
"disc"
,
TAG_ITEM_DISC
},
{
NULL
,
0
}
};
/* workaround for at least the last push_back_byte */
static
int
last_byte
=
EOF
;
/*
* This function has been borrowed from the tiny player found on
* wavpack.com. Modifications were required because mpd only handles
* max 16 bit samples.
*/
static
void
format_samples_int
(
int
Bps
,
void
*
buffer
,
uint32_t
samcnt
)
{
int32_t
temp
;
uchar
*
dst
=
(
uchar
*
)
buffer
;
int32_t
*
src
=
(
int32_t
*
)
buffer
;
switch
(
Bps
)
{
case
1
:
while
(
samcnt
--
)
*
dst
++
=
*
src
++
;
break
;
case
2
:
while
(
samcnt
--
)
{
*
dst
++
=
(
uchar
)(
temp
=
*
src
++
);
*
dst
++
=
(
uchar
)(
temp
>>
8
);
}
break
;
case
3
:
/* downscale to 16 bits */
while
(
samcnt
--
)
{
temp
=
*
src
++
;
*
dst
++
=
(
uchar
)(
temp
>>
8
);
*
dst
++
=
(
uchar
)(
temp
>>
16
);
}
break
;
case
4
:
/* downscale to 16 bits */
while
(
samcnt
--
)
{
temp
=
*
src
++
;
*
dst
++
=
(
uchar
)(
temp
>>
16
);
*
dst
++
=
(
uchar
)(
temp
>>
24
);
}
break
;
}
}
/*
* This function converts floating point sample data to 16 bit integer.
*/
static
void
format_samples_float
(
int
Bps
,
void
*
buffer
,
uint32_t
samcnt
)
{
int16_t
*
dst
=
(
int16_t
*
)
buffer
;
float
*
src
=
(
float
*
)
buffer
;
while
(
samcnt
--
)
{
*
dst
++
=
(
int16_t
)(
*
src
++
);
}
}
/*
* This does the main decoding thing.
* Requires an already opened WavpackContext.
*/
static
void
wavpack_decode
(
OutputBuffer
*
cb
,
DecoderControl
*
dc
,
WavpackContext
*
wpc
,
int
canseek
)
{
void
(
*
format_samples
)(
int
Bps
,
void
*
buffer
,
uint32_t
samcnt
);
char
chunk
[
CHUNK_SIZE
];
float
time
;
int
samplesreq
,
samplesgot
;
int
allsamples
;
int
position
,
outsamplesize
;
int
Bps
;
dc
->
audioFormat
.
sampleRate
=
WavpackGetSampleRate
(
wpc
);
dc
->
audioFormat
.
channels
=
WavpackGetReducedChannels
(
wpc
);
dc
->
audioFormat
.
bits
=
WavpackGetBitsPerSample
(
wpc
);
if
(
dc
->
audioFormat
.
bits
>
16
)
dc
->
audioFormat
.
bits
=
16
;
if
((
WavpackGetMode
(
wpc
)
&
MODE_FLOAT
)
==
MODE_FLOAT
)
format_samples
=
format_samples_float
;
else
format_samples
=
format_samples_int
;
allsamples
=
WavpackGetNumSamples
(
wpc
);
Bps
=
WavpackGetBytesPerSample
(
wpc
);
outsamplesize
=
Bps
;
if
(
outsamplesize
>
2
)
outsamplesize
=
2
;
outsamplesize
*=
dc
->
audioFormat
.
channels
;
samplesreq
=
sizeof
(
chunk
)
/
(
4
*
dc
->
audioFormat
.
channels
);
getOutputAudioFormat
(
&
(
dc
->
audioFormat
),
&
(
cb
->
audioFormat
));
dc
->
totalTime
=
(
float
)
allsamples
/
dc
->
audioFormat
.
sampleRate
;
dc
->
state
=
DECODE_STATE_DECODE
;
position
=
0
;
do
{
if
(
dc
->
seek
)
{
if
(
canseek
)
{
int
where
;
clearOutputBuffer
(
cb
);
where
=
dc
->
seekWhere
*
dc
->
audioFormat
.
sampleRate
;
if
(
WavpackSeekSample
(
wpc
,
where
))
position
=
where
;
else
dc
->
seekError
=
1
;
}
else
{
dc
->
seekError
=
1
;
}
dc
->
seek
=
0
;
}
if
(
dc
->
stop
)
break
;
samplesgot
=
WavpackUnpackSamples
(
wpc
,
(
int32_t
*
)
chunk
,
samplesreq
);
if
(
samplesgot
>
0
)
{
int
bitrate
=
(
int
)(
WavpackGetInstantBitrate
(
wpc
)
/
1000
+
0
.
5
);
position
+=
samplesgot
;
time
=
(
float
)
position
/
dc
->
audioFormat
.
sampleRate
;
format_samples
(
Bps
,
chunk
,
samplesgot
*
dc
->
audioFormat
.
channels
);
sendDataToOutputBuffer
(
cb
,
NULL
,
dc
,
0
,
chunk
,
samplesgot
*
outsamplesize
,
time
,
bitrate
,
NULL
);
}
}
while
(
samplesgot
==
samplesreq
);
flushOutputBuffer
(
cb
);
dc
->
state
=
DECODE_STATE_STOP
;
dc
->
stop
=
0
;
}
/*
* Reads metainfo from the specified file.
*/
static
MpdTag
*
wavpack_tagdup
(
char
*
fname
)
{
WavpackContext
*
wpc
;
MpdTag
*
tag
;
char
error
[
ERRORLEN
];
char
*
s
;
int
ssize
;
int
i
,
j
;
wpc
=
WavpackOpenFileInput
(
fname
,
error
,
OPEN_TAGS
,
0
);
if
(
wpc
==
NULL
)
{
ERROR
(
"failed to open WavPack file
\"
%s
\"
: %s
\n
"
,
fname
,
error
);
return
NULL
;
}
tag
=
newMpdTag
();
if
(
tag
==
NULL
)
{
ERROR
(
"failed to newMpdTag()
\n
"
);
return
NULL
;
}
tag
->
time
=
(
float
)
WavpackGetNumSamples
(
wpc
)
/
WavpackGetSampleRate
(
wpc
);
ssize
=
0
;
s
=
NULL
;
for
(
i
=
0
;
tagtypes
[
i
].
name
!=
NULL
;
++
i
)
{
j
=
WavpackGetTagItem
(
wpc
,
tagtypes
[
i
].
name
,
NULL
,
0
);
if
(
j
>
0
)
{
++
j
;
if
(
s
==
NULL
)
{
s
=
xmalloc
(
j
);
if
(
s
==
NULL
)
break
;
ssize
=
j
;
}
else
if
(
j
>
ssize
)
{
char
*
t
=
(
char
*
)
xrealloc
(
s
,
j
);
if
(
t
==
NULL
)
break
;
ssize
=
j
;
s
=
t
;
}
WavpackGetTagItem
(
wpc
,
tagtypes
[
i
].
name
,
s
,
j
);
addItemToMpdTag
(
tag
,
tagtypes
[
i
].
type
,
s
);
}
}
if
(
s
!=
NULL
)
free
(
s
);
WavpackCloseFile
(
wpc
);
return
tag
;
}
/*
* mpd InputStream <=> WavpackStreamReader wrapper callbacks
*/
static
int32_t
read_bytes
(
void
*
id
,
void
*
data
,
int32_t
bcount
)
{
uint8_t
*
buf
=
(
uint8_t
*
)
data
;
int32_t
i
=
0
;
if
(
last_byte
!=
EOF
)
{
*
buf
++
=
last_byte
;
last_byte
=
EOF
;
--
bcount
;
++
i
;
}
return
i
+
readFromInputStream
((
InputStream
*
)
id
,
buf
,
1
,
bcount
);
}
static
uint32_t
get_pos
(
void
*
id
)
{
return
((
InputStream
*
)
id
)
->
offset
;
}
static
int
set_pos_abs
(
void
*
id
,
uint32_t
pos
)
{
return
seekInputStream
((
InputStream
*
)
id
,
pos
,
SEEK_SET
);
}
static
int
set_pos_rel
(
void
*
id
,
int32_t
delta
,
int
mode
)
{
return
seekInputStream
((
InputStream
*
)
id
,
delta
,
mode
);
}
static
int
push_back_byte
(
void
*
id
,
int
c
)
{
last_byte
=
c
;
return
1
;
}
static
uint32_t
get_length
(
void
*
id
)
{
return
((
InputStream
*
)
id
)
->
size
;
}
static
int
can_seek
(
void
*
id
)
{
return
(
seekInputStream
((
InputStream
*
)
id
,
0
,
SEEK_SET
)
!=
-
1
);
}
static
WavpackStreamReader
mpd_is_reader
=
{
.
read_bytes
=
read_bytes
,
.
get_pos
=
get_pos
,
.
set_pos_abs
=
set_pos_abs
,
.
set_pos_rel
=
set_pos_rel
,
.
push_back_byte
=
push_back_byte
,
.
get_length
=
get_length
,
.
can_seek
=
can_seek
,
.
write_bytes
=
NULL
/* no need to write edited tags */
};
/*
* Tries to decode the specified stream, and gives true if managed to do it.
*/
static
unsigned
int
wavpack_trydecode
(
InputStream
*
is
)
{
char
error
[
ERRORLEN
];
WavpackContext
*
wpc
;
wpc
=
WavpackOpenFileInputEx
(
&
mpd_is_reader
,
(
void
*
)
is
,
NULL
,
error
,
OPEN_STREAMING
,
0
);
if
(
wpc
==
NULL
)
return
0
;
WavpackCloseFile
(
wpc
);
/* Seek it back in order to play from the first byte. */
seekInputStream
(
is
,
0
,
SEEK_SET
);
return
1
;
}
/*
* Decodes a stream.
* We cannot handle wvc files this way, use the wavpack_filedecode for that.
*/
static
int
wavpack_streamdecode
(
OutputBuffer
*
cb
,
DecoderControl
*
dc
,
InputStream
*
is
)
{
char
error
[
ERRORLEN
];
WavpackContext
*
wpc
;
/*
* wavpack_streamdecode is unable to use wvc :-(
* If we know the original stream url, we would find out the wvc url...
* This would require InputStream to store that.
*/
wpc
=
WavpackOpenFileInputEx
(
&
mpd_is_reader
,
(
void
*
)
is
,
NULL
,
error
,
OPEN_2CH_MAX
|
OPEN_NORMALIZE
,
15
);
if
(
wpc
==
NULL
)
{
ERROR
(
"failed to open WavPack stream: %s
\n
"
,
error
);
return
-
1
;
}
wavpack_decode
(
cb
,
dc
,
wpc
,
can_seek
(
is
));
WavpackCloseFile
(
wpc
);
closeInputStream
(
is
);
/* calling side doesn't do this in mpd 0.13.0 */
return
0
;
}
/*
* Decodes a file. This has the goods on wavpack_streamdecode that this
* can handle wvc files.
*/
static
int
wavpack_filedecode
(
OutputBuffer
*
cb
,
DecoderControl
*
dc
,
char
*
fname
)
{
char
error
[
ERRORLEN
];
WavpackContext
*
wpc
;
wpc
=
WavpackOpenFileInput
(
fname
,
error
,
OPEN_WVC
|
OPEN_2CH_MAX
|
OPEN_NORMALIZE
,
15
);
if
(
wpc
==
NULL
)
{
ERROR
(
"failed to open WavPack file
\"
%s
\"
: %s
\n
"
,
fname
,
error
);
return
-
1
;
}
wavpack_decode
(
cb
,
dc
,
wpc
,
1
);
WavpackCloseFile
(
wpc
);
return
0
;
}
static
char
*
wavpackSuffixes
[]
=
{
"wv"
,
NULL
};
static
char
*
wavpackMimeTypes
[]
=
{
"audio/x-wavpack"
,
NULL
};
InputPlugin
wavpackPlugin
=
{
"wavpack"
,
NULL
,
NULL
,
wavpack_trydecode
,
wavpack_streamdecode
,
wavpack_filedecode
,
/* provides more functionality! (wvc) */
wavpack_tagdup
,
INPUT_PLUGIN_STREAM_FILE
|
INPUT_PLUGIN_STREAM_URL
,
wavpackSuffixes
,
wavpackMimeTypes
};
#else
/* !HAVE_WAVPACK */
InputPlugin
wavpackPlugin
;
#endif
/* !HAVE_WAVPACK */
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