Commit 4fb31ea3 authored by Stefan Westerfeld's avatar Stefan Westerfeld

Newly generated watermarks can be written to files again.

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent 35b5e8be
bin_PROGRAMS = audiowmark
COMMON_SRC = utils.hh utils.cc convcode.hh convcode.cc random.hh random.cc mp3.cc mp3.hh wavdata.cc wavdata.hh \
audiostream.cc audiostream.hh sfinputstream.cc sfinputstream.hh stdoutwavoutputstream.cc stdoutwavoutputstream.hh
audiostream.cc audiostream.hh sfinputstream.cc sfinputstream.hh stdoutwavoutputstream.cc stdoutwavoutputstream.hh \
sfoutputstream.cc sfoutputstream.hh
COMMON_LIBS = $(SNDFILE_LIBS) $(FFTW_LIBS) $(LIBGCRYPT_LIBS) $(LIBMPG123_LIBS)
audiowmark_SOURCES = audiowmark.cc fft.cc fft.hh $(COMMON_SRC)
......
......@@ -20,6 +20,8 @@ class AudioInputStream : public AudioStream
class AudioOutputStream : public AudioStream
{
public:
virtual bool write_frames (const std::vector<float>& frames) = 0;
};
#endif /* AUDIOWMARK_AUDIO_STREAM_HH */
......@@ -12,6 +12,7 @@
#include "convcode.hh"
#include "random.hh"
#include "sfinputstream.hh"
#include "sfoutputstream.hh"
#include "stdoutwavoutputstream.hh"
#include <zita-resampler/resampler.h>
......@@ -710,12 +711,26 @@ add_watermark (const string& infile, const string& outfile, const string& bits)
bool open (int n_channels, int sample_rate, int bit_depth, size_t n_frames);
const int out_bit_depth = in_stream->bit_depth() > 16 ? 24 : 16;
auto out_stream = std::make_unique <StdoutWavOutputStream>();
if (!out_stream->open (in_stream->n_channels(), in_stream->sample_rate(), out_bit_depth, in_stream->n_frames()))
std::unique_ptr<AudioOutputStream> out_stream;
if (outfile == "-")
{
fprintf (stderr, "audiowmark: error writing to -\n"); //%s: %s\n", outfile.c_str(), out_wav_data.error_blurb()); FIXME
return 1;
StdoutWavOutputStream *swstream = new StdoutWavOutputStream();
out_stream.reset (swstream);
if (!swstream->open (in_stream->n_channels(), in_stream->sample_rate(), out_bit_depth, in_stream->n_frames()))
{
fprintf (stderr, "audiowmark: error writing to -\n"); //%s: %s\n", outfile.c_str(), out_wav_data.error_blurb()); FIXME
return 1;
}
}
else
{
SFOutputStream *sfostream = new SFOutputStream();
out_stream.reset (sfostream);
if (!sfostream->open (outfile, in_stream->n_channels(), in_stream->sample_rate(), out_bit_depth, in_stream->n_frames()))
{
error ("audiowmark: error writing to %s\n", outfile.c_str()); // FIXME, sfostream->error_blurb());
return 1;
}
}
enum State { PAD, SYNC, DATA } state = State::PAD;
int frame_bound = Params::frames_pad_start;
......
......@@ -114,5 +114,3 @@ SFInputStream::close()
m_state = State::CLOSED;
}
}
#include "sfoutputstream.hh"
#include "utils.hh"
#include <math.h>
#include <assert.h>
using std::string;
using std::vector;
SFOutputStream::~SFOutputStream()
{
close();
}
bool
SFOutputStream::open (const string& filename, int n_channels, int sample_rate, int bit_depth, size_t n_frames)
{
assert (m_state == State::NEW);
m_sample_rate = sample_rate;
m_n_frames = n_frames;
m_n_channels = n_channels;
SF_INFO sfinfo = {0,};
sfinfo.samplerate = sample_rate;
sfinfo.channels = n_channels;
if (bit_depth > 16)
{
sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_24;
m_bit_depth = 24;
}
else
{
sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
m_bit_depth = 16;
}
m_sndfile = sf_open (filename.c_str(), SFM_WRITE, &sfinfo);
int error = sf_error (m_sndfile);
if (error)
{
m_error_blurb = sf_strerror (m_sndfile);
if (m_sndfile)
sf_close (m_sndfile);
return false;
}
m_state = State::OPEN;
return true;
}
void
SFOutputStream::close()
{
if (m_state == State::OPEN)
{
assert (m_sndfile);
sf_close (m_sndfile);
m_state = State::CLOSED;
}
}
bool
SFOutputStream::write_frames (const vector<float>& samples)
{
vector<int> isamples (samples.size());
for (size_t i = 0; i < samples.size(); i++)
{
const double norm = 0x80000000LL;
const double min_value = -0x80000000LL;
const double max_value = 0x7FFFFFFF;
isamples[i] = lrint (bound<double> (min_value, samples[i] * norm, max_value));
}
sf_count_t frames = samples.size() / m_n_channels;
sf_count_t count = sf_writef_int (m_sndfile, &isamples[0], frames);
int error = sf_error (m_sndfile);
if (error)
{
m_error_blurb = sf_strerror (m_sndfile);
return false;
}
if (count != frames)
{
m_error_blurb = "writing sample data failed: short write";
return false;
}
return true;
}
int
SFOutputStream::bit_depth() const
{
return m_bit_depth;
}
int
SFOutputStream::sample_rate() const
{
return m_sample_rate;
}
size_t
SFOutputStream::n_frames() const
{
return m_n_frames;
}
#ifndef AUDIOWMARK_SF_OUTPUT_STREAM_HH
#define AUDIOWMARK_SF_OUTPUT_STREAM_HH
#include <string>
#include <sndfile.h>
#include "audiostream.hh"
class SFOutputStream : public AudioOutputStream
{
SNDFILE *m_sndfile = nullptr;
std::string m_error_blurb;
int m_bit_depth = 0;
int m_sample_rate = 0;
size_t m_n_frames = 0;
int m_n_channels = 0;
enum class State {
NEW,
OPEN,
CLOSED
};
State m_state = State::NEW;
public:
~SFOutputStream();
bool open (const std::string& filename, int n_channels, int sample_rate, int bit_depth, size_t n_frames);
bool write_frames (const std::vector<float>& frames) override;
void close();
int bit_depth() const override;
int sample_rate() const override;
size_t n_frames() const override;
};
#endif /* AUDIOWMARK_SF_OUTPUT_STREAM_HH */
......@@ -24,7 +24,7 @@ public:
~StdoutWavOutputStream();
bool open (int n_channels, int sample_rate, int bit_depth, size_t n_frames);
bool write_frames (const std::vector<float>& frames);
bool write_frames (const std::vector<float>& frames) override;
void close();
int sample_rate() const override;
int bit_depth() const override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment