Skip to content

Commit adfb68c

Browse files
committed
Merge branch 'preserve-encoding'
* preserve-encoding: README.adoc: minor wording fix. Move (not really portable) builtin bswap function into header. README.adoc: document float / double / 32 bit raw stream format raw-format-test.sh: also validate 8-bit raw input/output RawConverter: fix sign flip bug for big endian encoding. raw-format-test.sh: enable more test cases for unsigned encoding. Make testrawconverter fail if int16/uint16 values don't match. Extend testrawconverter to check 16-bit conversion values. TESTS: add raw-format-test (using ffmpeg) Make HLS work again with the encoding related changes. SFInputStream: handle more soundfile subformat types This ensures that libsndfile input .ogg and .mp3 files are treated as 24-bit again (like it used to be in previous audiowmark versions). Add wave subformat test. wav-pipe-test.sh: update test to handle 24:24 and 32:32 in:out bit checks. For raw streams, use float / double as encoding name. Changing raw bit depth is no longer supported for float / double encoding. Support 8 bit format in WavPipeInputStream. StdoutWavOutputStream: preserve encoding rather than optimizing for speed. Support float/double input for WavPipeInputStream. Float encoding fixes. Write floating point output in SFOutputStream for Encoding::FLOAT. Implement Encoding::FLOAT conversions in RawConverter. Fix testwavformat utility. Add Encoding accessor for streams/formats to represent float/double input. Add utility to test sndfile encoding. Signed-off-by: Stefan Westerfeld <[email protected]>
2 parents b73adb9 + 5fbcfc2 commit adfb68c

32 files changed

+762
-160
lines changed

README.adoc

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,9 @@ so this parameter must always be specified for raw streams.
512512
--raw-output-bits <bits>::
513513
--raw-bits <bits>::
514514

515-
The options can be used to set the input number of bits, the output number
516-
of bits or both. The number of bits can either be `16` or `24`. The default
517-
number of bits is `16`.
515+
The options can be used to set the input number of bits, the output number of
516+
bits or both. The number of bits can be `16`, `24` or `32`. The default number
517+
of bits is `16`.
518518

519519
--raw-input-endian <endian>::
520520
--raw-output-endian <endian>::
@@ -528,9 +528,10 @@ endianness is `little`.
528528
--raw-output-encoding <encoding>::
529529
--raw-encoding <encoding>::
530530

531-
These options can be used to set the input/output encoding or both.
532-
The <encoding> parameter can either be `signed` or `unsigned`. The
533-
default encoding is `signed`.
531+
These options can be used to set the input/output encoding or both. The
532+
<encoding> parameter can be `signed`, `unsigned`, `float` or `double`. The
533+
default encoding is `signed`. Using `float` (or `double`) encoding
534+
automatically sets the number of bits to `32` (or `64`).
534535

535536
--raw-channels <channels>::
536537

src/Makefile.am

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ audiowmark_SOURCES = audiowmark.cc $(COMMON_SRC)
1616
audiowmark_LDFLAGS = $(COMMON_LIBS)
1717

1818
noinst_PROGRAMS = testconvcode testrandom testmp3 teststream testlimiter testshortcode testmpegts testthreadpool \
19-
testrawconverter
19+
testrawconverter testwavformat
2020

2121
testconvcode_SOURCES = testconvcode.cc $(COMMON_SRC)
2222
testconvcode_LDFLAGS = $(COMMON_LIBS)
@@ -45,6 +45,9 @@ testthreadpool_LDFLAGS = $(COMMON_LIBS)
4545
testrawconverter_SOURCES = testrawconverter.cc $(COMMON_SRC)
4646
testrawconverter_LDFLAGS = $(COMMON_LIBS)
4747

48+
testwavformat_SOURCES = testwavformat.cc $(COMMON_SRC)
49+
testwavformat_LDFLAGS = $(COMMON_LIBS)
50+
4851
if COND_WITH_FFMPEG
4952
COMMON_SRC += hlsoutputstream.cc hlsoutputstream.hh
5053

src/audiostream.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ AudioInputStream::create (const string& filename, Error& err)
8080
}
8181

8282
std::unique_ptr<AudioOutputStream>
83-
AudioOutputStream::create (const string& filename, int n_channels, int sample_rate, int bit_depth, size_t n_frames, Error& err)
83+
AudioOutputStream::create (const string& filename, int n_channels, int sample_rate, int bit_depth, Encoding encoding, size_t n_frames, Error& err)
8484
{
8585
std::unique_ptr<AudioOutputStream> out_stream;
8686

@@ -98,7 +98,7 @@ AudioOutputStream::create (const string& filename, int n_channels, int sample_ra
9898

9999
StdoutWavOutputStream *swstream = new StdoutWavOutputStream();
100100
out_stream.reset (swstream);
101-
err = swstream->open (n_channels, sample_rate, bit_depth, n_frames, wav_pipe);
101+
err = swstream->open (n_channels, sample_rate, bit_depth, encoding, n_frames, wav_pipe);
102102
if (err)
103103
return nullptr;
104104
}
@@ -113,7 +113,7 @@ AudioOutputStream::create (const string& filename, int n_channels, int sample_ra
113113

114114
SFOutputStream *sfostream = new SFOutputStream();
115115
out_stream.reset (sfostream);
116-
err = sfostream->open (filename, n_channels, sample_rate, bit_depth, out_format);
116+
err = sfostream->open (filename, n_channels, sample_rate, bit_depth, encoding, out_format);
117117
if (err)
118118
return nullptr;
119119
}

src/audiostream.hh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
#include <memory>
2323
#include "utils.hh"
2424

25+
enum class Encoding {
26+
SIGNED,
27+
UNSIGNED,
28+
FLOAT
29+
};
30+
2531
class AudioStream
2632
{
2733
public:
@@ -40,6 +46,7 @@ public:
4046
// for streams that do not know the number of frames in advance (i.e. raw input stream)
4147
static constexpr size_t N_FRAMES_UNKNOWN = ~size_t (0);
4248
virtual size_t n_frames() const = 0;
49+
virtual Encoding encoding() const = 0;
4350

4451
virtual Error read_frames (std::vector<float>& samples, size_t count) = 0;
4552
};
@@ -48,7 +55,7 @@ class AudioOutputStream : public AudioStream
4855
{
4956
public:
5057
static std::unique_ptr<AudioOutputStream> create (const std::string& filename,
51-
int n_channels, int sample_rate, int bit_depth, size_t n_frames, Error& err);
58+
int n_channels, int sample_rate, int bit_depth, Encoding encoding, size_t n_frames, Error& err);
5259

5360
virtual Error write_frames (const std::vector<float>& frames) = 0;
5461
virtual Error close() = 0;

src/audiowmark.cc

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,39 @@ parse_endian (const string& str)
137137
exit (1);
138138
}
139139

140-
RawFormat::Encoding
141-
parse_encoding (const string& str)
140+
void
141+
parse_encoding (const string& str, RawFormat& fmt)
142142
{
143143
if (str == "signed")
144-
return RawFormat::Encoding::SIGNED;
145-
if (str == "unsigned")
146-
return RawFormat::Encoding::UNSIGNED;
147-
error ("audiowmark: unsupported encoding '%s'\n", str.c_str());
148-
exit (1);
144+
fmt.set_encoding (Encoding::SIGNED);
145+
else if (str == "unsigned")
146+
fmt.set_encoding (Encoding::UNSIGNED);
147+
else if (str == "float")
148+
{
149+
fmt.set_encoding (Encoding::FLOAT);
150+
fmt.set_bit_depth (32);
151+
}
152+
else if (str == "double")
153+
{
154+
fmt.set_encoding (Encoding::FLOAT);
155+
fmt.set_bit_depth (64);
156+
}
157+
else
158+
{
159+
error ("audiowmark: unsupported encoding '%s'\n", str.c_str());
160+
exit (1);
161+
}
162+
}
163+
164+
void
165+
update_raw_bits (RawFormat& fmt, int bits)
166+
{
167+
if (fmt.encoding() == Encoding::FLOAT)
168+
{
169+
error ("audiowmark: bit depth can not be changed for float / double encoding\n");
170+
exit (1);
171+
}
172+
fmt.set_bit_depth (bits);
149173
}
150174

151175
int
@@ -722,19 +746,6 @@ parse_add_options (ArgParser& ap)
722746
{
723747
Params::input_format = Params::output_format = parse_format (s);
724748
}
725-
if (ap.parse_opt ("--raw-input-bits", i))
726-
{
727-
Params::raw_input_format.set_bit_depth (i);
728-
}
729-
if (ap.parse_opt ("--raw-output-bits", i))
730-
{
731-
Params::raw_output_format.set_bit_depth (i);
732-
}
733-
if (ap.parse_opt ("--raw-bits", i))
734-
{
735-
Params::raw_input_format.set_bit_depth (i);
736-
Params::raw_output_format.set_bit_depth (i);
737-
}
738749
if (ap.parse_opt ( "--raw-input-endian", s))
739750
{
740751
auto e = parse_endian (s);
@@ -753,19 +764,29 @@ parse_add_options (ArgParser& ap)
753764
}
754765
if (ap.parse_opt ("--raw-input-encoding", s))
755766
{
756-
auto e = parse_encoding (s);
757-
Params::raw_input_format.set_encoding (e);
767+
parse_encoding (s, Params::raw_input_format);
758768
}
759769
if (ap.parse_opt ("--raw-output-encoding", s))
760770
{
761-
auto e = parse_encoding (s);
762-
Params::raw_output_format.set_encoding (e);
771+
parse_encoding (s, Params::raw_output_format);
763772
}
764773
if (ap.parse_opt ("--raw-encoding", s))
765774
{
766-
auto e = parse_encoding (s);
767-
Params::raw_input_format.set_encoding (e);
768-
Params::raw_output_format.set_encoding (e);
775+
parse_encoding (s, Params::raw_input_format);
776+
parse_encoding (s, Params::raw_output_format);
777+
}
778+
if (ap.parse_opt ("--raw-input-bits", i))
779+
{
780+
update_raw_bits (Params::raw_input_format, i);
781+
}
782+
if (ap.parse_opt ("--raw-output-bits", i))
783+
{
784+
update_raw_bits (Params::raw_output_format, i);
785+
}
786+
if (ap.parse_opt ("--raw-bits", i))
787+
{
788+
update_raw_bits (Params::raw_input_format, i);
789+
update_raw_bits (Params::raw_output_format, i);
769790
}
770791
if (ap.parse_opt ("--raw-channels", i))
771792
{

src/hls.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ hls_prepare (const string& in_dir, const string& out_dir, const string& filename
568568
SFOutputStream out_stream;
569569
err = out_stream.open (&full_flac_mem,
570570
audio_master_data.n_channels(), audio_master_data.sample_rate(), audio_master_data.bit_depth(),
571+
Encoding::SIGNED, /* flac does not support floating point audio */
571572
SFOutputStream::OutFormat::FLAC);
572573
if (err)
573574
{

src/mp3inputstream.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ MP3InputStream::bit_depth() const
181181
return 24; /* mp3 decoder is running on floats */
182182
}
183183

184+
Encoding
185+
MP3InputStream::encoding() const
186+
{
187+
return Encoding::SIGNED; /* should use 24-bit pcm output */
188+
}
189+
184190
int
185191
MP3InputStream::sample_rate() const
186192
{

src/mp3inputstream.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public:
5151
int sample_rate() const override;
5252
int n_channels() const override;
5353
size_t n_frames() const override;
54+
Encoding encoding() const override;
5455

5556
static bool detect (const std::string& filename);
5657
};

0 commit comments

Comments
 (0)