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
e4bbc120
Commit
e4bbc120
authored
Oct 28, 2008
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mp3: no CamelCase
Renamed all functions and variables. Also removed the mp3DecodeData typedef.
parent
1f7c53e6
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
254 additions
and
255 deletions
+254
-255
mp3_plugin.c
src/decoder/mp3_plugin.c
+254
-255
No files found.
src/decoder/mp3_plugin.c
View file @
e4bbc120
...
@@ -50,7 +50,7 @@ enum muteframe {
...
@@ -50,7 +50,7 @@ enum muteframe {
#define DEFAULT_GAPLESS_MP3_PLAYBACK 1
#define DEFAULT_GAPLESS_MP3_PLAYBACK 1
static
int
gapless
PlaybackEnabled
;
static
int
gapless
_playback
;
static
inline
int32_t
static
inline
int32_t
mad_fixed_to_24_sample
(
mad_fixed_t
sample
)
mad_fixed_to_24_sample
(
mad_fixed_t
sample
)
...
@@ -89,61 +89,61 @@ mad_fixed_to_24_buffer(int32_t *dest, const struct mad_synth *synth,
...
@@ -89,61 +89,61 @@ mad_fixed_to_24_buffer(int32_t *dest, const struct mad_synth *synth,
static
int
mp3_plugin_init
(
void
)
static
int
mp3_plugin_init
(
void
)
{
{
gaplessPlaybackEnabled
=
getBoolConfigParam
(
CONF_GAPLESS_MP3_PLAYBACK
,
gapless_playback
=
getBoolConfigParam
(
CONF_GAPLESS_MP3_PLAYBACK
,
1
);
1
);
if
(
gapless_playback
==
CONF_BOOL_UNSET
)
if
(
gaplessPlaybackEnabled
==
CONF_BOOL_UNSET
)
gapless_playback
=
DEFAULT_GAPLESS_MP3_PLAYBACK
;
gaplessPlaybackEnabled
=
DEFAULT_GAPLESS_MP3_PLAYBACK
;
return
1
;
return
1
;
}
}
#define MP3_DATA_OUTPUT_BUFFER_SIZE 2048
#define MP3_DATA_OUTPUT_BUFFER_SIZE 2048
typedef
struct
_mp3DecodeD
ata
{
struct
mp3_d
ata
{
struct
mad_stream
stream
;
struct
mad_stream
stream
;
struct
mad_frame
frame
;
struct
mad_frame
frame
;
struct
mad_synth
synth
;
struct
mad_synth
synth
;
mad_timer_t
timer
;
mad_timer_t
timer
;
unsigned
char
readB
uffer
[
READ_BUFFER_SIZE
];
unsigned
char
input_b
uffer
[
READ_BUFFER_SIZE
];
int32_t
output
B
uffer
[
MP3_DATA_OUTPUT_BUFFER_SIZE
];
int32_t
output
_b
uffer
[
MP3_DATA_OUTPUT_BUFFER_SIZE
];
float
total
T
ime
;
float
total
_t
ime
;
float
elapsed
T
ime
;
float
elapsed
_t
ime
;
enum
muteframe
mute
F
rame
;
enum
muteframe
mute
_f
rame
;
long
*
frame
Offset
;
long
*
frame
_offsets
;
mad_timer_t
*
times
;
mad_timer_t
*
times
;
unsigned
long
highest
F
rame
;
unsigned
long
highest
_f
rame
;
unsigned
long
max
F
rames
;
unsigned
long
max
_f
rames
;
unsigned
long
current
F
rame
;
unsigned
long
current
_f
rame
;
unsigned
int
drop
FramesAtStart
;
unsigned
int
drop
_start_frames
;
unsigned
int
drop
FramesAtEnd
;
unsigned
int
drop
_end_frames
;
unsigned
int
drop
SamplesAtStart
;
unsigned
int
drop
_start_samples
;
unsigned
int
drop
SamplesAtEnd
;
unsigned
int
drop
_end_samples
;
int
found
X
ing
;
int
found
_x
ing
;
int
found
FirstF
rame
;
int
found
_first_f
rame
;
int
decoded
FirstF
rame
;
int
decoded
_first_f
rame
;
unsigned
long
bit
R
ate
;
unsigned
long
bit
_r
ate
;
struct
decoder
*
decoder
;
struct
decoder
*
decoder
;
struct
input_stream
*
in
S
tream
;
struct
input_stream
*
in
put_s
tream
;
enum
mad_layer
layer
;
enum
mad_layer
layer
;
}
mp3DecodeData
;
};
static
void
initMp3DecodeData
(
mp3DecodeData
*
data
,
struct
decoder
*
decoder
,
static
void
struct
input_stream
*
inStream
)
mp3_data_init
(
struct
mp3_data
*
data
,
struct
decoder
*
decoder
,
struct
input_stream
*
input_stream
)
{
{
data
->
mute
F
rame
=
MUTEFRAME_NONE
;
data
->
mute
_f
rame
=
MUTEFRAME_NONE
;
data
->
highest
F
rame
=
0
;
data
->
highest
_f
rame
=
0
;
data
->
max
F
rames
=
0
;
data
->
max
_f
rames
=
0
;
data
->
frame
Offset
=
NULL
;
data
->
frame
_offsets
=
NULL
;
data
->
times
=
NULL
;
data
->
times
=
NULL
;
data
->
current
F
rame
=
0
;
data
->
current
_f
rame
=
0
;
data
->
drop
FramesAtStart
=
0
;
data
->
drop
_start_frames
=
0
;
data
->
drop
FramesAtEnd
=
0
;
data
->
drop
_end_frames
=
0
;
data
->
drop
SamplesAtStart
=
0
;
data
->
drop
_start_samples
=
0
;
data
->
drop
SamplesAtEnd
=
0
;
data
->
drop
_end_samples
=
0
;
data
->
found
X
ing
=
0
;
data
->
found
_x
ing
=
0
;
data
->
found
FirstF
rame
=
0
;
data
->
found
_first_f
rame
=
0
;
data
->
decoded
FirstF
rame
=
0
;
data
->
decoded
_first_f
rame
=
0
;
data
->
decoder
=
decoder
;
data
->
decoder
=
decoder
;
data
->
in
Stream
=
inS
tream
;
data
->
in
put_stream
=
input_s
tream
;
data
->
layer
=
0
;
data
->
layer
=
0
;
mad_stream_init
(
&
data
->
stream
);
mad_stream_init
(
&
data
->
stream
);
...
@@ -153,61 +153,61 @@ static void initMp3DecodeData(mp3DecodeData * data, struct decoder *decoder,
...
@@ -153,61 +153,61 @@ static void initMp3DecodeData(mp3DecodeData * data, struct decoder *decoder,
mad_timer_reset
(
&
data
->
timer
);
mad_timer_reset
(
&
data
->
timer
);
}
}
static
int
seekMp3InputBuffer
(
mp3DecodeData
*
data
,
long
offset
)
static
int
mp3_seek
(
struct
mp3_data
*
data
,
long
offset
)
{
{
if
(
!
input_stream_seek
(
data
->
in
S
tream
,
offset
,
SEEK_SET
))
if
(
!
input_stream_seek
(
data
->
in
put_s
tream
,
offset
,
SEEK_SET
))
return
-
1
;
return
-
1
;
mad_stream_buffer
(
&
data
->
stream
,
data
->
readB
uffer
,
0
);
mad_stream_buffer
(
&
data
->
stream
,
data
->
input_b
uffer
,
0
);
(
data
->
stream
).
error
=
0
;
(
data
->
stream
).
error
=
0
;
return
0
;
return
0
;
}
}
static
int
fillMp3InputBuffer
(
mp3DecodeData
*
data
)
static
int
mp3_fill_buffer
(
struct
mp3_data
*
data
)
{
{
size_t
readSize
;
size_t
remaining
,
length
;
size_t
remaining
;
unsigned
char
*
dest
;
size_t
readed
;
unsigned
char
*
readStart
;
if
(
data
->
stream
.
next_frame
!=
NULL
)
{
remaining
=
data
->
stream
.
bufend
-
data
->
stream
.
next_frame
;
if
((
data
->
stream
).
next_frame
!=
NULL
)
{
memmove
(
data
->
input_buffer
,
data
->
stream
.
next_frame
,
remaining
=
(
data
->
stream
).
bufend
-
(
data
->
stream
).
next_frame
;
remaining
);
memmove
(
data
->
readBuffer
,
(
data
->
stream
).
next_frame
,
remaining
);
dest
=
(
data
->
input_buffer
)
+
remaining
;
readStart
=
(
data
->
readBuffer
)
+
remaining
;
length
=
READ_BUFFER_SIZE
-
remaining
;
readSize
=
READ_BUFFER_SIZE
-
remaining
;
}
else
{
}
else
{
readSize
=
READ_BUFFER_SIZE
;
remaining
=
0
;
readStart
=
data
->
readBuffer
,
remaining
=
0
;
length
=
READ_BUFFER_SIZE
;
dest
=
data
->
input_buffer
;
}
}
/* we've exhausted the read buffer, so give up!, these potential
/* we've exhausted the read buffer, so give up!, these potential
* mp3 frames are way too big, and thus unlikely to be mp3 frames */
* mp3 frames are way too big, and thus unlikely to be mp3 frames */
if
(
readSize
==
0
)
if
(
length
==
0
)
return
-
1
;
return
-
1
;
readed
=
decoder_read
(
data
->
decoder
,
data
->
inStream
,
length
=
decoder_read
(
data
->
decoder
,
data
->
input_stream
,
dest
,
length
);
readStart
,
readSize
);
if
(
length
==
0
)
if
(
readed
==
0
)
return
-
1
;
return
-
1
;
mad_stream_buffer
(
&
data
->
stream
,
data
->
readBuffer
,
readed
+
remaining
);
mad_stream_buffer
(
&
data
->
stream
,
data
->
input_buffer
,
length
+
remaining
);
(
data
->
stream
).
error
=
0
;
(
data
->
stream
).
error
=
0
;
return
0
;
return
0
;
}
}
#ifdef HAVE_ID3TAG
#ifdef HAVE_ID3TAG
static
ReplayGainInfo
*
parse
Id3ReplayGainI
nfo
(
struct
id3_tag
*
tag
)
static
ReplayGainInfo
*
parse
_id3_replay_gain_i
nfo
(
struct
id3_tag
*
tag
)
{
{
int
i
;
int
i
;
char
*
key
;
char
*
key
;
char
*
value
;
char
*
value
;
struct
id3_frame
*
frame
;
struct
id3_frame
*
frame
;
int
found
=
0
;
int
found
=
0
;
ReplayGainInfo
*
replay
GainI
nfo
;
ReplayGainInfo
*
replay
_gain_i
nfo
;
replay
GainI
nfo
=
newReplayGainInfo
();
replay
_gain_i
nfo
=
newReplayGainInfo
();
for
(
i
=
0
;
(
frame
=
id3_tag_findframe
(
tag
,
"TXXX"
,
i
));
i
++
)
{
for
(
i
=
0
;
(
frame
=
id3_tag_findframe
(
tag
,
"TXXX"
,
i
));
i
++
)
{
if
(
frame
->
nfields
<
3
)
if
(
frame
->
nfields
<
3
)
...
@@ -221,16 +221,16 @@ static ReplayGainInfo *parseId3ReplayGainInfo(struct id3_tag *tag)
...
@@ -221,16 +221,16 @@ static ReplayGainInfo *parseId3ReplayGainInfo(struct id3_tag *tag)
(
&
frame
->
fields
[
2
]));
(
&
frame
->
fields
[
2
]));
if
(
strcasecmp
(
key
,
"replaygain_track_gain"
)
==
0
)
{
if
(
strcasecmp
(
key
,
"replaygain_track_gain"
)
==
0
)
{
replay
GainI
nfo
->
trackGain
=
atof
(
value
);
replay
_gain_i
nfo
->
trackGain
=
atof
(
value
);
found
=
1
;
found
=
1
;
}
else
if
(
strcasecmp
(
key
,
"replaygain_album_gain"
)
==
0
)
{
}
else
if
(
strcasecmp
(
key
,
"replaygain_album_gain"
)
==
0
)
{
replay
GainI
nfo
->
albumGain
=
atof
(
value
);
replay
_gain_i
nfo
->
albumGain
=
atof
(
value
);
found
=
1
;
found
=
1
;
}
else
if
(
strcasecmp
(
key
,
"replaygain_track_peak"
)
==
0
)
{
}
else
if
(
strcasecmp
(
key
,
"replaygain_track_peak"
)
==
0
)
{
replay
GainI
nfo
->
trackPeak
=
atof
(
value
);
replay
_gain_i
nfo
->
trackPeak
=
atof
(
value
);
found
=
1
;
found
=
1
;
}
else
if
(
strcasecmp
(
key
,
"replaygain_album_peak"
)
==
0
)
{
}
else
if
(
strcasecmp
(
key
,
"replaygain_album_peak"
)
==
0
)
{
replay
GainI
nfo
->
albumPeak
=
atof
(
value
);
replay
_gain_i
nfo
->
albumPeak
=
atof
(
value
);
found
=
1
;
found
=
1
;
}
}
...
@@ -239,22 +239,21 @@ static ReplayGainInfo *parseId3ReplayGainInfo(struct id3_tag *tag)
...
@@ -239,22 +239,21 @@ static ReplayGainInfo *parseId3ReplayGainInfo(struct id3_tag *tag)
}
}
if
(
found
)
if
(
found
)
return
replay
GainI
nfo
;
return
replay
_gain_i
nfo
;
freeReplayGainInfo
(
replay
GainI
nfo
);
freeReplayGainInfo
(
replay
_gain_i
nfo
);
return
NULL
;
return
NULL
;
}
}
#endif
#endif
#ifdef HAVE_ID3TAG
#ifdef HAVE_ID3TAG
static
void
mp3_parseId3Tag
(
mp3DecodeData
*
data
,
size_t
tagsize
,
static
void
mp3_parse_id3
(
struct
mp3_data
*
data
,
size_t
tagsize
,
struct
tag
**
mpdTag
,
ReplayGainInfo
**
replayGainInfo
)
struct
tag
**
mpd_tag
,
ReplayGainInfo
**
replay_gain_info_r
)
{
{
struct
id3_tag
*
id3
T
ag
=
NULL
;
struct
id3_tag
*
id3
_t
ag
=
NULL
;
id3_length_t
count
;
id3_length_t
count
;
id3_byte_t
const
*
id3_data
;
id3_byte_t
const
*
id3_data
;
id3_byte_t
*
allocated
=
NULL
;
id3_byte_t
*
allocated
=
NULL
;
struct
tag
*
tmpMpdTag
;
ReplayGainInfo
*
tmpReplayGainInfo
;
count
=
data
->
stream
.
bufend
-
data
->
stream
.
this_frame
;
count
=
data
->
stream
.
bufend
-
data
->
stream
.
this_frame
;
...
@@ -272,7 +271,7 @@ static void mp3_parseId3Tag(mp3DecodeData * data, size_t tagsize,
...
@@ -272,7 +271,7 @@ static void mp3_parseId3Tag(mp3DecodeData * data, size_t tagsize,
while
(
count
<
tagsize
)
{
while
(
count
<
tagsize
)
{
size_t
len
;
size_t
len
;
len
=
decoder_read
(
data
->
decoder
,
data
->
in
S
tream
,
len
=
decoder_read
(
data
->
decoder
,
data
->
in
put_s
tream
,
allocated
+
count
,
tagsize
-
count
);
allocated
+
count
,
tagsize
-
count
);
if
(
len
==
0
)
if
(
len
==
0
)
break
;
break
;
...
@@ -288,29 +287,29 @@ static void mp3_parseId3Tag(mp3DecodeData * data, size_t tagsize,
...
@@ -288,29 +287,29 @@ static void mp3_parseId3Tag(mp3DecodeData * data, size_t tagsize,
id3_data
=
allocated
;
id3_data
=
allocated
;
}
}
id3
T
ag
=
id3_tag_parse
(
id3_data
,
tagsize
);
id3
_t
ag
=
id3_tag_parse
(
id3_data
,
tagsize
);
if
(
!
id3Tag
)
if
(
id3_tag
==
NULL
)
goto
fail
;
goto
fail
;
if
(
mpd
T
ag
)
{
if
(
mpd
_t
ag
)
{
tmpMpdTag
=
tag_id3_import
(
id3T
ag
);
struct
tag
*
tmp_tag
=
tag_id3_import
(
id3_t
ag
);
if
(
tmp
MpdTag
)
{
if
(
tmp
_tag
!=
NULL
)
{
if
(
*
mpd
Tag
)
if
(
*
mpd
_tag
!=
NULL
)
tag_free
(
*
mpd
T
ag
);
tag_free
(
*
mpd
_t
ag
);
*
mpd
Tag
=
tmpMpdT
ag
;
*
mpd
_tag
=
tmp_t
ag
;
}
}
}
}
if
(
replay
GainInfo
)
{
if
(
replay
_gain_info_r
)
{
tmpReplayGainInfo
=
parseId3ReplayGainInfo
(
id3T
ag
);
ReplayGainInfo
*
tmp_rgi
=
parse_id3_replay_gain_info
(
id3_t
ag
);
if
(
tmp
ReplayGainInfo
)
{
if
(
tmp
_rgi
!=
NULL
)
{
if
(
*
replay
GainInfo
)
if
(
*
replay
_gain_info_r
)
freeReplayGainInfo
(
*
replay
GainInfo
);
freeReplayGainInfo
(
*
replay
_gain_info_r
);
*
replay
GainInfo
=
tmpReplayGainInfo
;
*
replay
_gain_info_r
=
tmp_rgi
;
}
}
}
}
id3_tag_delete
(
id3
T
ag
);
id3_tag_delete
(
id3
_t
ag
);
fail:
fail:
if
(
allocated
)
if
(
allocated
)
free
(
allocated
);
free
(
allocated
);
...
@@ -318,14 +317,14 @@ fail:
...
@@ -318,14 +317,14 @@ fail:
#endif
#endif
static
enum
mp3_action
static
enum
mp3_action
decode
NextFrameHeader
(
mp3DecodeData
*
data
,
struct
tag
**
tag
,
decode
_next_frame_header
(
struct
mp3_data
*
data
,
struct
tag
**
tag
,
ReplayGainInfo
**
replayGainInfo
)
ReplayGainInfo
**
replay_gain_info_r
)
{
{
enum
mad_layer
layer
;
enum
mad_layer
layer
;
if
((
data
->
stream
).
buffer
==
NULL
if
((
data
->
stream
).
buffer
==
NULL
||
(
data
->
stream
).
error
==
MAD_ERROR_BUFLEN
)
{
||
(
data
->
stream
).
error
==
MAD_ERROR_BUFLEN
)
{
if
(
fillMp3InputB
uffer
(
data
)
<
0
)
{
if
(
mp3_fill_b
uffer
(
data
)
<
0
)
{
return
DECODE_BREAK
;
return
DECODE_BREAK
;
}
}
}
}
...
@@ -342,8 +341,8 @@ decodeNextFrameHeader(mp3DecodeData * data, struct tag ** tag,
...
@@ -342,8 +341,8 @@ decodeNextFrameHeader(mp3DecodeData * data, struct tag ** tag,
if
(
tagsize
>
0
)
{
if
(
tagsize
>
0
)
{
if
(
tag
&&
!
(
*
tag
))
{
if
(
tag
&&
!
(
*
tag
))
{
mp3_parse
Id3Tag
(
data
,
(
size_t
)
tagsize
,
mp3_parse
_id3
(
data
,
(
size_t
)
tagsize
,
tag
,
replayGainInfo
);
tag
,
replay_gain_info_r
);
}
else
{
}
else
{
mad_stream_skip
(
&
(
data
->
stream
),
mad_stream_skip
(
&
(
data
->
stream
),
tagsize
);
tagsize
);
...
@@ -382,11 +381,11 @@ decodeNextFrameHeader(mp3DecodeData * data, struct tag ** tag,
...
@@ -382,11 +381,11 @@ decodeNextFrameHeader(mp3DecodeData * data, struct tag ** tag,
}
}
static
enum
mp3_action
static
enum
mp3_action
decodeNextFrame
(
mp3DecodeData
*
data
)
decodeNextFrame
(
struct
mp3_data
*
data
)
{
{
if
((
data
->
stream
).
buffer
==
NULL
if
((
data
->
stream
).
buffer
==
NULL
||
(
data
->
stream
).
error
==
MAD_ERROR_BUFLEN
)
{
||
(
data
->
stream
).
error
==
MAD_ERROR_BUFLEN
)
{
if
(
fillMp3InputB
uffer
(
data
)
<
0
)
{
if
(
mp3_fill_b
uffer
(
data
)
<
0
)
{
return
DECODE_BREAK
;
return
DECODE_BREAK
;
}
}
}
}
...
@@ -458,10 +457,10 @@ struct lame {
...
@@ -458,10 +457,10 @@ struct lame {
char
encoder
[
10
];
/* 9 byte encoder name/version ("LAME3.97b") */
char
encoder
[
10
];
/* 9 byte encoder name/version ("LAME3.97b") */
struct
version
version
;
/* struct containing just the version */
struct
version
version
;
/* struct containing just the version */
float
peak
;
/* replaygain peak */
float
peak
;
/* replaygain peak */
float
track
Gain
;
/* replaygain track gain */
float
track
_gain
;
/* replaygain track gain */
float
album
Gain
;
/* replaygain album gain */
float
album
_gain
;
/* replaygain album gain */
int
encoder
Delay
;
/* # of added samples at start of mp3 */
int
encoder
_delay
;
/* # of added samples at start of mp3 */
int
encoder
Padding
;
/* # of added samples at end of mp3 */
int
encoder
_padding
;
/* # of added samples at end of mp3 */
int
crc
;
/* CRC of the first 190 bytes of this frame */
int
crc
;
/* CRC of the first 190 bytes of this frame */
};
};
...
@@ -587,29 +586,29 @@ static int parse_lame(struct lame *lame, struct mad_bitptr *ptr, int *bitlen)
...
@@ -587,29 +586,29 @@ static int parse_lame(struct lame *lame, struct mad_bitptr *ptr, int *bitlen)
lame
->
peak
=
mad_f_todouble
(
mad_bit_read
(
ptr
,
32
)
<<
5
);
/* peak */
lame
->
peak
=
mad_f_todouble
(
mad_bit_read
(
ptr
,
32
)
<<
5
);
/* peak */
DEBUG
(
"LAME peak found: %f
\n
"
,
lame
->
peak
);
DEBUG
(
"LAME peak found: %f
\n
"
,
lame
->
peak
);
lame
->
track
G
ain
=
0
;
lame
->
track
_g
ain
=
0
;
name
=
mad_bit_read
(
ptr
,
3
);
/* gain name */
name
=
mad_bit_read
(
ptr
,
3
);
/* gain name */
orig
=
mad_bit_read
(
ptr
,
3
);
/* gain originator */
orig
=
mad_bit_read
(
ptr
,
3
);
/* gain originator */
sign
=
mad_bit_read
(
ptr
,
1
);
/* sign bit */
sign
=
mad_bit_read
(
ptr
,
1
);
/* sign bit */
gain
=
mad_bit_read
(
ptr
,
9
);
/* gain*10 */
gain
=
mad_bit_read
(
ptr
,
9
);
/* gain*10 */
if
(
gain
&&
name
==
1
&&
orig
!=
0
)
{
if
(
gain
&&
name
==
1
&&
orig
!=
0
)
{
lame
->
track
G
ain
=
((
sign
?
-
gain
:
gain
)
/
10
.
0
)
+
adj
;
lame
->
track
_g
ain
=
((
sign
?
-
gain
:
gain
)
/
10
.
0
)
+
adj
;
DEBUG
(
"LAME track gain found: %f
\n
"
,
lame
->
track
G
ain
);
DEBUG
(
"LAME track gain found: %f
\n
"
,
lame
->
track
_g
ain
);
}
}
/* tmz reports that this isn't currently written by any version of lame
/* tmz reports that this isn't currently written by any version of lame
* (as of 3.97). Since we have no way of testing it, don't use it.
* (as of 3.97). Since we have no way of testing it, don't use it.
* Wouldn't want to go blowing someone's ears just because we read it
* Wouldn't want to go blowing someone's ears just because we read it
* wrong. :P -- jat */
* wrong. :P -- jat */
lame
->
album
G
ain
=
0
;
lame
->
album
_g
ain
=
0
;
#if 0
#if 0
name = mad_bit_read(ptr, 3); /* gain name */
name = mad_bit_read(ptr, 3); /* gain name */
orig = mad_bit_read(ptr, 3); /* gain originator */
orig = mad_bit_read(ptr, 3); /* gain originator */
sign = mad_bit_read(ptr, 1); /* sign bit */
sign = mad_bit_read(ptr, 1); /* sign bit */
gain = mad_bit_read(ptr, 9); /* gain*10 */
gain = mad_bit_read(ptr, 9); /* gain*10 */
if (gain && name == 2 && orig != 0) {
if (gain && name == 2 && orig != 0) {
lame->album
G
ain = ((sign ? -gain : gain) / 10.0) + adj;
lame->album
_g
ain = ((sign ? -gain : gain) / 10.0) + adj;
DEBUG("LAME album gain found: %f\n", lame->track
G
ain);
DEBUG("LAME album gain found: %f\n", lame->track
_g
ain);
}
}
#else
#else
mad_bit_read
(
ptr
,
16
);
mad_bit_read
(
ptr
,
16
);
...
@@ -617,11 +616,11 @@ static int parse_lame(struct lame *lame, struct mad_bitptr *ptr, int *bitlen)
...
@@ -617,11 +616,11 @@ static int parse_lame(struct lame *lame, struct mad_bitptr *ptr, int *bitlen)
mad_bit_read
(
ptr
,
16
);
mad_bit_read
(
ptr
,
16
);
lame
->
encoder
D
elay
=
mad_bit_read
(
ptr
,
12
);
lame
->
encoder
_d
elay
=
mad_bit_read
(
ptr
,
12
);
lame
->
encoder
P
adding
=
mad_bit_read
(
ptr
,
12
);
lame
->
encoder
_p
adding
=
mad_bit_read
(
ptr
,
12
);
DEBUG
(
"encoder delay is %i, encoder padding is %i
\n
"
,
DEBUG
(
"encoder delay is %i, encoder padding is %i
\n
"
,
lame
->
encoder
Delay
,
lame
->
encoderP
adding
);
lame
->
encoder
_delay
,
lame
->
encoder_p
adding
);
mad_bit_read
(
ptr
,
80
);
mad_bit_read
(
ptr
,
80
);
...
@@ -632,8 +631,9 @@ static int parse_lame(struct lame *lame, struct mad_bitptr *ptr, int *bitlen)
...
@@ -632,8 +631,9 @@ static int parse_lame(struct lame *lame, struct mad_bitptr *ptr, int *bitlen)
return
1
;
return
1
;
}
}
static
int
decodeFirstFrame
(
mp3DecodeData
*
data
,
static
int
struct
tag
**
tag
,
ReplayGainInfo
**
replayGainInfo
)
mp3_decode_first_frame
(
struct
mp3_data
*
data
,
struct
tag
**
tag
,
ReplayGainInfo
**
replay_gain_info_r
)
{
{
struct
decoder
*
decoder
=
data
->
decoder
;
struct
decoder
*
decoder
=
data
->
decoder
;
struct
xing
xing
;
struct
xing
xing
;
...
@@ -647,7 +647,7 @@ static int decodeFirstFrame(mp3DecodeData * data,
...
@@ -647,7 +647,7 @@ static int decodeFirstFrame(mp3DecodeData * data,
xing
.
flags
=
0
;
xing
.
flags
=
0
;
while
(
1
)
{
while
(
1
)
{
while
((
ret
=
decode
NextFrameHeader
(
data
,
tag
,
replayGainInfo
))
==
DECODE_CONT
&&
while
((
ret
=
decode
_next_frame_header
(
data
,
tag
,
replay_gain_info_r
))
==
DECODE_CONT
&&
(
!
decoder
||
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_NONE
));
(
!
decoder
||
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_NONE
));
if
(
ret
==
DECODE_BREAK
||
if
(
ret
==
DECODE_BREAK
||
(
decoder
&&
decoder_get_command
(
decoder
)
!=
DECODE_COMMAND_NONE
))
(
decoder
&&
decoder_get_command
(
decoder
)
!=
DECODE_COMMAND_NONE
))
...
@@ -669,112 +669,111 @@ static int decodeFirstFrame(mp3DecodeData * data,
...
@@ -669,112 +669,111 @@ static int decodeFirstFrame(mp3DecodeData * data,
* Attempt to calulcate the length of the song from filesize
* Attempt to calulcate the length of the song from filesize
*/
*/
{
{
off_t
offset
=
data
->
in
S
tream
->
offset
;
off_t
offset
=
data
->
in
put_s
tream
->
offset
;
mad_timer_t
duration
=
data
->
frame
.
header
.
duration
;
mad_timer_t
duration
=
data
->
frame
.
header
.
duration
;
float
frameTime
=
((
float
)
mad_timer_count
(
duration
,
float
frame_duration
=
((
float
)
mad_timer_count
(
duration
,
MAD_UNITS_MILLISECONDS
))
/
1000
;
MAD_UNITS_MILLISECONDS
))
/
1000
;
if
(
data
->
stream
.
this_frame
!=
NULL
)
if
(
data
->
stream
.
this_frame
!=
NULL
)
offset
-=
data
->
stream
.
bufend
-
data
->
stream
.
this_frame
;
offset
-=
data
->
stream
.
bufend
-
data
->
stream
.
this_frame
;
else
else
offset
-=
data
->
stream
.
bufend
-
data
->
stream
.
buffer
;
offset
-=
data
->
stream
.
bufend
-
data
->
stream
.
buffer
;
if
(
data
->
in
S
tream
->
size
>=
offset
)
{
if
(
data
->
in
put_s
tream
->
size
>=
offset
)
{
data
->
total
Time
=
((
data
->
inS
tream
->
size
-
offset
)
*
data
->
total
_time
=
((
data
->
input_s
tream
->
size
-
offset
)
*
8
.
0
)
/
(
data
->
frame
).
header
.
bitrate
;
8
.
0
)
/
(
data
->
frame
).
header
.
bitrate
;
data
->
max
Frames
=
data
->
totalTime
/
frameTime
+
data
->
max
_frames
=
data
->
total_time
/
frame_duration
+
FRAMES_CUSHION
;
FRAMES_CUSHION
;
}
else
{
}
else
{
data
->
max
F
rames
=
FRAMES_CUSHION
;
data
->
max
_f
rames
=
FRAMES_CUSHION
;
data
->
total
T
ime
=
0
;
data
->
total
_t
ime
=
0
;
}
}
}
}
/*
/*
* if an xing tag exists, use that!
* if an xing tag exists, use that!
*/
*/
if
(
parse_xing
(
&
xing
,
&
ptr
,
&
bitlen
))
{
if
(
parse_xing
(
&
xing
,
&
ptr
,
&
bitlen
))
{
data
->
found
X
ing
=
1
;
data
->
found
_x
ing
=
1
;
data
->
mute
F
rame
=
MUTEFRAME_SKIP
;
data
->
mute
_f
rame
=
MUTEFRAME_SKIP
;
if
((
xing
.
flags
&
XING_FRAMES
)
&&
xing
.
frames
)
{
if
((
xing
.
flags
&
XING_FRAMES
)
&&
xing
.
frames
)
{
mad_timer_t
duration
=
data
->
frame
.
header
.
duration
;
mad_timer_t
duration
=
data
->
frame
.
header
.
duration
;
mad_timer_multiply
(
&
duration
,
xing
.
frames
);
mad_timer_multiply
(
&
duration
,
xing
.
frames
);
data
->
total
T
ime
=
((
float
)
mad_timer_count
(
duration
,
MAD_UNITS_MILLISECONDS
))
/
1000
;
data
->
total
_t
ime
=
((
float
)
mad_timer_count
(
duration
,
MAD_UNITS_MILLISECONDS
))
/
1000
;
data
->
max
F
rames
=
xing
.
frames
;
data
->
max
_f
rames
=
xing
.
frames
;
}
}
if
(
parse_lame
(
&
lame
,
&
ptr
,
&
bitlen
))
{
if
(
parse_lame
(
&
lame
,
&
ptr
,
&
bitlen
))
{
if
(
gapless
PlaybackEnabled
&&
if
(
gapless
_playback
&&
data
->
in
S
tream
->
seekable
)
{
data
->
in
put_s
tream
->
seekable
)
{
data
->
drop
SamplesAtStart
=
lame
.
encoderD
elay
+
data
->
drop
_start_samples
=
lame
.
encoder_d
elay
+
DECODERDELAY
;
DECODERDELAY
;
data
->
drop
SamplesAtEnd
=
lame
.
encoderP
adding
;
data
->
drop
_end_samples
=
lame
.
encoder_p
adding
;
}
}
/* Album gain isn't currently used. See comment in
/* Album gain isn't currently used. See comment in
* parse_lame() for details. -- jat */
* parse_lame() for details. -- jat */
if
(
replay
GainInfo
&&
!*
replayGainInfo
&&
if
(
replay
_gain_info_r
&&
!*
replay_gain_info_r
&&
lame
.
track
G
ain
)
{
lame
.
track
_g
ain
)
{
*
replay
GainInfo
=
newReplayGainInfo
();
*
replay
_gain_info_r
=
newReplayGainInfo
();
(
*
replay
GainInfo
)
->
trackGain
=
lame
.
trackG
ain
;
(
*
replay
_gain_info_r
)
->
trackGain
=
lame
.
track_g
ain
;
(
*
replay
GainInfo
)
->
trackPeak
=
lame
.
peak
;
(
*
replay
_gain_info_r
)
->
trackPeak
=
lame
.
peak
;
}
}
}
}
}
}
if
(
!
data
->
max
F
rames
)
return
-
1
;
if
(
!
data
->
max
_f
rames
)
return
-
1
;
if
(
data
->
max
F
rames
>
8
*
1024
*
1024
)
{
if
(
data
->
max
_f
rames
>
8
*
1024
*
1024
)
{
ERROR
(
"mp3 file header indicates too many frames: %lu"
,
ERROR
(
"mp3 file header indicates too many frames: %lu"
,
data
->
max
F
rames
);
data
->
max
_f
rames
);
return
-
1
;
return
-
1
;
}
}
data
->
frame
Offset
=
xmalloc
(
sizeof
(
long
)
*
data
->
maxF
rames
);
data
->
frame
_offsets
=
xmalloc
(
sizeof
(
long
)
*
data
->
max_f
rames
);
data
->
times
=
xmalloc
(
sizeof
(
mad_timer_t
)
*
data
->
max
F
rames
);
data
->
times
=
xmalloc
(
sizeof
(
mad_timer_t
)
*
data
->
max
_f
rames
);
return
0
;
return
0
;
}
}
static
void
mp3
DecodeDataFinalize
(
mp3DecodeData
*
data
)
static
void
mp3
_data_finish
(
struct
mp3_data
*
data
)
{
{
mad_synth_finish
(
&
data
->
synth
);
mad_synth_finish
(
&
data
->
synth
);
mad_frame_finish
(
&
data
->
frame
);
mad_frame_finish
(
&
data
->
frame
);
mad_stream_finish
(
&
data
->
stream
);
mad_stream_finish
(
&
data
->
stream
);
if
(
data
->
frame
Offset
)
free
(
data
->
frameOffset
);
if
(
data
->
frame
_offsets
)
free
(
data
->
frame_offsets
);
if
(
data
->
times
)
free
(
data
->
times
);
if
(
data
->
times
)
free
(
data
->
times
);
}
}
/* this is primarily used for getting total time for tags */
/* this is primarily used for getting total time for tags */
static
int
getMp3TotalT
ime
(
char
*
file
)
static
int
mp3_total_file_t
ime
(
char
*
file
)
{
{
struct
input_stream
in
S
tream
;
struct
input_stream
in
put_s
tream
;
mp3DecodeD
ata
data
;
struct
mp3_d
ata
data
;
int
ret
;
int
ret
;
if
(
!
input_stream_open
(
&
in
S
tream
,
file
))
if
(
!
input_stream_open
(
&
in
put_s
tream
,
file
))
return
-
1
;
return
-
1
;
initMp3DecodeData
(
&
data
,
NULL
,
&
inS
tream
);
mp3_data_init
(
&
data
,
NULL
,
&
input_s
tream
);
if
(
decodeFirstF
rame
(
&
data
,
NULL
,
NULL
)
<
0
)
if
(
mp3_decode_first_f
rame
(
&
data
,
NULL
,
NULL
)
<
0
)
ret
=
-
1
;
ret
=
-
1
;
else
else
ret
=
data
.
total
T
ime
+
0
.
5
;
ret
=
data
.
total
_t
ime
+
0
.
5
;
mp3
DecodeDataFinalize
(
&
data
);
mp3
_data_finish
(
&
data
);
input_stream_close
(
&
in
S
tream
);
input_stream_close
(
&
in
put_s
tream
);
return
ret
;
return
ret
;
}
}
static
int
static
int
openMp3FromInputStream
(
struct
input_stream
*
inStream
,
mp3DecodeData
*
data
,
mp3_open
(
struct
input_stream
*
is
,
struct
mp3_data
*
data
,
struct
decoder
*
decoder
,
struct
tag
**
tag
,
struct
decoder
*
decoder
,
struct
tag
**
tag
,
ReplayGainInfo
**
replayGainInfo
)
ReplayGainInfo
**
replay_gain_info_r
)
{
{
initMp3DecodeData
(
data
,
decoder
,
inStream
);
mp3_data_init
(
data
,
decoder
,
is
);
*
tag
=
NULL
;
*
tag
=
NULL
;
if
(
decodeFirstFrame
(
data
,
tag
,
replayGainInfo
)
<
0
)
{
if
(
mp3_decode_first_frame
(
data
,
tag
,
replay_gain_info_r
)
<
0
)
{
mp3
DecodeDataFinalize
(
data
);
mp3
_data_finish
(
data
);
if
(
tag
&&
*
tag
)
if
(
tag
&&
*
tag
)
tag_free
(
*
tag
);
tag_free
(
*
tag
);
return
-
1
;
return
-
1
;
...
@@ -784,7 +783,7 @@ openMp3FromInputStream(struct input_stream *inStream, mp3DecodeData * data,
...
@@ -784,7 +783,7 @@ openMp3FromInputStream(struct input_stream *inStream, mp3DecodeData * data,
}
}
static
enum
mp3_action
static
enum
mp3_action
mp3
Read
(
mp3DecodeData
*
data
,
ReplayGainInfo
**
replayGainInfo
)
mp3
_read
(
struct
mp3_data
*
data
,
ReplayGainInfo
**
replay_gain_info_r
)
{
{
struct
decoder
*
decoder
=
data
->
decoder
;
struct
decoder
*
decoder
=
data
->
decoder
;
unsigned
int
pcm_length
,
max_samples
;
unsigned
int
pcm_length
,
max_samples
;
...
@@ -792,94 +791,94 @@ mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
...
@@ -792,94 +791,94 @@ mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
int
ret
;
int
ret
;
int
skip
;
int
skip
;
if
(
data
->
current
Frame
>=
data
->
highestF
rame
)
{
if
(
data
->
current
_frame
>=
data
->
highest_f
rame
)
{
mad_timer_add
(
&
data
->
timer
,
(
data
->
frame
).
header
.
duration
);
mad_timer_add
(
&
data
->
timer
,
(
data
->
frame
).
header
.
duration
);
data
->
bit
R
ate
=
(
data
->
frame
).
header
.
bitrate
;
data
->
bit
_r
ate
=
(
data
->
frame
).
header
.
bitrate
;
if
(
data
->
current
Frame
>=
data
->
maxF
rames
)
{
if
(
data
->
current
_frame
>=
data
->
max_f
rames
)
{
data
->
current
Frame
=
data
->
maxF
rames
-
1
;
data
->
current
_frame
=
data
->
max_f
rames
-
1
;
}
else
{
}
else
{
data
->
highest
F
rame
++
;
data
->
highest
_f
rame
++
;
}
}
data
->
frame
Offset
[
data
->
currentFrame
]
=
data
->
inS
tream
->
offset
;
data
->
frame
_offsets
[
data
->
current_frame
]
=
data
->
input_s
tream
->
offset
;
if
(
data
->
stream
.
this_frame
!=
NULL
)
{
if
(
data
->
stream
.
this_frame
!=
NULL
)
{
data
->
frame
Offset
[
data
->
currentF
rame
]
-=
data
->
frame
_offsets
[
data
->
current_f
rame
]
-=
data
->
stream
.
bufend
-
data
->
stream
.
this_frame
;
data
->
stream
.
bufend
-
data
->
stream
.
this_frame
;
}
else
{
}
else
{
data
->
frame
Offset
[
data
->
currentF
rame
]
-=
data
->
frame
_offsets
[
data
->
current_f
rame
]
-=
data
->
stream
.
bufend
-
data
->
stream
.
buffer
;
data
->
stream
.
bufend
-
data
->
stream
.
buffer
;
}
}
data
->
times
[
data
->
current
F
rame
]
=
data
->
timer
;
data
->
times
[
data
->
current
_f
rame
]
=
data
->
timer
;
}
else
{
}
else
{
data
->
timer
=
data
->
times
[
data
->
current
F
rame
];
data
->
timer
=
data
->
times
[
data
->
current
_f
rame
];
}
}
data
->
current
F
rame
++
;
data
->
current
_f
rame
++
;
data
->
elapsed
T
ime
=
data
->
elapsed
_t
ime
=
((
float
)
mad_timer_count
(
data
->
timer
,
MAD_UNITS_MILLISECONDS
))
/
((
float
)
mad_timer_count
(
data
->
timer
,
MAD_UNITS_MILLISECONDS
))
/
1000
;
1000
;
switch
(
data
->
mute
F
rame
)
{
switch
(
data
->
mute
_f
rame
)
{
case
MUTEFRAME_SKIP
:
case
MUTEFRAME_SKIP
:
data
->
mute
F
rame
=
MUTEFRAME_NONE
;
data
->
mute
_f
rame
=
MUTEFRAME_NONE
;
break
;
break
;
case
MUTEFRAME_SEEK
:
case
MUTEFRAME_SEEK
:
if
(
decoder_seek_where
(
decoder
)
<=
data
->
elapsed
T
ime
)
{
if
(
decoder_seek_where
(
decoder
)
<=
data
->
elapsed
_t
ime
)
{
decoder_clear
(
decoder
);
decoder_clear
(
decoder
);
data
->
mute
F
rame
=
MUTEFRAME_NONE
;
data
->
mute
_f
rame
=
MUTEFRAME_NONE
;
decoder_command_finished
(
decoder
);
decoder_command_finished
(
decoder
);
}
}
break
;
break
;
case
MUTEFRAME_NONE
:
case
MUTEFRAME_NONE
:
mad_synth_frame
(
&
data
->
synth
,
&
data
->
frame
);
mad_synth_frame
(
&
data
->
synth
,
&
data
->
frame
);
if
(
!
data
->
found
FirstF
rame
)
{
if
(
!
data
->
found
_first_f
rame
)
{
unsigned
int
samples
PerF
rame
=
(
data
->
synth
).
pcm
.
length
;
unsigned
int
samples
_per_f
rame
=
(
data
->
synth
).
pcm
.
length
;
data
->
drop
FramesAtStart
=
data
->
dropSamplesAtStart
/
samplesPerF
rame
;
data
->
drop
_start_frames
=
data
->
drop_start_samples
/
samples_per_f
rame
;
data
->
drop
FramesAtEnd
=
data
->
dropSamplesAtEnd
/
samplesPerF
rame
;
data
->
drop
_end_frames
=
data
->
drop_end_samples
/
samples_per_f
rame
;
data
->
drop
SamplesAtStart
=
data
->
dropSamplesAtStart
%
samplesPerF
rame
;
data
->
drop
_start_samples
=
data
->
drop_start_samples
%
samples_per_f
rame
;
data
->
drop
SamplesAtEnd
=
data
->
dropSamplesAtEnd
%
samplesPerF
rame
;
data
->
drop
_end_samples
=
data
->
drop_end_samples
%
samples_per_f
rame
;
data
->
found
FirstF
rame
=
1
;
data
->
found
_first_f
rame
=
1
;
}
}
if
(
data
->
drop
FramesAtStart
>
0
)
{
if
(
data
->
drop
_start_frames
>
0
)
{
data
->
drop
FramesAtStart
--
;
data
->
drop
_start_frames
--
;
break
;
break
;
}
else
if
((
data
->
drop
FramesAtEnd
>
0
)
&&
}
else
if
((
data
->
drop
_end_frames
>
0
)
&&
(
data
->
current
Frame
==
(
data
->
maxFrames
+
1
-
data
->
dropFramesAtEnd
)))
{
(
data
->
current
_frame
==
(
data
->
max_frames
+
1
-
data
->
drop_end_frames
)))
{
/* stop decoding, effectively dropping all remaining
/* stop decoding, effectively dropping all remaining
* frames */
* frames */
return
DECODE_BREAK
;
return
DECODE_BREAK
;
}
}
if
(
data
->
in
S
tream
->
meta_title
)
{
if
(
data
->
in
put_s
tream
->
meta_title
)
{
struct
tag
*
tag
=
tag_new
();
struct
tag
*
tag
=
tag_new
();
if
(
data
->
in
S
tream
->
meta_name
)
{
if
(
data
->
in
put_s
tream
->
meta_name
)
{
tag_add_item
(
tag
,
TAG_ITEM_NAME
,
tag_add_item
(
tag
,
TAG_ITEM_NAME
,
data
->
in
S
tream
->
meta_name
);
data
->
in
put_s
tream
->
meta_name
);
}
}
tag_add_item
(
tag
,
TAG_ITEM_TITLE
,
tag_add_item
(
tag
,
TAG_ITEM_TITLE
,
data
->
in
S
tream
->
meta_title
);
data
->
in
put_s
tream
->
meta_title
);
free
(
data
->
in
S
tream
->
meta_title
);
free
(
data
->
in
put_s
tream
->
meta_title
);
data
->
in
S
tream
->
meta_title
=
NULL
;
data
->
in
put_s
tream
->
meta_title
=
NULL
;
tag_free
(
tag
);
tag_free
(
tag
);
}
}
if
(
!
data
->
decoded
FirstF
rame
)
{
if
(
!
data
->
decoded
_first_f
rame
)
{
i
=
data
->
drop
SamplesAtStart
;
i
=
data
->
drop
_start_samples
;
data
->
decoded
FirstF
rame
=
1
;
data
->
decoded
_first_f
rame
=
1
;
}
else
}
else
i
=
0
;
i
=
0
;
pcm_length
=
data
->
synth
.
pcm
.
length
;
pcm_length
=
data
->
synth
.
pcm
.
length
;
if
(
data
->
drop
SamplesAtEnd
&&
if
(
data
->
drop
_end_samples
&&
(
data
->
current
Frame
==
data
->
maxFrames
-
data
->
dropFramesAtEnd
))
{
(
data
->
current
_frame
==
data
->
max_frames
-
data
->
drop_end_frames
))
{
if
(
data
->
drop
SamplesAtEnd
>=
pcm_length
)
if
(
data
->
drop
_end_samples
>=
pcm_length
)
pcm_length
=
0
;
pcm_length
=
0
;
else
else
pcm_length
-=
data
->
drop
SamplesAtEnd
;
pcm_length
-=
data
->
drop
_end_samples
;
}
}
max_samples
=
sizeof
(
data
->
output
B
uffer
)
/
max_samples
=
sizeof
(
data
->
output
_b
uffer
)
/
sizeof
(
data
->
output
B
uffer
[
0
])
/
sizeof
(
data
->
output
_b
uffer
[
0
])
/
MAD_NCHANNELS
(
&
(
data
->
frame
).
header
);
MAD_NCHANNELS
(
&
(
data
->
frame
).
header
);
while
(
i
<
pcm_length
)
{
while
(
i
<
pcm_length
)
{
...
@@ -890,53 +889,52 @@ mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
...
@@ -890,53 +889,52 @@ mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
i
+=
num_samples
;
i
+=
num_samples
;
mad_fixed_to_24_buffer
(
data
->
output
B
uffer
,
mad_fixed_to_24_buffer
(
data
->
output
_b
uffer
,
&
data
->
synth
,
&
data
->
synth
,
i
-
num_samples
,
i
,
i
-
num_samples
,
i
,
MAD_NCHANNELS
(
&
(
data
->
frame
).
header
));
MAD_NCHANNELS
(
&
(
data
->
frame
).
header
));
num_samples
*=
MAD_NCHANNELS
(
&
(
data
->
frame
).
header
);
num_samples
*=
MAD_NCHANNELS
(
&
(
data
->
frame
).
header
);
cmd
=
decoder_data
(
decoder
,
data
->
in
S
tream
,
cmd
=
decoder_data
(
decoder
,
data
->
in
put_s
tream
,
data
->
in
S
tream
->
seekable
,
data
->
in
put_s
tream
->
seekable
,
data
->
output
B
uffer
,
data
->
output
_b
uffer
,
sizeof
(
data
->
output
B
uffer
[
0
])
*
num_samples
,
sizeof
(
data
->
output
_b
uffer
[
0
])
*
num_samples
,
data
->
elapsed
T
ime
,
data
->
elapsed
_t
ime
,
data
->
bit
R
ate
/
1000
,
data
->
bit
_r
ate
/
1000
,
(
replay
GainInfo
!=
NULL
)
?
*
replayGainInfo
:
NULL
);
(
replay
_gain_info_r
!=
NULL
)
?
*
replay_gain_info_r
:
NULL
);
if
(
cmd
==
DECODE_COMMAND_STOP
)
if
(
cmd
==
DECODE_COMMAND_STOP
)
return
DECODE_BREAK
;
return
DECODE_BREAK
;
}
}
if
(
data
->
drop
SamplesAtEnd
&&
if
(
data
->
drop
_end_samples
&&
(
data
->
current
Frame
==
data
->
maxFrames
-
data
->
dropFramesAtEnd
))
(
data
->
current
_frame
==
data
->
max_frames
-
data
->
drop_end_frames
))
/* stop decoding, effectively dropping
/* stop decoding, effectively dropping
* all remaining samples */
* all remaining samples */
return
DECODE_BREAK
;
return
DECODE_BREAK
;
if
(
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_SEEK
&&
if
(
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_SEEK
&&
data
->
in
S
tream
->
seekable
)
{
data
->
in
put_s
tream
->
seekable
)
{
unsigned
long
j
=
0
;
unsigned
long
j
=
0
;
data
->
mute
F
rame
=
MUTEFRAME_SEEK
;
data
->
mute
_f
rame
=
MUTEFRAME_SEEK
;
while
(
j
<
data
->
highest
F
rame
&&
while
(
j
<
data
->
highest
_f
rame
&&
decoder_seek_where
(
decoder
)
>
decoder_seek_where
(
decoder
)
>
((
float
)
mad_timer_count
(
data
->
times
[
j
],
((
float
)
mad_timer_count
(
data
->
times
[
j
],
MAD_UNITS_MILLISECONDS
))
MAD_UNITS_MILLISECONDS
))
/
1000
)
{
/
1000
)
{
j
++
;
j
++
;
}
}
if
(
j
<
data
->
highestFrame
)
{
if
(
j
<
data
->
highest_frame
)
{
if
(
seekMp3InputBuffer
(
data
,
if
(
mp3_seek
(
data
,
data
->
frameOffset
[
j
])
==
data
->
frame_offsets
[
j
])
==
0
)
{
0
)
{
decoder_clear
(
decoder
);
decoder_clear
(
decoder
);
data
->
current
F
rame
=
j
;
data
->
current
_f
rame
=
j
;
decoder_command_finished
(
decoder
);
decoder_command_finished
(
decoder
);
}
else
}
else
decoder_seek_error
(
decoder
);
decoder_seek_error
(
decoder
);
data
->
mute
F
rame
=
MUTEFRAME_NONE
;
data
->
mute
_f
rame
=
MUTEFRAME_NONE
;
}
}
}
else
if
(
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_SEEK
&&
}
else
if
(
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_SEEK
&&
!
data
->
in
S
tream
->
seekable
)
{
!
data
->
in
put_s
tream
->
seekable
)
{
decoder_seek_error
(
decoder
);
decoder_seek_error
(
decoder
);
}
}
}
}
...
@@ -944,14 +942,14 @@ mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
...
@@ -944,14 +942,14 @@ mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
while
(
1
)
{
while
(
1
)
{
skip
=
0
;
skip
=
0
;
while
((
ret
=
while
((
ret
=
decode
NextFrameH
eader
(
data
,
NULL
,
decode
_next_frame_h
eader
(
data
,
NULL
,
replayGainInfo
))
==
DECODE_CONT
replay_gain_info_r
))
==
DECODE_CONT
&&
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_NONE
)
;
&&
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_NONE
)
;
if
(
ret
==
DECODE_BREAK
||
decoder_get_command
(
decoder
)
!=
DECODE_COMMAND_NONE
)
if
(
ret
==
DECODE_BREAK
||
decoder_get_command
(
decoder
)
!=
DECODE_COMMAND_NONE
)
break
;
break
;
else
if
(
ret
==
DECODE_SKIP
)
else
if
(
ret
==
DECODE_SKIP
)
skip
=
1
;
skip
=
1
;
if
(
data
->
mute
F
rame
==
MUTEFRAME_NONE
)
{
if
(
data
->
mute
_f
rame
==
MUTEFRAME_NONE
)
{
while
((
ret
=
decodeNextFrame
(
data
))
==
DECODE_CONT
&&
while
((
ret
=
decodeNextFrame
(
data
))
==
DECODE_CONT
&&
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_NONE
)
;
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_NONE
)
;
if
(
ret
==
DECODE_BREAK
||
if
(
ret
==
DECODE_BREAK
||
...
@@ -977,8 +975,7 @@ mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
...
@@ -977,8 +975,7 @@ mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
return
ret
;
return
ret
;
}
}
static
void
initAudioFormatFromMp3DecodeData
(
mp3DecodeData
*
data
,
static
void
mp3_audio_format
(
struct
mp3_data
*
data
,
struct
audio_format
*
af
)
struct
audio_format
*
af
)
{
{
af
->
bits
=
24
;
af
->
bits
=
24
;
af
->
sample_rate
=
(
data
->
frame
).
header
.
samplerate
;
af
->
sample_rate
=
(
data
->
frame
).
header
.
samplerate
;
...
@@ -986,15 +983,15 @@ static void initAudioFormatFromMp3DecodeData(mp3DecodeData * data,
...
@@ -986,15 +983,15 @@ static void initAudioFormatFromMp3DecodeData(mp3DecodeData * data,
}
}
static
int
static
int
mp3_decode
(
struct
decoder
*
decoder
,
struct
input_stream
*
inS
tream
)
mp3_decode
(
struct
decoder
*
decoder
,
struct
input_stream
*
input_s
tream
)
{
{
mp3DecodeD
ata
data
;
struct
mp3_d
ata
data
;
struct
tag
*
tag
=
NULL
;
struct
tag
*
tag
=
NULL
;
ReplayGainInfo
*
replay
GainI
nfo
=
NULL
;
ReplayGainInfo
*
replay
_gain_i
nfo
=
NULL
;
struct
audio_format
audio_format
;
struct
audio_format
audio_format
;
if
(
openMp3FromInputStream
(
inS
tream
,
&
data
,
decoder
,
if
(
mp3_open
(
input_s
tream
,
&
data
,
decoder
,
&
tag
,
&
replayGainI
nfo
)
<
0
)
{
&
tag
,
&
replay_gain_i
nfo
)
<
0
)
{
if
(
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_NONE
)
{
if
(
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_NONE
)
{
ERROR
ERROR
(
"Input does not appear to be a mp3 bit stream.
\n
"
);
(
"Input does not appear to be a mp3 bit stream.
\n
"
);
...
@@ -1003,67 +1000,69 @@ mp3_decode(struct decoder * decoder, struct input_stream *inStream)
...
@@ -1003,67 +1000,69 @@ mp3_decode(struct decoder * decoder, struct input_stream *inStream)
return
0
;
return
0
;
}
}
initAudioFormatFromMp3DecodeData
(
&
data
,
&
audio_format
);
mp3_audio_format
(
&
data
,
&
audio_format
);
if
(
in
S
tream
->
meta_title
)
{
if
(
in
put_s
tream
->
meta_title
)
{
if
(
tag
)
if
(
tag
)
tag_free
(
tag
);
tag_free
(
tag
);
tag
=
tag_new
();
tag
=
tag_new
();
tag_add_item
(
tag
,
TAG_ITEM_TITLE
,
inStream
->
meta_title
);
tag_add_item
(
tag
,
TAG_ITEM_TITLE
,
input_stream
->
meta_title
);
free
(
inStream
->
meta_title
);
free
(
input_stream
->
meta_title
);
inStream
->
meta_title
=
NULL
;
input_stream
->
meta_title
=
NULL
;
if
(
inStream
->
meta_name
)
{
if
(
input_stream
->
meta_name
)
{
tag_add_item
(
tag
,
TAG_ITEM_NAME
,
inStream
->
meta_name
);
tag_add_item
(
tag
,
TAG_ITEM_NAME
,
input_stream
->
meta_name
);
}
}
tag_free
(
tag
);
tag_free
(
tag
);
}
else
if
(
tag
)
{
}
else
if
(
tag
)
{
if
(
in
S
tream
->
meta_name
)
{
if
(
in
put_s
tream
->
meta_name
)
{
tag_clear_items_by_type
(
tag
,
TAG_ITEM_NAME
);
tag_clear_items_by_type
(
tag
,
TAG_ITEM_NAME
);
tag_add_item
(
tag
,
TAG_ITEM_NAME
,
inStream
->
meta_name
);
tag_add_item
(
tag
,
TAG_ITEM_NAME
,
input_stream
->
meta_name
);
}
}
tag_free
(
tag
);
tag_free
(
tag
);
}
else
if
(
in
S
tream
->
meta_name
)
{
}
else
if
(
in
put_s
tream
->
meta_name
)
{
tag
=
tag_new
();
tag
=
tag_new
();
if
(
inStream
->
meta_name
)
{
if
(
input_stream
->
meta_name
)
{
tag_add_item
(
tag
,
TAG_ITEM_NAME
,
inStream
->
meta_name
);
tag_add_item
(
tag
,
TAG_ITEM_NAME
,
input_stream
->
meta_name
);
}
}
tag_free
(
tag
);
tag_free
(
tag
);
}
}
decoder_initialized
(
decoder
,
&
audio_format
,
data
.
total
T
ime
);
decoder_initialized
(
decoder
,
&
audio_format
,
data
.
total
_t
ime
);
while
(
mp3
Read
(
&
data
,
&
replayGainI
nfo
)
!=
DECODE_BREAK
)
;
while
(
mp3
_read
(
&
data
,
&
replay_gain_i
nfo
)
!=
DECODE_BREAK
)
;
if
(
replay
GainI
nfo
)
if
(
replay
_gain_i
nfo
)
freeReplayGainInfo
(
replay
GainI
nfo
);
freeReplayGainInfo
(
replay
_gain_i
nfo
);
if
(
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_SEEK
&&
if
(
decoder_get_command
(
decoder
)
==
DECODE_COMMAND_SEEK
&&
data
.
mute
F
rame
==
MUTEFRAME_SEEK
)
{
data
.
mute
_f
rame
==
MUTEFRAME_SEEK
)
{
decoder_clear
(
decoder
);
decoder_clear
(
decoder
);
decoder_command_finished
(
decoder
);
decoder_command_finished
(
decoder
);
}
}
decoder_flush
(
decoder
);
decoder_flush
(
decoder
);
mp3
DecodeDataFinalize
(
&
data
);
mp3
_data_finish
(
&
data
);
return
0
;
return
0
;
}
}
static
struct
tag
*
mp3_tag
D
up
(
char
*
file
)
static
struct
tag
*
mp3_tag
_d
up
(
char
*
file
)
{
{
struct
tag
*
ret
=
NULL
;
struct
tag
*
ret
=
NULL
;
int
total_time
;
int
total_time
;
ret
=
tag_id3_load
(
file
);
ret
=
tag_id3_load
(
file
);
total_time
=
getMp3TotalTime
(
file
);
total_time
=
mp3_total_file_time
(
file
);
if
(
total_time
>=
0
)
{
if
(
total_time
>=
0
)
{
if
(
!
ret
)
if
(
!
ret
)
ret
=
tag_new
();
ret
=
tag_new
();
ret
->
time
=
total_time
;
ret
->
time
=
total_time
;
}
else
{
}
else
{
DEBUG
(
"mp3_tag
D
up: Failed to get total song time from: %s
\n
"
,
DEBUG
(
"mp3_tag
_d
up: Failed to get total song time from: %s
\n
"
,
file
);
file
);
}
}
...
@@ -1071,14 +1070,14 @@ static struct tag *mp3_tagDup(char *file)
...
@@ -1071,14 +1070,14 @@ static struct tag *mp3_tagDup(char *file)
}
}
static
const
char
*
mp3_suffixes
[]
=
{
"mp3"
,
"mp2"
,
NULL
};
static
const
char
*
mp3_suffixes
[]
=
{
"mp3"
,
"mp2"
,
NULL
};
static
const
char
*
mp3_mime
T
ypes
[]
=
{
"audio/mpeg"
,
NULL
};
static
const
char
*
mp3_mime
_t
ypes
[]
=
{
"audio/mpeg"
,
NULL
};
struct
decoder_plugin
mp3Plugin
=
{
struct
decoder_plugin
mp3Plugin
=
{
.
name
=
"mp3"
,
.
name
=
"mp3"
,
.
init
=
mp3_plugin_init
,
.
init
=
mp3_plugin_init
,
.
stream_decode
=
mp3_decode
,
.
stream_decode
=
mp3_decode
,
.
tag_dup
=
mp3_tag
D
up
,
.
tag_dup
=
mp3_tag
_d
up
,
.
stream_types
=
INPUT_PLUGIN_STREAM_FILE
|
INPUT_PLUGIN_STREAM_URL
,
.
stream_types
=
INPUT_PLUGIN_STREAM_FILE
|
INPUT_PLUGIN_STREAM_URL
,
.
suffixes
=
mp3_suffixes
,
.
suffixes
=
mp3_suffixes
,
.
mime_types
=
mp3_mime
T
ypes
.
mime_types
=
mp3_mime
_t
ypes
};
};
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