Skip to content

Commit

Permalink
Sndfile min. 1.0.26, extension_table def in cpp, sndfile_backend remo…
Browse files Browse the repository at this point in the history
…ve conditions, TODO's added, split up map function
  • Loading branch information
Hrick87 committed Mar 4, 2024
1 parent e454729 commit f1b544c
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 67 deletions.
4 changes: 2 additions & 2 deletions 3rdparty/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ thirdparty_versions = {
'openfec': '1.4.2.7',
'openssl': '3.0.8',
'pulseaudio': '12.2',
'sndfile': '1.0.25',
'sndfile': '1.0.26',
'sox': '14.4.2',
'speexdsp': '1.2.0',

Expand Down Expand Up @@ -252,7 +252,7 @@ elif 'sndfile' in system_dependencies:
if not is_crosscompiling:
if not conf.CheckLibWithHeaderExt(
'sndfile', 'sndfile.h', 'C'):
env.Die("libsndfile >= 1.0.25 not found (see 'config.log' for details)")
env.Die("libsndfile >= 1.0.26 not found (see 'config.log' for details)")
else:
if not conf.CheckLibWithHeaderExt('sndfile', 'sndfile.h', 'C', run=False):
env.Die("libsndfile not found (see 'config.log' for details)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,10 @@ void SndfileBackend::discover_drivers(core::Array<DriverInfo, MaxDrivers>& drive

const char* driver = format_info.extension;

if ((strcmp(format_info.extension, "wav") == 0)
|| (strcmp(format_info.extension, "mat") == 0)) {
for (size_t map_index = 0; map_index < ROC_ARRAY_SIZE(file_type_map);
map_index++) {
if (file_type_map[map_index].format_id == format_info.format) {
driver = file_type_map[map_index].driver_name;
}
for (size_t map_index = 0; map_index < ROC_ARRAY_SIZE(file_type_map);
map_index++) {
if (file_type_map[map_index].format_id == format_info.format) {
driver = file_type_map[map_index].driver_name;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2024 Roc Streaming authors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "sndfile_extension_table.h"
#include "sndfile.h"

FileMap file_type_map[5] = { { SF_FORMAT_MAT4, "mat4", NULL },
{ SF_FORMAT_MAT5, "mat5", NULL },
{ SF_FORMAT_WAV, "wav", "wav" },
{ SF_FORMAT_NIST, "nist", NULL },
{ SF_FORMAT_WAVEX, "wavex", NULL } };
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@
*/

//! @file roc_sndio/target_sndfile/roc_sndio/sndfile_extension_table.h
//! @brief TODO.
//! @brief Sndfile driver map.

#ifndef ROC_SNDIO_SNDFILE_EXTENSION_TABLE_H_
#define ROC_SNDIO_SNDFILE_EXTENSION_TABLE_H_

#pragma once
#include "sndfile.h"

//! Sndfile driver map.
struct FileMap {
//! SF_FORMAT ID corresponding to the enum value in sndfile.h
Expand All @@ -24,10 +21,8 @@ struct FileMap {
//! File extension associated with driver and SF_FORMAT if it exists.
const char* file_extension;
};
static FileMap file_type_map[5] = { { SF_FORMAT_MAT4, "mat4", NULL },
{ SF_FORMAT_MAT5, "mat5", NULL },
{ SF_FORMAT_WAV, "wav", "wav" },
{ SF_FORMAT_NIST, "nist", NULL },
{ SF_FORMAT_WAVEX, "wavex", NULL } };

//! Declare the file_type_map as extern
extern FileMap file_type_map[5];

#endif // ROC_SNDIO_SNDFILE_EXTENSION_TABLE_H_
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#define FORMAT_COUNT 2 // Number of major formats that don't allow for 32 bits;
#define BUFFER_SIZE 512

#include "roc_sndio/sndfile_sink.h"
Expand All @@ -19,7 +18,25 @@ namespace roc {
namespace sndio {
namespace {

bool map_to_sndfile(const char** driver, const char* path, SF_INFO& sfinfo) {
bool map_to_sub_format(SF_INFO& file_info_, int format_enum) {
// Provides the minimum number of sub formats needed to support all possible major
// formats
int high_to_low_sub_formats[4] = { SF_FORMAT_PCM_24, SF_FORMAT_PCM_16,
SF_FORMAT_DPCM_16 };

for (size_t format_attempt = 0;
format_attempt < ROC_ARRAY_SIZE(high_to_low_sub_formats); format_attempt++) {
file_info_.format = format_enum | high_to_low_sub_formats[format_attempt];

if (sf_format_check(&file_info_)) {
return true;
}
}

return false;
}

bool map_to_sndfile(const char** driver, const char* path, SF_INFO& file_info_) {
const char* file_extension;
const char* dot = strrchr(path, '.');

Expand Down Expand Up @@ -91,38 +108,13 @@ bool map_to_sndfile(const char** driver, const char* path, SF_INFO& sfinfo) {

roc_log(LogDebug, "detected file format type `%s'", *driver);

sfinfo.format = format_enum | sfinfo.format;
file_info_.format = format_enum | file_info_.format;

if (sf_format_check(&sfinfo)) {
if (sf_format_check(&file_info_)) {
return true;
} else {
return map_to_sub_format(file_info_, format_enum);
}

int temp_format = 0;

for (int format_attempt = 0; format_attempt < FORMAT_COUNT; format_attempt++) {
if (format_enum == SF_FORMAT_XI) {
sfinfo.channels = 1;
if (format_attempt == 0) {
temp_format = format_enum | SF_FORMAT_DPCM_16;
} else {
temp_format = format_enum | SF_FORMAT_DPCM_8;
}
} else {
if (format_attempt == 0) {
temp_format = format_enum | SF_FORMAT_PCM_24;
} else {
temp_format = format_enum | SF_FORMAT_PCM_16;
}
}

sfinfo.format = temp_format;

if (sf_format_check(&sfinfo)) {
return true;
}
}

return false;
}

} // namespace
Expand All @@ -142,24 +134,36 @@ SndfileSink::SndfileSink(core::IArena& arena, const Config& config)
}

frame_length_ = config.frame_length;
sample_spec_ = config.sample_spec;

if (frame_length_ == 0) {
roc_log(LogError, "sndfile sink: frame length is zero");
return;
}

memset(&file_info_, 0, sizeof(file_info_));
// file_info_.format = (int)config.sample_spec.pcm_format(); this needs to be
// converted to corresponding enum of sndfile somehow
file_info_.format = SF_FORMAT_PCM_32;
file_info_.channels = (int)config.sample_spec.num_channels();
file_info_.samplerate = (int)config.sample_spec.sample_rate();
sample_spec_ = config.sample_spec;

if (sample_spec_.sample_format() == audio::SampleFormat_Invalid) {
sample_spec_.set_sample_format(audio::SampleFormat_Pcm);
sample_spec_.set_pcm_format(audio::PcmFormat_SInt32);
}

if (sample_spec_.sample_rate() == 0) {
sample_spec_.set_sample_rate(41000);
}

if (file_info_.samplerate == 0) {
file_info_.samplerate = 48000;
if (!sample_spec_.channel_set().is_valid()) {
sample_spec_.channel_set().set_layout(audio::ChanLayout_Surround);
sample_spec_.channel_set().set_order(audio::ChanOrder_Smpte);
sample_spec_.channel_set().set_channel_range(0, 2, true);
}

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

// TODO(gh-696): map format from sample_space
file_info_.format = SF_FORMAT_PCM_32;
file_info_.channels = (int)sample_spec_.num_channels();
file_info_.samplerate = (int)sample_spec_.sample_rate();

valid_ = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,24 +181,23 @@ bool SndfileSource::read(audio::Frame& frame) {
}

audio::sample_t* frame_data = frame.raw_samples();
size_t num_channels = (size_t)file_info_.channels;
// size_t num_channels = (size_t)file_info_.channels;
sf_count_t frame_left = (sf_count_t)frame.num_raw_samples();
size_t samples_per_ch = frame.num_raw_samples() / num_channels;
// size_t samples_per_ch = frame.num_raw_samples() / num_channels;

sf_count_t n_samples = sf_read_float(file_, frame_data, frame_left);
if (sf_error(file_) != 0) {
// TODO(gh-183): return error instead of panic
roc_panic("sndfile source: sf_read_float() failed: %s", sf_strerror(file_));
}

if (n_samples < frame_left) {
if (n_samples == 0) {
eof_ = true;
}

if ((size_t)n_samples < samples_per_ch) {
memset(frame.raw_samples() + (size_t)n_samples * num_channels, 0,
(samples_per_ch - (size_t)n_samples) * num_channels
* sizeof(audio::sample_t));
if (n_samples < frame_left && n_samples != 0) {
memset(frame.raw_samples() + (size_t)n_samples, 0,
(size_t)(frame_left - n_samples) * sizeof(audio::sample_t));
}

return !eof_;
Expand Down
2 changes: 1 addition & 1 deletion src/tests/roc_sndio/test_backend_sink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ TEST_GROUP(backend_sink) {
}
};

TEST(backend_sink, noop) {
TEST(backend_sink, write_open) {
for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends();
n_backend++) {
IBackend& backend = BackendMap::instance().nth_backend(n_backend);
Expand Down
2 changes: 1 addition & 1 deletion src/tests/roc_sndio/test_backend_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ TEST_GROUP(backend_source) {
}
};

TEST(backend_source, noop) {
TEST(backend_source, read_open) {
for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends();
n_backend++) {
core::TempFile file("test.wav");
Expand Down

0 comments on commit f1b544c

Please sign in to comment.