Permalink
Browse files

IO refactoring

  • Loading branch information...
dlevin256 committed Dec 6, 2018
1 parent afd39ce commit 28c6ce8d1f98c198f5403f7139dee5597f8e32da
@@ -44,6 +44,7 @@ build64/
cmake-build-debug/
cmake-build-release/
build-*/
build_*/

# test directory
svg/
@@ -48,6 +48,9 @@ set(KFR_DFT_SRC
${CMAKE_SOURCE_DIR}/include/kfr/dft/impl/dft-impl-f64.cpp
${CMAKE_SOURCE_DIR}/include/kfr/dft/impl/convolution-impl.cpp)

set(KFR_IO_SRC
${CMAKE_SOURCE_DIR}/include/kfr/io/impl/audiofile-impl.cpp)

if (ENABLE_TESTS)

if (IOS)
@@ -98,3 +101,7 @@ target_include_directories(kfr INTERFACE include)

add_library(kfr_dft ${KFR_DFT_SRC})
target_link_libraries(kfr_dft kfr)

add_library(kfr_io ${KFR_IO_SRC})
target_link_libraries(kfr_io kfr)
target_compile_definitions(kfr_io PUBLIC KFR_ENABLE_FLAC=1)
@@ -31,7 +31,7 @@ add_executable(fir fir.cpp)
target_link_libraries(fir kfr)

add_executable(sample_rate_conversion sample_rate_conversion.cpp)
target_link_libraries(sample_rate_conversion kfr)
target_link_libraries(sample_rate_conversion kfr kfr_io)

add_executable(dft dft.cpp)
target_link_libraries(dft kfr kfr_dft)
@@ -30,10 +30,11 @@ int main()
const size_t destsize = r(resampled.data(), swept_sine);

univector<i32> i32data = clamp(resampled.truncate(destsize) * i32max, -i32max, +i32max);
univector2d<i32> data = { i32data };

auto wr = sequential_file_writer("audio_high_quality.wav");
audio_encode(wr, data, audioformat(data, output_sr));
{
audio_writer_wav<i32> writer(open_file_for_writing(KFR_FILEPATH("audio_high_quality.wav")),
audio_format{ 2, audio_sample_type::i32, output_sr });
writer.write(i32data.data(), i32data.size());
}

plot_save("audio_high_quality", "audio_high_quality.wav", "");
}
@@ -45,10 +46,11 @@ int main()
const size_t destsize = r(resampled.data(), swept_sine);

univector<i32> i32data = clamp(resampled.truncate(destsize) * i32max, -i32max, +i32max);
univector2d<i32> data = { i32data };

auto wr = sequential_file_writer("audio_normal_quality.wav");
audio_encode(wr, data, audioformat(data, output_sr));
{
audio_writer_wav<i32> writer(open_file_for_writing(KFR_FILEPATH("audio_normal_quality.wav")),
audio_format{ 2, audio_sample_type::i32, output_sr });
writer.write(i32data.data(), i32data.size());
}

plot_save("audio_normal_quality", "audio_normal_quality.wav", "");
}
@@ -60,10 +62,11 @@ int main()
const size_t destsize = r(resampled.data(), swept_sine);

univector<i32> i32data = clamp(resampled.truncate(destsize) * i32max, -i32max, +i32max);
univector2d<i32> data = { i32data };

auto wr = sequential_file_writer("audio_low_quality.wav");
audio_encode(wr, data, audioformat(data, output_sr));
{
audio_writer_wav<i32> writer(open_file_for_writing(KFR_FILEPATH("audio_low_quality.wav")),
audio_format{ 2, audio_sample_type::i32, output_sr });
writer.write(i32data.data(), i32data.size());
}

plot_save("audio_low_quality", "audio_low_quality.wav", "");
}
@@ -75,10 +78,11 @@ int main()
const size_t destsize = r(resampled.data(), swept_sine);

univector<i32> i32data = clamp(resampled.truncate(destsize) * i32max, -i32max, +i32max);
univector2d<i32> data = { i32data };

auto wr = sequential_file_writer("audio_draft_quality.wav");
audio_encode(wr, data, audioformat(data, output_sr));
{
audio_writer_wav<i32> writer(open_file_for_writing(KFR_FILEPATH("audio_draft_quality.wav")),
audio_format{ 2, audio_sample_type::i32, output_sr });
writer.write(i32data.data(), i32data.size());
}

plot_save("audio_draft_quality", "audio_draft_quality.wav", "");
}
@@ -31,49 +31,137 @@
namespace kfr
{

enum class audio_sample_type
{
unknown,
i8,
i16,
i24,
i32,
i64,
f32,
f64,

first_float = f32
};

inline constexpr size_t audio_sample_sizeof(audio_sample_type type)
{
switch (type)
{
case audio_sample_type::i8:
return 1;
case audio_sample_type::i16:
return 2;
case audio_sample_type::i32:
case audio_sample_type::f32:
return 4;
case audio_sample_type::i64:
case audio_sample_type::f64:
return 8;
default:
return 0;
}
}

inline constexpr size_t audio_sample_bit_depth(audio_sample_type type)
{
return audio_sample_sizeof(type) * 8;
}

using audio_sample_type_clist =
cvals_t<audio_sample_type, audio_sample_type::i8, audio_sample_type::i16, audio_sample_type::i24,
audio_sample_type::i32, audio_sample_type::i64, audio_sample_type::f32, audio_sample_type::f64>;

template <audio_sample_type type>
struct audio_sample_get_type;

template <>
struct audio_sample_get_type<audio_sample_type::i8>
{
using type = i8;
};
template <>
struct audio_sample_get_type<audio_sample_type::i16>
{
using type = i16;
};
template <>
struct audio_sample_get_type<audio_sample_type::i24>
{
using type = i24;
};
template <>
struct audio_sample_get_type<audio_sample_type::i32>
{
using type = i32;
};
template <>
struct audio_sample_get_type<audio_sample_type::i64>
{
using type = i64;
};
template <>
struct audio_sample_get_type<audio_sample_type::f32>
{
using type = f32;
};
template <>
struct audio_sample_get_type<audio_sample_type::f64>
{
using type = f64;
};

template <typename T>
struct audio_sample_traits;

template <>
struct audio_sample_traits<i8>
{
constexpr static f32 scale = 127.f;
constexpr static f32 scale = 127.f;
constexpr static audio_sample_type type = audio_sample_type::i8;
};

template <>
struct audio_sample_traits<i16>
{
constexpr static f32 scale = 32767.f;
constexpr static f32 scale = 32767.f;
constexpr static audio_sample_type type = audio_sample_type::i16;
};

template <>
struct audio_sample_traits<i24>
{
constexpr static f32 scale = 8388607.f;
constexpr static f32 scale = 8388607.f;
constexpr static audio_sample_type type = audio_sample_type::i24;
};

template <>
struct audio_sample_traits<i32>
{
constexpr static f64 scale = 2147483647.0;
constexpr static f64 scale = 2147483647.0;
constexpr static audio_sample_type type = audio_sample_type::i32;
};

template <>
struct audio_sample_traits<i64>
{
constexpr static f64 scale = 9223372036854775807.0;
constexpr static f64 scale = 9223372036854775807.0;
constexpr static audio_sample_type type = audio_sample_type::i64;
};

template <>
struct audio_sample_traits<f32>
{
constexpr static f32 scale = 1;
constexpr static f32 scale = 1;
constexpr static audio_sample_type type = audio_sample_type::f32;
};

template <>
struct audio_sample_traits<f64>
{
constexpr static f64 scale = 1;
constexpr static f64 scale = 1;
constexpr static audio_sample_type type = audio_sample_type::f64;
};

template <typename Tout, typename Tin, typename Tout_traits = audio_sample_traits<Tout>,
@@ -122,4 +210,22 @@ void convert(Tout* out, const Tin* in, size_t size)
out[i] = convert_sample<Tout, Tin, Tout_traits, Tin_traits>(in[i]);
}
}

template <typename Tout, typename Tout_traits = audio_sample_traits<Tout>>
void convert(Tout* out, const void* in, audio_sample_type in_type, size_t size)
{
cswitch(audio_sample_type_clist{}, in_type, [&](auto t) {
using type = typename audio_sample_get_type<val_of(t)>::type;
convert(out, reinterpret_cast<const type*>(in), size);
});
}

template <typename Tin, typename Tin_traits = audio_sample_traits<Tin>>
void convert(void* out, audio_sample_type out_type, const Tin* in, size_t size)
{
cswitch(audio_sample_type_clist{}, out_type, [&](auto t) {
using type = typename audio_sample_get_type<val_of(t)>::type;
convert(reinterpret_cast<type*>(out), in, size);
});
}
} // namespace kfr
Oops, something went wrong.

0 comments on commit 28c6ce8

Please sign in to comment.