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
5420f9ae
Commit
5420f9ae
authored
Nov 17, 2009
by
Viliam Mateicka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
encoder: introducing flac encoder plugin
parent
39404725
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
324 additions
and
0 deletions
+324
-0
Makefile.am
Makefile.am
+6
-0
NEWS
NEWS
+2
-0
configure.ac
configure.ac
+16
-0
flac_encoder.c
src/encoder/flac_encoder.c
+296
-0
encoder_list.c
src/encoder_list.c
+4
-0
No files found.
Makefile.am
View file @
5420f9ae
...
@@ -501,11 +501,13 @@ endif
...
@@ -501,11 +501,13 @@ endif
ENCODER_CFLAGS
=
\
ENCODER_CFLAGS
=
\
$(LAME_CFLAGS)
\
$(LAME_CFLAGS)
\
$(TWOLAME_CFLAGS)
\
$(TWOLAME_CFLAGS)
\
$
(
patsubst
-I
%/FLAC,-I%,
$(FLAC_CFLAGS)
)
\
$(VORBISENC_CFLAGS)
$(VORBISENC_CFLAGS)
ENCODER_LIBS
=
\
ENCODER_LIBS
=
\
$(LAME_LIBS)
\
$(LAME_LIBS)
\
$(TWOLAME_LIBS)
\
$(TWOLAME_LIBS)
\
$(FLAC_LIBS)
\
$(VORBISENC_LIBS)
$(VORBISENC_LIBS)
ENCODER_SRC
=
ENCODER_SRC
=
...
@@ -529,6 +531,10 @@ endif
...
@@ -529,6 +531,10 @@ endif
if
ENABLE_TWOLAME_ENCODER
if
ENABLE_TWOLAME_ENCODER
ENCODER_SRC
+=
src/encoder/twolame_encoder.c
ENCODER_SRC
+=
src/encoder/twolame_encoder.c
endif
endif
if
ENABLE_FLAC_ENCODER
ENCODER_SRC
+=
src/encoder/flac_encoder.c
endif
endif
endif
...
...
NEWS
View file @
5420f9ae
...
@@ -29,6 +29,8 @@ ver 0.16 (20??/??/??)
...
@@ -29,6 +29,8 @@ ver 0.16 (20??/??/??)
- wavpack: allow more than 2 channels
- wavpack: allow more than 2 channels
* encoders:
* encoders:
- twolame: new encoder plugin based on libtwolame
- twolame: new encoder plugin based on libtwolame
- flac: new encoder plugin based on libFLAC
- wave: new encoder plugin for PCM WAV format
* output:
* output:
- recorder: new output plugin for recording radio streams
- recorder: new output plugin for recording radio streams
- alsa: don't recover on CANCEL
- alsa: don't recover on CANCEL
...
...
configure.ac
View file @
5420f9ae
...
@@ -989,6 +989,8 @@ fi
...
@@ -989,6 +989,8 @@ fi
AM_CONDITIONAL(HAVE_FLAC, test x$enable_flac = xyes)
AM_CONDITIONAL(HAVE_FLAC, test x$enable_flac = xyes)
enable_flac_encoder=$enable_flac
if test x$enable_oggflac = xyes; then
if test x$enable_oggflac = xyes; then
oldmpdcflags="$MPD_CFLAGS"
oldmpdcflags="$MPD_CFLAGS"
oldmpdlibs="$MPD_LIBS"
oldmpdlibs="$MPD_LIBS"
...
@@ -1087,6 +1089,7 @@ else
...
@@ -1087,6 +1089,7 @@ else
enable_lame_encoder=no
enable_lame_encoder=no
enable_twolame_encoder=no
enable_twolame_encoder=no
enable_wave_encoder=no
enable_wave_encoder=no
enable_flac_encoder=no
fi
fi
MPD_AUTO_PKG(vorbis_encoder, VORBISENC, [vorbisenc],
MPD_AUTO_PKG(vorbis_encoder, VORBISENC, [vorbisenc],
...
@@ -1107,6 +1110,7 @@ MPD_AUTO_PKG(twolame_encoder, TWOLAME, [twolame],
...
@@ -1107,6 +1110,7 @@ MPD_AUTO_PKG(twolame_encoder, TWOLAME, [twolame],
if test x$enable_vorbis_encoder != xno ||
if test x$enable_vorbis_encoder != xno ||
test x$enable_lame_encoder != xno ||
test x$enable_lame_encoder != xno ||
test x$enable_twolame_encoder != xno ||
test x$enable_twolame_encoder != xno ||
test x$enable_flac_encoder != xno ||
test x$enable_wave_encoder != xno; then
test x$enable_wave_encoder != xno; then
# at least one encoder plugin is enabled
# at least one encoder plugin is enabled
enable_encoder=yes
enable_encoder=yes
...
@@ -1194,6 +1198,12 @@ if test x$enable_wave_encoder = xyes; then
...
@@ -1194,6 +1198,12 @@ if test x$enable_wave_encoder = xyes; then
[Define to enable the PCM wave encoder plugin])
[Define to enable the PCM wave encoder plugin])
fi
fi
AM_CONDITIONAL(ENABLE_FLAC_ENCODER, test x$enable_flac_encoder = xyes)
if test x$enable_flac_encoder = xyes; then
AC_DEFINE(ENABLE_FLAC_ENCODER, 1,
[Define to enable the FLAC encoder plugin])
fi
dnl
dnl
dnl Documentation
dnl Documentation
dnl
dnl
...
@@ -1444,6 +1454,12 @@ if
...
@@ -1444,6 +1454,12 @@ if
echo " TwoLAME mp3 encoder ...........disabled"
echo " TwoLAME mp3 encoder ...........disabled"
fi
fi
if test x$enable_flac_encoder = xyes; then
echo " FLAC encoder ..................enabled"
else
echo " FLAC encoder ..................disabled"
fi
if test x$enable_wave_encoder = xyes; then
if test x$enable_wave_encoder = xyes; then
echo " PCM wave encoder ..............enabled"
echo " PCM wave encoder ..............enabled"
else
else
...
...
src/encoder/flac_encoder.c
0 → 100644
View file @
5420f9ae
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include "encoder_api.h"
#include "encoder_plugin.h"
#include "audio_format.h"
#include "pcm_buffer.h"
#include <assert.h>
#include <string.h>
#include <FLAC/stream_encoder.h>
struct
flac_encoder
{
struct
encoder
encoder
;
struct
audio_format
audio_format
;
unsigned
compression
;
FLAC__StreamEncoder
*
fse
;
struct
pcm_buffer
expand_buffer
;
struct
pcm_buffer
buffer
;
size_t
buffer_length
;
};
extern
const
struct
encoder_plugin
flac_encoder_plugin
;
static
inline
GQuark
flac_encoder_quark
(
void
)
{
return
g_quark_from_static_string
(
"flac_encoder"
);
}
static
bool
flac_encoder_configure
(
struct
flac_encoder
*
encoder
,
const
struct
config_param
*
param
,
G_GNUC_UNUSED
GError
**
error
)
{
encoder
->
compression
=
config_get_block_unsigned
(
param
,
"compression"
,
5
);
return
true
;
}
static
struct
encoder
*
flac_encoder_init
(
const
struct
config_param
*
param
,
GError
**
error
)
{
struct
flac_encoder
*
encoder
;
encoder
=
g_new
(
struct
flac_encoder
,
1
);
encoder_struct_init
(
&
encoder
->
encoder
,
&
flac_encoder_plugin
);
/* load configuration from "param" */
if
(
!
flac_encoder_configure
(
encoder
,
param
,
error
))
{
/* configuration has failed, roll back and return error */
g_free
(
encoder
);
return
NULL
;
}
return
&
encoder
->
encoder
;
}
static
void
flac_encoder_finish
(
struct
encoder
*
_encoder
)
{
struct
flac_encoder
*
encoder
=
(
struct
flac_encoder
*
)
_encoder
;
/* the real libFLAC cleanup was already performed by
flac_encoder_close(), so no real work here */
g_free
(
encoder
);
}
static
bool
flac_encoder_setup
(
struct
flac_encoder
*
encoder
,
GError
**
error
)
{
if
(
!
FLAC__stream_encoder_set_compression_level
(
encoder
->
fse
,
encoder
->
compression
))
{
g_set_error
(
error
,
flac_encoder_quark
(),
0
,
"error setting flac compression to %d"
,
encoder
->
compression
);
return
false
;
}
if
(
!
FLAC__stream_encoder_set_channels
(
encoder
->
fse
,
encoder
->
audio_format
.
channels
))
{
g_set_error
(
error
,
flac_encoder_quark
(),
0
,
"error setting flac channels num to %d"
,
encoder
->
audio_format
.
channels
);
return
false
;
}
if
(
!
FLAC__stream_encoder_set_bits_per_sample
(
encoder
->
fse
,
encoder
->
audio_format
.
bits
))
{
g_set_error
(
error
,
flac_encoder_quark
(),
0
,
"error setting flac bit format to %d"
,
encoder
->
audio_format
.
bits
);
return
false
;
}
if
(
!
FLAC__stream_encoder_set_sample_rate
(
encoder
->
fse
,
encoder
->
audio_format
.
sample_rate
))
{
g_set_error
(
error
,
flac_encoder_quark
(),
0
,
"error setting flac sample rate to %d"
,
encoder
->
audio_format
.
sample_rate
);
return
false
;
}
return
true
;
}
static
FLAC__StreamEncoderWriteStatus
flac_write_callback
(
G_GNUC_UNUSED
const
FLAC__StreamEncoder
*
fse
,
const
FLAC__byte
data
[],
size_t
bytes
,
G_GNUC_UNUSED
unsigned
samples
,
G_GNUC_UNUSED
unsigned
current_frame
,
void
*
client_data
)
{
struct
flac_encoder
*
encoder
=
(
struct
flac_encoder
*
)
client_data
;
char
*
buffer
=
pcm_buffer_get
(
&
encoder
->
buffer
,
encoder
->
buffer_length
+
bytes
);
//transfer data to buffer
memcpy
(
buffer
+
encoder
->
buffer_length
,
data
,
bytes
);
encoder
->
buffer_length
+=
bytes
;
return
FLAC__STREAM_ENCODER_WRITE_STATUS_OK
;
}
static
bool
flac_encoder_open
(
struct
encoder
*
_encoder
,
struct
audio_format
*
audio_format
,
GError
**
error
)
{
struct
flac_encoder
*
encoder
=
(
struct
flac_encoder
*
)
_encoder
;
FLAC__StreamEncoderInitStatus
init_status
;
encoder
->
audio_format
=
*
audio_format
;
/* FIXME: flac should support 32bit as well */
if
(
audio_format
->
bits
>
24
)
audio_format
->
bits
=
24
;
/* allocate the encoder */
encoder
->
fse
=
FLAC__stream_encoder_new
();
if
(
encoder
->
fse
==
NULL
)
{
g_set_error
(
error
,
flac_encoder_quark
(),
0
,
"flac_new() failed"
);
return
false
;
}
if
(
!
flac_encoder_setup
(
encoder
,
error
))
{
FLAC__stream_encoder_delete
(
encoder
->
fse
);
return
false
;
}
encoder
->
buffer_length
=
0
;
pcm_buffer_init
(
&
encoder
->
buffer
);
pcm_buffer_init
(
&
encoder
->
expand_buffer
);
/* this immediatelly outputs data throught callback */
init_status
=
FLAC__stream_encoder_init_stream
(
encoder
->
fse
,
flac_write_callback
,
NULL
,
NULL
,
NULL
,
encoder
);
if
(
init_status
!=
FLAC__STREAM_ENCODER_INIT_STATUS_OK
)
{
g_set_error
(
error
,
flac_encoder_quark
(),
0
,
"failed to initialize encoder: %s
\n
"
,
FLAC__StreamEncoderInitStatusString
[
init_status
]);
FLAC__stream_encoder_delete
(
encoder
->
fse
);
return
false
;
}
return
true
;
}
static
void
flac_encoder_close
(
struct
encoder
*
_encoder
)
{
struct
flac_encoder
*
encoder
=
(
struct
flac_encoder
*
)
_encoder
;
FLAC__stream_encoder_delete
(
encoder
->
fse
);
pcm_buffer_deinit
(
&
encoder
->
buffer
);
pcm_buffer_deinit
(
&
encoder
->
expand_buffer
);
}
static
bool
flac_encoder_flush
(
struct
encoder
*
_encoder
,
G_GNUC_UNUSED
GError
**
error
)
{
struct
flac_encoder
*
encoder
=
(
struct
flac_encoder
*
)
_encoder
;
return
FLAC__stream_encoder_finish
(
encoder
->
fse
);
}
static
inline
void
pcm8_to_flac
(
int32_t
*
out
,
const
int8_t
*
in
,
unsigned
num_samples
)
{
while
(
num_samples
>
0
)
{
*
out
++
=
*
in
++
;
--
num_samples
;
}
}
static
inline
void
pcm16_to_flac
(
int32_t
*
out
,
const
int16_t
*
in
,
unsigned
num_samples
)
{
while
(
num_samples
>
0
)
{
*
out
++
=
*
in
++
;
--
num_samples
;
}
}
static
bool
flac_encoder_write
(
struct
encoder
*
_encoder
,
const
void
*
data
,
size_t
length
,
G_GNUC_UNUSED
GError
**
error
)
{
struct
flac_encoder
*
encoder
=
(
struct
flac_encoder
*
)
_encoder
;
unsigned
num_frames
,
num_samples
;
void
*
exbuffer
;
const
void
*
buffer
=
NULL
;
/* format conversion */
num_frames
=
length
/
audio_format_frame_size
(
&
encoder
->
audio_format
);
num_samples
=
num_frames
*
encoder
->
audio_format
.
channels
;
switch
(
encoder
->
audio_format
.
bits
)
{
case
8
:
exbuffer
=
pcm_buffer_get
(
&
encoder
->
expand_buffer
,
length
*
4
);
pcm8_to_flac
(
exbuffer
,
data
,
num_samples
);
buffer
=
exbuffer
;
break
;
case
16
:
exbuffer
=
pcm_buffer_get
(
&
encoder
->
expand_buffer
,
length
*
2
);
pcm16_to_flac
(
exbuffer
,
data
,
num_samples
);
buffer
=
exbuffer
;
break
;
case
24
:
case
32
:
/* nothing need to be done
* format is the same for both mpd and libFLAC */
buffer
=
data
;
break
;
}
/* feed samples to encoder */
if
(
!
FLAC__stream_encoder_process_interleaved
(
encoder
->
fse
,
buffer
,
num_frames
))
{
g_set_error
(
error
,
flac_encoder_quark
(),
0
,
"flac encoder process failed"
);
return
false
;
}
return
true
;
}
static
size_t
flac_encoder_read
(
struct
encoder
*
_encoder
,
void
*
dest
,
size_t
length
)
{
struct
flac_encoder
*
encoder
=
(
struct
flac_encoder
*
)
_encoder
;
char
*
buffer
=
pcm_buffer_get
(
&
encoder
->
buffer
,
encoder
->
buffer_length
);
if
(
length
>
encoder
->
buffer_length
)
length
=
encoder
->
buffer_length
;
memcpy
(
dest
,
buffer
,
length
);
encoder
->
buffer_length
-=
length
;
memmove
(
buffer
,
buffer
+
length
,
encoder
->
buffer_length
);
return
length
;
}
const
struct
encoder_plugin
flac_encoder_plugin
=
{
.
name
=
"flac"
,
.
init
=
flac_encoder_init
,
.
finish
=
flac_encoder_finish
,
.
open
=
flac_encoder_open
,
.
close
=
flac_encoder_close
,
.
flush
=
flac_encoder_flush
,
.
write
=
flac_encoder_write
,
.
read
=
flac_encoder_read
,
};
src/encoder_list.c
View file @
5420f9ae
...
@@ -28,6 +28,7 @@ extern const struct encoder_plugin vorbis_encoder_plugin;
...
@@ -28,6 +28,7 @@ extern const struct encoder_plugin vorbis_encoder_plugin;
extern
const
struct
encoder_plugin
lame_encoder_plugin
;
extern
const
struct
encoder_plugin
lame_encoder_plugin
;
extern
const
struct
encoder_plugin
twolame_encoder_plugin
;
extern
const
struct
encoder_plugin
twolame_encoder_plugin
;
extern
const
struct
encoder_plugin
wave_encoder_plugin
;
extern
const
struct
encoder_plugin
wave_encoder_plugin
;
extern
const
struct
encoder_plugin
flac_encoder_plugin
;
static
const
struct
encoder_plugin
*
encoder_plugins
[]
=
{
static
const
struct
encoder_plugin
*
encoder_plugins
[]
=
{
&
null_encoder_plugin
,
&
null_encoder_plugin
,
...
@@ -43,6 +44,9 @@ static const struct encoder_plugin *encoder_plugins[] = {
...
@@ -43,6 +44,9 @@ static const struct encoder_plugin *encoder_plugins[] = {
#ifdef ENABLE_WAVE_ENCODER
#ifdef ENABLE_WAVE_ENCODER
&
wave_encoder_plugin
,
&
wave_encoder_plugin
,
#endif
#endif
#ifdef ENABLE_FLAC_ENCODER
&
flac_encoder_plugin
,
#endif
NULL
NULL
};
};
...
...
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