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
d9578f64
Commit
d9578f64
authored
May 19, 2021
by
Max Kellermann
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'flac-ogg' of
git://github.com/jprjr/VGMPD
parents
b2cec7a0
87fa6bca
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
99 additions
and
32 deletions
+99
-32
plugins.rst
doc/plugins.rst
+4
-0
FlacEncoderPlugin.cxx
src/encoder/plugins/FlacEncoderPlugin.cxx
+80
-17
OggEncoder.hxx
src/encoder/plugins/OggEncoder.hxx
+2
-2
OpusEncoderPlugin.cxx
src/encoder/plugins/OpusEncoderPlugin.cxx
+1
-1
VorbisEncoderPlugin.cxx
src/encoder/plugins/VorbisEncoderPlugin.cxx
+1
-1
meson.build
src/lib/xiph/meson.build
+0
-1
Serial.cxx
src/util/Serial.cxx
+6
-6
Serial.hxx
src/util/Serial.hxx
+4
-4
meson.build
src/util/meson.build
+1
-0
No files found.
doc/plugins.rst
View file @
d9578f64
...
...
@@ -588,6 +588,10 @@ Encodes into `FLAC <https://xiph.org/flac/>`_ (lossless).
- Description
* - **compression**
- Sets the libFLAC compression level. The levels range from 0 (fastest, least compression) to 8 (slowest, most compression).
* - **oggflac yes|no**
- Configures if the stream should be Ogg FLAC versus native FLAC. Defaults to "no" (use native FLAC).
* - **oggchaining yes|no**
- Configures if the stream should use Ogg Chaining for in-stream metadata. Defaults to "no". Setting this to "yes" also enables Ogg FLAC.
lame
----
...
...
src/encoder/plugins/FlacEncoderPlugin.cxx
View file @
d9578f64
...
...
@@ -23,8 +23,11 @@
#include "pcm/Buffer.hxx"
#include "util/DynamicFifoBuffer.hxx"
#include "util/RuntimeError.hxx"
#include "util/Serial.hxx"
#include "util/StringUtil.hxx"
#include <FLAC/stream_encoder.h>
#include <FLAC/metadata.h>
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
#error libFLAC is too old
...
...
@@ -34,6 +37,7 @@ class FlacEncoder final : public Encoder {
const
AudioFormat
audio_format
;
FLAC__StreamEncoder
*
const
fse
;
const
unsigned
compression
;
PcmBuffer
expand_buffer
;
...
...
@@ -44,7 +48,7 @@ class FlacEncoder final : public Encoder {
DynamicFifoBuffer
<
uint8_t
>
output_buffer
;
public
:
FlacEncoder
(
AudioFormat
_audio_format
,
FLAC__StreamEncoder
*
_fse
);
FlacEncoder
(
AudioFormat
_audio_format
,
FLAC__StreamEncoder
*
_fse
,
unsigned
_compression
,
bool
_oggflac
,
bool
_oggchaining
);
~
FlacEncoder
()
noexcept
override
{
FLAC__stream_encoder_delete
(
fse
);
...
...
@@ -56,9 +60,14 @@ public:
}
void
Flush
()
override
{
}
void
PreTag
()
override
{
(
void
)
FLAC__stream_encoder_finish
(
fse
);
}
void
SendTag
(
const
Tag
&
tag
)
override
;
void
Write
(
const
void
*
data
,
size_t
length
)
override
;
size_t
Read
(
void
*
dest
,
size_t
length
)
noexcept
override
{
...
...
@@ -80,6 +89,8 @@ private:
class
PreparedFlacEncoder
final
:
public
PreparedEncoder
{
const
unsigned
compression
;
const
bool
oggchaining
;
const
bool
oggflac
;
public
:
explicit
PreparedFlacEncoder
(
const
ConfigBlock
&
block
);
...
...
@@ -88,12 +99,16 @@ public:
Encoder
*
Open
(
AudioFormat
&
audio_format
)
override
;
[[
nodiscard
]]
const
char
*
GetMimeType
()
const
noexcept
override
{
return
"audio/flac"
;
if
(
oggflac
)
return
"audio/ogg"
;
return
"audio/flac"
;
}
};
PreparedFlacEncoder
::
PreparedFlacEncoder
(
const
ConfigBlock
&
block
)
:
compression
(
block
.
GetBlockValue
(
"compression"
,
5U
))
:
compression
(
block
.
GetBlockValue
(
"compression"
,
5U
)),
oggchaining
(
block
.
GetBlockValue
(
"oggchaining"
,
false
)),
oggflac
(
block
.
GetBlockValue
(
"oggflac"
,
false
)
||
oggchaining
)
{
}
...
...
@@ -105,8 +120,23 @@ flac_encoder_init(const ConfigBlock &block)
static
void
flac_encoder_setup
(
FLAC__StreamEncoder
*
fse
,
unsigned
compression
,
const
AudioFormat
&
audio_format
,
unsigned
bits_per_sample
)
const
AudioFormat
&
audio_format
)
{
unsigned
bits_per_sample
;
switch
(
audio_format
.
format
)
{
case
SampleFormat
:
:
S8
:
bits_per_sample
=
8
;
break
;
case
SampleFormat
:
:
S16
:
bits_per_sample
=
16
;
break
;
default
:
bits_per_sample
=
24
;
}
if
(
!
FLAC__stream_encoder_set_compression_level
(
fse
,
compression
))
throw
FormatRuntimeError
(
"error setting flac compression to %d"
,
compression
);
...
...
@@ -123,16 +153,26 @@ flac_encoder_setup(FLAC__StreamEncoder *fse, unsigned compression,
audio_format
.
sample_rate
))
throw
FormatRuntimeError
(
"error setting flac sample rate to %d"
,
audio_format
.
sample_rate
);
if
(
!
FLAC__stream_encoder_set_ogg_serial_number
(
fse
,
GenerateSerial
()))
throw
FormatRuntimeError
(
"error setting ogg serial number"
);
}
FlacEncoder
::
FlacEncoder
(
AudioFormat
_audio_format
,
FLAC__StreamEncoder
*
_fse
)
:
Encoder
(
false
),
FlacEncoder
::
FlacEncoder
(
AudioFormat
_audio_format
,
FLAC__StreamEncoder
*
_fse
,
unsigned
_compression
,
bool
_oggflac
,
bool
_oggchaining
)
:
Encoder
(
_oggchaining
),
audio_format
(
_audio_format
),
fse
(
_fse
),
compression
(
_compression
),
output_buffer
(
8192
)
{
/* this immediately outputs data through callback */
auto
init_status
=
auto
init_status
=
_oggflac
?
FLAC__stream_encoder_init_ogg_stream
(
fse
,
nullptr
,
WriteCallback
,
nullptr
,
nullptr
,
nullptr
,
this
)
:
FLAC__stream_encoder_init_stream
(
fse
,
WriteCallback
,
nullptr
,
nullptr
,
nullptr
,
...
...
@@ -146,24 +186,17 @@ FlacEncoder::FlacEncoder(AudioFormat _audio_format, FLAC__StreamEncoder *_fse)
Encoder
*
PreparedFlacEncoder
::
Open
(
AudioFormat
&
audio_format
)
{
unsigned
bits_per_sample
;
/* FIXME: flac should support 32bit as well */
switch
(
audio_format
.
format
)
{
case
SampleFormat
:
:
S8
:
bits_per_sample
=
8
;
break
;
case
SampleFormat
:
:
S16
:
bits_per_sample
=
16
;
break
;
case
SampleFormat
:
:
S24_P32
:
bits_per_sample
=
24
;
break
;
default
:
bits_per_sample
=
24
;
audio_format
.
format
=
SampleFormat
::
S24_P32
;
}
...
...
@@ -173,16 +206,46 @@ PreparedFlacEncoder::Open(AudioFormat &audio_format)
throw
std
::
runtime_error
(
"FLAC__stream_encoder_new() failed"
);
try
{
flac_encoder_setup
(
fse
,
compression
,
audio_format
,
bits_per_sample
);
flac_encoder_setup
(
fse
,
compression
,
audio_format
);
}
catch
(...)
{
FLAC__stream_encoder_delete
(
fse
);
throw
;
}
return
new
FlacEncoder
(
audio_format
,
fse
);
return
new
FlacEncoder
(
audio_format
,
fse
,
compression
,
oggflac
,
oggchaining
);
}
void
FlacEncoder
::
SendTag
(
const
Tag
&
tag
)
{
/* re-initialize encoder since flac_encoder_finish resets everything */
flac_encoder_setup
(
fse
,
compression
,
audio_format
);
FLAC__StreamMetadata
*
metadata
=
FLAC__metadata_object_new
(
FLAC__METADATA_TYPE_VORBIS_COMMENT
);
FLAC__StreamMetadata_VorbisComment_Entry
entry
;
for
(
const
auto
&
item
:
tag
)
{
char
name
[
64
];
ToUpperASCII
(
name
,
tag_item_names
[
item
.
type
],
sizeof
(
name
));
FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair
(
&
entry
,
name
,
item
.
value
);
FLAC__metadata_object_vorbiscomment_append_comment
(
metadata
,
entry
,
false
);
}
FLAC__stream_encoder_set_metadata
(
fse
,
&
metadata
,
1
);
auto
init_status
=
FLAC__stream_encoder_init_ogg_stream
(
fse
,
nullptr
,
WriteCallback
,
nullptr
,
nullptr
,
nullptr
,
this
);
FLAC__metadata_object_delete
(
metadata
);
if
(
init_status
!=
FLAC__STREAM_ENCODER_INIT_STATUS_OK
)
throw
FormatRuntimeError
(
"failed to initialize encoder: %s
\n
"
,
FLAC__StreamEncoderInitStatusString
[
init_status
]);
}
static
inline
void
pcm8_to_flac
(
int32_t
*
out
,
const
int8_t
*
in
,
unsigned
num_samples
)
noexcept
{
...
...
src/encoder/plugins/OggEncoder.hxx
View file @
d9578f64
...
...
@@ -23,7 +23,7 @@
#include "../EncoderAPI.hxx"
#include "lib/xiph/OggStreamState.hxx"
#include "lib/xiph/OggPage.hxx"
#include "
lib/xiph/Ogg
Serial.hxx"
#include "
util/
Serial.hxx"
#include <ogg/ogg.h>
...
...
@@ -42,7 +42,7 @@ protected:
public
:
OggEncoder
(
bool
_implements_tag
)
:
Encoder
(
_implements_tag
),
stream
(
Generate
Ogg
Serial
())
{
stream
(
GenerateSerial
())
{
}
/* virtual methods from class Encoder */
...
...
src/encoder/plugins/OpusEncoderPlugin.cxx
View file @
d9578f64
...
...
@@ -405,7 +405,7 @@ OpusEncoder::PreTag()
void
OpusEncoder
::
SendTag
(
const
Tag
&
tag
)
{
stream
.
Reinitialize
(
Generate
Ogg
Serial
());
stream
.
Reinitialize
(
GenerateSerial
());
opus_encoder_ctl
(
enc
,
OPUS_GET_LOOKAHEAD
(
&
lookahead
));
GenerateHeaders
(
&
tag
);
}
...
...
src/encoder/plugins/VorbisEncoderPlugin.cxx
View file @
d9578f64
...
...
@@ -225,7 +225,7 @@ VorbisEncoder::SendTag(const Tag &tag)
/* reset ogg_stream_state and begin a new stream */
stream
.
Reinitialize
(
Generate
Ogg
Serial
());
stream
.
Reinitialize
(
GenerateSerial
());
/* send that vorbis_comment to the ogg_stream_state */
...
...
src/lib/xiph/meson.build
View file @
d9578f64
...
...
@@ -72,7 +72,6 @@ if libogg_dep.found()
ogg = static_library(
'ogg',
'OggVisitor.cxx',
'OggSerial.cxx',
'OggSyncState.cxx',
'OggFind.cxx',
'OggPacket.cxx',
...
...
src/
lib/xiph/Ogg
Serial.cxx
→
src/
util/
Serial.cxx
View file @
d9578f64
...
...
@@ -17,18 +17,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "
Ogg
Serial.hxx"
#include "
util/
Compiler.h"
#include "Serial.hxx"
#include "Compiler.h"
#include <atomic>
#include <chrono>
static
std
::
atomic_uint
next_
ogg_
serial
;
static
std
::
atomic_uint
next_serial
;
int
Generate
Ogg
Serial
()
noexcept
GenerateSerial
()
noexcept
{
unsigned
serial
=
++
next_
ogg_
serial
;
unsigned
serial
=
++
next_serial
;
if
(
gcc_unlikely
(
serial
<
16
))
{
/* first-time initialization: seed with a clock value,
which is random enough for our use */
...
...
@@ -38,7 +38,7 @@ GenerateOggSerial() noexcept
const
auto
now
=
steady_clock
::
now
().
time_since_epoch
();
const
auto
now_ms
=
duration_cast
<
milliseconds
>
(
now
);
const
unsigned
seed
=
now_ms
.
count
();
next_
ogg_
serial
=
serial
=
seed
;
next_serial
=
serial
=
seed
;
}
return
serial
;
...
...
src/
lib/xiph/Ogg
Serial.hxx
→
src/
util/
Serial.hxx
View file @
d9578f64
...
...
@@ -17,13 +17,13 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_
OGG_
SERIAL_HXX
#define MPD_
OGG_
SERIAL_HXX
#ifndef MPD_SERIAL_HXX
#define MPD_SERIAL_HXX
/**
* Generate the next pseudo-random
Ogg
serial.
* Generate the next pseudo-random serial.
*/
int
Generate
Ogg
Serial
()
noexcept
;
GenerateSerial
()
noexcept
;
#endif
src/util/meson.build
View file @
d9578f64
...
...
@@ -29,6 +29,7 @@ util = static_library(
'ByteReverse.cxx',
'format.c',
'BitReverse.cxx',
'Serial.cxx',
include_directories: inc,
)
...
...
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