Skip to content

Commit

Permalink
sndfile_source detects file extensions and no longer segfaults, sndfi…
Browse files Browse the repository at this point in the history
…le_sink needs info set
  • Loading branch information
Hrick87 committed Dec 4, 2023
1 parent ddc2169 commit 5a3caa6
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,49 @@
namespace roc {
namespace sndio {

namespace{

const char* drivers[] = {
"wav",
"aiff",
"aifc",
"au",
"snd",
"paf",
"sf",
"voc",
"w64",
"mat",
"pvf",
"xi",
"htk",
"caf",
"sd2",
"flac"
};

const char * detect_file_extension(const char* path){
const char *dot = strrchr(path, '.');
if(!dot || dot == path){
return NULL;
}
roc_log(LogInfo, "detected file format type `%s'", dot + 1);
return dot + 1;
}

bool check_file_extension_support(const char* file_extension){
for(size_t sndfile_extension = 0; sndfile_extension < ROC_ARRAY_SIZE(drivers); sndfile_extension++){
if(strcmp(drivers[sndfile_extension], file_extension) == 0){

return true;
}
}

return false;
}

}

SndfileBackend::SndfileBackend() : first_created_(false) {

roc_log(LogDebug, "sndfile backend: initializing");
Expand All @@ -33,6 +76,7 @@ void SndfileBackend::discover_drivers(core::Array<DriverInfo, MaxDrivers>& drive
}

const char* driver = format_info.extension;
printf("Extension: %s\nName: %s\n", driver, format_info.name);
if (!driver_list.push_back(DriverInfo(driver, DriverType_File,
DriverFlag_IsDefault
| DriverFlag_SupportsSource
Expand All @@ -49,12 +93,22 @@ IDevice * SndfileBackend::open_device(DeviceType device_type,
const char* path,
const Config& config,
core::IArena& arena){
if(driver_type != DriverType_File)
{

if(driver_type != DriverType_File){
roc_log(LogDebug, "sndfile backend: driver=%s is not a file type", driver);
return NULL;
}

if(!driver && path){
if(!(driver = detect_file_extension(path))){
roc_panic("sndfile backend: file format could not be detected");
}
}

if(!check_file_extension_support(driver)){
roc_panic("sndfile backend: file format is not supported");
}

first_created_ = true;

switch (device_type) {
Expand Down Expand Up @@ -98,6 +152,7 @@ IDevice * SndfileBackend::open_device(DeviceType device_type,

roc_panic("sndfile backend: invalid device type");
}

}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,6 @@ void SndfileSink::write(audio::Frame& frame) {
int32_t* buffer_data = buffer_.data();
size_t buffer_pos = 0;



while (frame_size > 0) {
for (; buffer_pos < buffer_size_ && frame_size > 0; buffer_pos++) {
buffer_data[buffer_pos] = (int32_t)frame_data[buffer_pos]; //??
Expand Down Expand Up @@ -188,7 +186,8 @@ bool SndfileSink::setup_buffer_() {

bool SndfileSink::open_(const char* driver, const char* path) {

if(!sf_format_check (&sf_info_out_))
//TODO: Implement sf_info_out_ data retrieval to pass this check
if(!sf_format_check(&sf_info_out_))
{
roc_panic("sndfile sink: Invalid encoding");
}
Expand All @@ -213,7 +212,7 @@ bool SndfileSink::open_(const char* driver, const char* path) {
void SndfileSink::write_(const int32_t * samples, size_t n_samples) {

if (n_samples > 0) {
if (sf_writef_int(sndfile_output_, samples, (sf_count_t)n_samples) != (sf_count_t)n_samples) {
if (sf_write_int(sndfile_output_, samples, (sf_count_t)n_samples) != (sf_count_t)n_samples) {
roc_log(LogError, "sndfile sink: failed to write output buffer");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,42 @@

namespace roc {
namespace sndio {
namespace {

struct {
const char * format_cstring;
int format_enum;
} file_type_map[]={
{"aiff", SF_FORMAT_AIFF},
{"au", SF_FORMAT_AU},
{"avr", SF_FORMAT_AVR},
{"caf", SF_FORMAT_CAF},
{"htk", SF_FORMAT_HTK},
{"iff", SF_FORMAT_SVX},
{"mat", SF_FORMAT_MAT4},
{"mat", SF_FORMAT_MAT5},
{"mpc", SF_FORMAT_MPC2K},
{"paf", SF_FORMAT_PAF},
{"pvf", SF_FORMAT_PVF},
{"raw", SF_FORMAT_RAW},
{"rf64", SF_FORMAT_RF64},
{"sd2", SF_FORMAT_SD2},
{"sds", SF_FORMAT_SDS},
{"sf", SF_FORMAT_IRCAM},
{"voc", SF_FORMAT_VOC},
{"w64", SF_FORMAT_W64},
{"wav", SF_FORMAT_WAV},
{"wav", SF_FORMAT_NIST},
{"wav", SF_FORMAT_WAVEX},
{"wve", SF_FORMAT_WVE},
{"svx", SF_FORMAT_SVX},
{"sv", SF_FORMAT_SVX},
{"xi", SF_FORMAT_XI},

{"ogg", SF_FORMAT_OGG},
{"flac", SF_FORMAT_FLAC},
};
}

SndfileSource::SndfileSource(core::IArena& arena, const Config& config)
: driver_name_(arena)
Expand Down Expand Up @@ -45,7 +81,7 @@ SndfileSource::SndfileSource(core::IArena& arena, const Config& config)
}

memset(&sf_info_in_, 0, sizeof(sf_info_in_));

valid_ = true;
}

Expand Down Expand Up @@ -246,8 +282,8 @@ bool SndfileSource::read(audio::Frame& frame) {
n_samples = buffer_size_;
}

n_samples = (size_t)sf_readf_int(sndfile_input_, buffer_data, (sf_count_t)n_samples); //Does not return less than 0 so casting is safe

n_samples = (size_t)sf_read_int(sndfile_input_, buffer_data, (sf_count_t)n_samples); //Does not return less than 0 so casting is safe
if (n_samples == 0) {
roc_log(LogDebug, "sndfile source: got eof from sndfile");
eof_ = true;
Expand Down Expand Up @@ -328,11 +364,21 @@ bool SndfileSource::setup_buffer_() {
return true;
}

int SndfileSource::map_to_sndfile_(){
for(size_t format_struct_index = 0; format_struct_index < sizeof(file_type_map) / sizeof(file_type_map[0]); format_struct_index++){
if(strcmp(file_type_map[format_struct_index].format_cstring, driver_name_.c_str()) == 0){
return file_type_map[format_struct_index].format_enum;
}
}

roc_panic("sndfile source: Cannot map driver name to sndfile format");
}

bool SndfileSource::open_() {
if (sndfile_input_) {
roc_panic("sndfile source: already opened");
}

sndfile_input_ =
sf_open(input_name_.is_empty() ? NULL : input_name_.c_str(), SFM_READ, &sf_info_in_);
if (!sndfile_input_) {
Expand All @@ -349,12 +395,16 @@ bool SndfileSource::open_() {
(unsigned long)sf_info_in_.channels);
return false;
}


sf_info_in_.format = map_to_sndfile_();

sample_spec_.set_sample_rate((unsigned long)sf_info_in_.samplerate);

roc_log(LogInfo,
"sndfile source:"
" in_bits=%lu in_rate=%lu "
" format=%d in_rate=%lu "
" in_ch=%lu is_file=%d",
(unsigned long)sf_info_in_.format,
sf_info_in_.format,
(unsigned long)sf_info_in_.samplerate,
(unsigned long)sf_info_in_.channels, (int)is_file_);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class SndfileSource : public ISource, private core::NonCopyable<> {
bool setup_names_(const char* driver, const char* path);
bool setup_buffer_();

int map_to_sndfile_();
bool open_();
void close_();

Expand Down

0 comments on commit 5a3caa6

Please sign in to comment.