Commit 14c6f9f0 authored by Stefan Westerfeld's avatar Stefan Westerfeld

Support writing output to memory with SFOutputStream.

Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parent 8f189696
...@@ -169,7 +169,7 @@ SFInputStream::close() ...@@ -169,7 +169,7 @@ SFInputStream::close()
static sf_count_t static sf_count_t
virtual_get_len (void *data) virtual_get_len (void *data)
{ {
SFInputStream::VirtualData *vdata = static_cast<SFInputStream::VirtualData *> (data); SFVirtualData *vdata = static_cast<SFVirtualData *> (data);
return vdata->mem->size(); return vdata->mem->size();
} }
...@@ -177,7 +177,7 @@ virtual_get_len (void *data) ...@@ -177,7 +177,7 @@ virtual_get_len (void *data)
static sf_count_t static sf_count_t
virtual_seek (sf_count_t offset, int whence, void *data) virtual_seek (sf_count_t offset, int whence, void *data)
{ {
SFInputStream::VirtualData *vdata = static_cast<SFInputStream::VirtualData *> (data); SFVirtualData *vdata = static_cast<SFVirtualData *> (data);
if (whence == SEEK_CUR) if (whence == SEEK_CUR)
{ {
...@@ -200,7 +200,7 @@ virtual_seek (sf_count_t offset, int whence, void *data) ...@@ -200,7 +200,7 @@ virtual_seek (sf_count_t offset, int whence, void *data)
static sf_count_t static sf_count_t
virtual_read (void *ptr, sf_count_t count, void *data) virtual_read (void *ptr, sf_count_t count, void *data)
{ {
SFInputStream::VirtualData *vdata = static_cast<SFInputStream::VirtualData *> (data); SFVirtualData *vdata = static_cast<SFVirtualData *> (data);
int rcount = 0; int rcount = 0;
if (size_t (vdata->offset + count) <= vdata->mem->size()) if (size_t (vdata->offset + count) <= vdata->mem->size())
...@@ -229,7 +229,7 @@ virtual_read (void *ptr, sf_count_t count, void *data) ...@@ -229,7 +229,7 @@ virtual_read (void *ptr, sf_count_t count, void *data)
static sf_count_t static sf_count_t
virtual_write (const void *ptr, sf_count_t count, void *data) virtual_write (const void *ptr, sf_count_t count, void *data)
{ {
SFInputStream::VirtualData *vdata = static_cast<SFInputStream::VirtualData *> (data); SFVirtualData *vdata = static_cast<SFVirtualData *> (data);
const unsigned char *uptr = static_cast<const unsigned char *> (ptr); const unsigned char *uptr = static_cast<const unsigned char *> (ptr);
for (sf_count_t i = 0; i < count; i++) for (sf_count_t i = 0; i < count; i++)
...@@ -248,22 +248,26 @@ virtual_write (const void *ptr, sf_count_t count, void *data) ...@@ -248,22 +248,26 @@ virtual_write (const void *ptr, sf_count_t count, void *data)
static sf_count_t static sf_count_t
virtual_tell (void *data) virtual_tell (void *data)
{ {
SFInputStream::VirtualData *vdata = static_cast<SFInputStream::VirtualData *> (data); SFVirtualData *vdata = static_cast<SFVirtualData *> (data);
return vdata->offset; return vdata->offset;
} }
Error SFVirtualData::SFVirtualData() :
SFInputStream::open (const vector<unsigned char> *data) io {
{
virtual_data.mem = const_cast<vector<unsigned char> *> (data);
SF_VIRTUAL_IO sf_virtual_io = {
virtual_get_len, virtual_get_len,
virtual_seek, virtual_seek,
virtual_read, virtual_read,
virtual_write, virtual_write,
virtual_tell virtual_tell
}; }
{
}
Error
SFInputStream::open (const vector<unsigned char> *data)
{
m_virtual_data.mem = const_cast<vector<unsigned char> *> (data);
return open ([&] (SF_INFO *sfinfo) { return open ([&] (SF_INFO *sfinfo) {
return sf_open_virtual (&sf_virtual_io, SFM_READ, sfinfo, &virtual_data); return sf_open_virtual (&m_virtual_data.io, SFM_READ, sfinfo, &m_virtual_data);
}); });
} }
...@@ -25,18 +25,21 @@ ...@@ -25,18 +25,21 @@
#include "audiostream.hh" #include "audiostream.hh"
class SFInputStream : public AudioInputStream /* to support virtual io read/write from/to memory */
struct SFVirtualData
{ {
public: SFVirtualData();
/* to support read from memory */
struct VirtualData
{
std::vector<unsigned char> *mem = nullptr; std::vector<unsigned char> *mem = nullptr;
sf_count_t offset = 0; sf_count_t offset = 0;
}; SF_VIRTUAL_IO io;
};
class SFInputStream : public AudioInputStream
{
private: private:
VirtualData virtual_data; SFVirtualData m_virtual_data;
SNDFILE *m_sndfile = nullptr; SNDFILE *m_sndfile = nullptr;
int m_n_channels = 0; int m_n_channels = 0;
int m_n_values = 0; int m_n_values = 0;
......
...@@ -31,6 +31,14 @@ SFOutputStream::~SFOutputStream() ...@@ -31,6 +31,14 @@ SFOutputStream::~SFOutputStream()
Error Error
SFOutputStream::open (const string& filename, int n_channels, int sample_rate, int bit_depth, size_t n_frames) SFOutputStream::open (const string& filename, int n_channels, int sample_rate, int bit_depth, size_t n_frames)
{
return open ([&] (SF_INFO *sfinfo) {
return sf_open (filename.c_str(), SFM_WRITE, sfinfo);
}, n_channels, sample_rate, bit_depth, n_frames);
}
Error
SFOutputStream::open (std::function<SNDFILE* (SF_INFO *)> open_func, int n_channels, int sample_rate, int bit_depth, size_t n_frames)
{ {
assert (m_state == State::NEW); assert (m_state == State::NEW);
...@@ -52,7 +60,7 @@ SFOutputStream::open (const string& filename, int n_channels, int sample_rate, i ...@@ -52,7 +60,7 @@ SFOutputStream::open (const string& filename, int n_channels, int sample_rate, i
m_bit_depth = 16; m_bit_depth = 16;
} }
m_sndfile = sf_open (filename.c_str(), SFM_WRITE, &sfinfo); m_sndfile = open_func (&sfinfo);
int error = sf_error (m_sndfile); int error = sf_error (m_sndfile);
if (error) if (error)
{ {
...@@ -122,3 +130,13 @@ SFOutputStream::n_channels() const ...@@ -122,3 +130,13 @@ SFOutputStream::n_channels() const
{ {
return m_n_channels; return m_n_channels;
} }
Error
SFOutputStream::open (vector<unsigned char> *data, int n_channels, int sample_rate, int bit_depth, size_t n_frames)
{
m_virtual_data.mem = data;
return open ([&] (SF_INFO *sfinfo) {
return sf_open_virtual (&m_virtual_data.io, SFM_WRITE, sfinfo, &m_virtual_data);
}, n_channels, sample_rate, bit_depth, n_frames);
}
...@@ -23,9 +23,12 @@ ...@@ -23,9 +23,12 @@
#include <sndfile.h> #include <sndfile.h>
#include "audiostream.hh" #include "audiostream.hh"
#include "sfinputstream.hh"
class SFOutputStream : public AudioOutputStream class SFOutputStream : public AudioOutputStream
{ {
SFVirtualData m_virtual_data;
SNDFILE *m_sndfile = nullptr; SNDFILE *m_sndfile = nullptr;
int m_bit_depth = 0; int m_bit_depth = 0;
int m_sample_rate = 0; int m_sample_rate = 0;
...@@ -38,10 +41,12 @@ class SFOutputStream : public AudioOutputStream ...@@ -38,10 +41,12 @@ class SFOutputStream : public AudioOutputStream
}; };
State m_state = State::NEW; State m_state = State::NEW;
Error open (std::function<SNDFILE* (SF_INFO *)> open_func, int n_channels, int sample_rate, int bit_depth, size_t n_frames);
public: public:
~SFOutputStream(); ~SFOutputStream();
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 open (std::vector<unsigned char> *data, 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;
Error close() override; Error close() override;
int bit_depth() 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