Commit 45e64803 authored by Stefan Westerfeld's avatar Stefan Westerfeld

Improved error handling. Handle errors during output stream close.

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent fa259ba4
...@@ -28,6 +28,7 @@ class AudioOutputStream : public AudioStream ...@@ -28,6 +28,7 @@ class AudioOutputStream : public AudioStream
{ {
public: public:
virtual Error write_frames (const std::vector<float>& frames) = 0; virtual Error write_frames (const std::vector<float>& frames) = 0;
virtual Error close() = 0;
}; };
#endif /* AUDIOWMARK_AUDIO_STREAM_HH */ #endif /* AUDIOWMARK_AUDIO_STREAM_HH */
...@@ -74,22 +74,34 @@ RawOutputStream::write_frames (const vector<float>& samples) ...@@ -74,22 +74,34 @@ RawOutputStream::write_frames (const vector<float>& samples)
m_raw_converter->to_raw (samples, bytes); m_raw_converter->to_raw (samples, bytes);
fwrite (&bytes[0], 1, bytes.size(), m_output_file); fwrite (&bytes[0], 1, bytes.size(), m_output_file);
if (ferror (m_output_file))
return Error ("write sample data failed");
return Error::Code::NONE; return Error::Code::NONE;
} }
void Error
RawOutputStream::close() RawOutputStream::close()
{ {
if (m_state == State::OPEN) if (m_state == State::OPEN)
{ {
if (m_output_file)
{
fflush (m_output_file);
if (ferror (m_output_file))
return Error ("error during flush");
}
if (m_close_file && m_output_file) if (m_close_file && m_output_file)
{ {
fclose (m_output_file); if (fclose (m_output_file) != 0)
return Error ("error during close");
m_output_file = nullptr; m_output_file = nullptr;
m_close_file = false; m_close_file = false;
} }
m_state = State::CLOSED; m_state = State::CLOSED;
} }
return Error::Code::NONE;
} }
...@@ -28,7 +28,7 @@ public: ...@@ -28,7 +28,7 @@ public:
Error open (const std::string& filename, const RawFormat& format); Error open (const std::string& filename, const RawFormat& format);
Error write_frames (const std::vector<float>& frames) override; Error write_frames (const std::vector<float>& frames) override;
void close(); Error close();
}; };
#endif /* AUDIOWMARK_RAW_OUTPUT_STREAM_HH */ #endif /* AUDIOWMARK_RAW_OUTPUT_STREAM_HH */
...@@ -49,16 +49,18 @@ SFOutputStream::open (const string& filename, int n_channels, int sample_rate, i ...@@ -49,16 +49,18 @@ SFOutputStream::open (const string& filename, int n_channels, int sample_rate, i
return Error::Code::NONE; return Error::Code::NONE;
} }
void Error
SFOutputStream::close() SFOutputStream::close()
{ {
if (m_state == State::OPEN) if (m_state == State::OPEN)
{ {
assert (m_sndfile); assert (m_sndfile);
sf_close (m_sndfile); if (sf_close (m_sndfile))
return Error ("sf_close returned an error");
m_state = State::CLOSED; m_state = State::CLOSED;
} }
return Error::Code::NONE;
} }
Error Error
......
...@@ -26,7 +26,7 @@ public: ...@@ -26,7 +26,7 @@ public:
Error open (const std::string& filename, int n_channels, int sample_rate, int bit_depth, size_t n_frames); Error open (const std::string& filename, int n_channels, int sample_rate, int bit_depth, size_t n_frames);
Error write_frames (const std::vector<float>& frames) override; Error write_frames (const std::vector<float>& frames) override;
void close(); Error close() override;
int bit_depth() const override; int bit_depth() const override;
int sample_rate() const override; int sample_rate() const override;
int n_channels() const override; int n_channels() const override;
......
...@@ -101,6 +101,8 @@ StdoutWavOutputStream::open (int n_channels, int sample_rate, int bit_depth, siz ...@@ -101,6 +101,8 @@ StdoutWavOutputStream::open (int n_channels, int sample_rate, int bit_depth, siz
header_append_u32 (header_bytes, data_size); header_append_u32 (header_bytes, data_size);
fwrite (&header_bytes[0], 1, header_bytes.size(), stdout); fwrite (&header_bytes[0], 1, header_bytes.size(), stdout);
if (ferror (stdout))
return Error ("write wav header failed");
m_bit_depth = bit_depth; m_bit_depth = bit_depth;
m_sample_rate = sample_rate; m_sample_rate = sample_rate;
...@@ -118,19 +120,28 @@ StdoutWavOutputStream::write_frames (const vector<float>& samples) ...@@ -118,19 +120,28 @@ StdoutWavOutputStream::write_frames (const vector<float>& samples)
m_raw_converter->to_raw (samples, output_bytes); m_raw_converter->to_raw (samples, output_bytes);
fwrite (&output_bytes[0], 1, output_bytes.size(), stdout); fwrite (&output_bytes[0], 1, output_bytes.size(), stdout);
if (ferror (stdout))
return Error ("write sample data failed");
return Error::Code::NONE; return Error::Code::NONE;
} }
void Error
StdoutWavOutputStream::close() StdoutWavOutputStream::close()
{ {
if (m_state == State::OPEN) if (m_state == State::OPEN)
{ {
for (size_t i = 0; i < m_close_padding; i++) for (size_t i = 0; i < m_close_padding; i++)
fputc (0, stdout); {
fputc (0, stdout);
if (ferror (stdout))
return Error ("write wav padding failed");
}
fflush (stdout);
if (ferror (stdout))
return Error ("error during flush");
m_state = State::CLOSED; m_state = State::CLOSED;
} }
return Error::Code::NONE;
} }
...@@ -28,7 +28,7 @@ public: ...@@ -28,7 +28,7 @@ public:
Error open (int n_channels, int sample_rate, int bit_depth, size_t n_frames); Error open (int n_channels, int sample_rate, int bit_depth, size_t n_frames);
Error write_frames (const std::vector<float>& frames) override; Error write_frames (const std::vector<float>& frames) override;
void close(); Error close();
int sample_rate() const override; int sample_rate() const override;
int bit_depth() const override; int bit_depth() const override;
int n_channels() const override; int n_channels() const override;
......
...@@ -718,6 +718,11 @@ add_watermark (const string& infile, const string& outfile, const string& bits) ...@@ -718,6 +718,11 @@ add_watermark (const string& infile, const string& outfile, const string& bits)
total_output_frames += samples.size() / n_channels; total_output_frames += samples.size() / n_channels;
} }
fprintf (stderr, "total output: %zd, expected: %zd\n", total_output_frames, in_stream->n_frames()); fprintf (stderr, "total output: %zd, expected: %zd\n", total_output_frames, in_stream->n_frames());
Error err = out_stream->close();
if (err)
error ("audiowmark: closing output stream failed: %s\n", err.message());
#if 0 #if 0
if (Params::snr) if (Params::snr)
{ {
......
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