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()
static sf_count_t
virtual_get_len (void *data)
{
SFInputStream::VirtualData *vdata = static_cast<SFInputStream::VirtualData *> (data);
SFVirtualData *vdata = static_cast<SFVirtualData *> (data);
return vdata->mem->size();
}
......@@ -177,7 +177,7 @@ virtual_get_len (void *data)
static sf_count_t
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)
{
......@@ -200,7 +200,7 @@ virtual_seek (sf_count_t offset, int whence, void *data)
static sf_count_t
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;
if (size_t (vdata->offset + count) <= vdata->mem->size())
......@@ -229,7 +229,7 @@ virtual_read (void *ptr, sf_count_t count, void *data)
static sf_count_t
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);
for (sf_count_t i = 0; i < count; i++)
......@@ -248,22 +248,26 @@ virtual_write (const void *ptr, sf_count_t count, void *data)
static sf_count_t
virtual_tell (void *data)
{
SFInputStream::VirtualData *vdata = static_cast<SFInputStream::VirtualData *> (data);
SFVirtualData *vdata = static_cast<SFVirtualData *> (data);
return vdata->offset;
}
Error
SFInputStream::open (const vector<unsigned char> *data)
{
virtual_data.mem = const_cast<vector<unsigned char> *> (data);
SF_VIRTUAL_IO sf_virtual_io = {
SFVirtualData::SFVirtualData() :
io {
virtual_get_len,
virtual_seek,
virtual_read,
virtual_write,
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 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 @@
#include "audiostream.hh"
class SFInputStream : public AudioInputStream
/* to support virtual io read/write from/to memory */
struct SFVirtualData
{
public:
/* to support read from memory */
struct VirtualData
{
std::vector<unsigned char> *mem = nullptr;
sf_count_t offset = 0;
};
SFVirtualData();
std::vector<unsigned char> *mem = nullptr;
sf_count_t offset = 0;
SF_VIRTUAL_IO io;
};
class SFInputStream : public AudioInputStream
{
private:
VirtualData virtual_data;
SFVirtualData m_virtual_data;
SNDFILE *m_sndfile = nullptr;
int m_n_channels = 0;
int m_n_values = 0;
......
......@@ -31,6 +31,14 @@ SFOutputStream::~SFOutputStream()
Error
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);
......@@ -52,7 +60,7 @@ SFOutputStream::open (const string& filename, int n_channels, int sample_rate, i
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);
if (error)
{
......@@ -122,3 +130,13 @@ SFOutputStream::n_channels() const
{
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 @@
#include <sndfile.h>
#include "audiostream.hh"
#include "sfinputstream.hh"
class SFOutputStream : public AudioOutputStream
{
SFVirtualData m_virtual_data;
SNDFILE *m_sndfile = nullptr;
int m_bit_depth = 0;
int m_sample_rate = 0;
......@@ -38,10 +41,12 @@ class SFOutputStream : public AudioOutputStream
};
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:
~SFOutputStream();
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 close() 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