From f75044cb03a3d9561655edd9d957f7d83f48bdf4 Mon Sep 17 00:00:00 2001 From: aikiriao Date: Sat, 28 Jan 2023 18:13:48 +0900 Subject: [PATCH] initial commit for SRLA. --- .editorconfig | 16 + .gitignore | 7 + CMakeLists.txt | 46 + COPYING | 21 + README.md | 45 + cmake/gtest.cmake | 51 + evaluation/codec_comparison_summery.csv | 19 + evaluation/codec_comparison_summery_sse41.csv | 19 + include/srla.h | 49 + include/srla_decoder.h | 55 + include/srla_encoder.h | 63 + include/srla_stdint.h | 11 + libs/CMakeLists.txt | 11 + libs/bit_stream/CMakeLists.txt | 37 + libs/bit_stream/include/bit_stream.h | 446 +++++ libs/bit_stream/src/CMakeLists.txt | 4 + libs/bit_stream/src/bit_stream.c | 388 +++++ libs/byte_array/CMakeLists.txt | 16 + libs/byte_array/include/byte_array.h | 210 +++ libs/command_line_parser/CMakeLists.txt | 33 + .../include/command_line_parser.h | 61 + libs/command_line_parser/src/CMakeLists.txt | 4 + .../src/command_line_parser.c | 331 ++++ libs/lpc/CMakeLists.txt | 37 + libs/lpc/include/lpc.h | 118 ++ libs/lpc/src/CMakeLists.txt | 4 + libs/lpc/src/lpc.c | 1440 +++++++++++++++++ libs/srla_coder/CMakeLists.txt | 39 + libs/srla_coder/include/srla_coder.h | 33 + libs/srla_coder/src/CMakeLists.txt | 4 + libs/srla_coder/src/srla_coder.c | 586 +++++++ libs/srla_decoder/CMakeLists.txt | 42 + libs/srla_decoder/src/CMakeLists.txt | 6 + libs/srla_decoder/src/srla_decoder.c | 714 ++++++++ libs/srla_decoder/src/srla_lpc_synthesize.c | 128 ++ libs/srla_decoder/src/srla_lpc_synthesize.h | 18 + libs/srla_encoder/CMakeLists.txt | 42 + libs/srla_encoder/src/CMakeLists.txt | 6 + libs/srla_encoder/src/srla_encoder.c | 1025 ++++++++++++ libs/srla_encoder/src/srla_lpc_predict.c | 30 + libs/srla_encoder/src/srla_lpc_predict.h | 19 + libs/srla_internal/CMakeLists.txt | 37 + libs/srla_internal/include/srla_internal.h | 102 ++ libs/srla_internal/include/srla_utility.h | 148 ++ libs/srla_internal/src/CMakeLists.txt | 5 + libs/srla_internal/src/srla_internal.c | 21 + libs/srla_internal/src/srla_utility.c | 268 +++ libs/wav/CMakeLists.txt | 33 + libs/wav/include/wav.h | 66 + libs/wav/src/CMakeLists.txt | 4 + libs/wav/src/wav.c | 990 ++++++++++++ test/CMakeLists.txt | 12 + test/bit_stream/CMakeLists.txt | 35 + test/bit_stream/bit_stream_common_test.cpp | 228 +++ test/bit_stream/bit_stream_function_test.cpp | 44 + test/bit_stream/bit_stream_macro_test.cpp | 6 + test/bit_stream/main.cpp | 7 + test/byte_array/CMakeLists.txt | 35 + test/byte_array/main.cpp | 360 +++++ test/command_line_parser/CMakeLists.txt | 35 + test/command_line_parser/main.cpp | 587 +++++++ test/lpc/CMakeLists.txt | 35 + test/lpc/main.cpp | 229 +++ test/srla_coder/CMakeLists.txt | 45 + test/srla_coder/PriChanIcon.png | Bin 0 -> 214955 bytes test/srla_coder/main.cpp | 314 ++++ test/srla_decoder/CMakeLists.txt | 39 + test/srla_decoder/main.cpp | 7 + test/srla_decoder/srla_decoder_test.cpp | 537 ++++++ .../srla_decoder/srla_lpc_synthesize_test.cpp | 4 + test/srla_encode_decode/CMakeLists.txt | 37 + test/srla_encode_decode/main.cpp | 532 ++++++ test/srla_encoder/CMakeLists.txt | 39 + test/srla_encoder/main.cpp | 7 + test/srla_encoder/srla_encoder_test.cpp | 430 +++++ test/srla_encoder/srla_lpc_predict_test.cpp | 4 + test/srla_internal/CMakeLists.txt | 46 + test/srla_internal/PriChanIcon.png | Bin 0 -> 544324 bytes test/srla_internal/a.wav | Bin 0 -> 240044 bytes test/srla_internal/main.cpp | 81 + test/wav/16bit.wav | Bin 0 -> 88244 bytes test/wav/16bit_2ch.wav | Bin 0 -> 176444 bytes test/wav/24bit.wav | Bin 0 -> 132344 bytes test/wav/24bit_2ch.wav | Bin 0 -> 264644 bytes test/wav/32bit.wav | Bin 0 -> 176444 bytes test/wav/32bit_2ch.wav | Bin 0 -> 352844 bytes test/wav/8bit.wav | Bin 0 -> 44144 bytes test/wav/8bit_2ch.wav | Bin 0 -> 88244 bytes test/wav/CMakeLists.txt | 46 + test/wav/a.wav | Bin 0 -> 240044 bytes test/wav/main.cpp | 246 +++ tools/sfla_codec/CMakeLists.txt | 46 + tools/sfla_codec/sfla_codec.c | 359 ++++ tools/sfla_player/CMakeLists.txt | 54 + tools/sfla_player/sfla_player.c | 161 ++ tools/sfla_player/sfla_player.h | 32 + tools/sfla_player/sfla_player_coreaudio.c | 127 ++ tools/sfla_player/sfla_player_pulseaudio.c | 108 ++ tools/sfla_player/sfla_player_wasapi.c | 179 ++ 99 files changed, 13001 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 README.md create mode 100644 cmake/gtest.cmake create mode 100644 evaluation/codec_comparison_summery.csv create mode 100644 evaluation/codec_comparison_summery_sse41.csv create mode 100644 include/srla.h create mode 100644 include/srla_decoder.h create mode 100644 include/srla_encoder.h create mode 100644 include/srla_stdint.h create mode 100644 libs/CMakeLists.txt create mode 100644 libs/bit_stream/CMakeLists.txt create mode 100644 libs/bit_stream/include/bit_stream.h create mode 100644 libs/bit_stream/src/CMakeLists.txt create mode 100644 libs/bit_stream/src/bit_stream.c create mode 100644 libs/byte_array/CMakeLists.txt create mode 100644 libs/byte_array/include/byte_array.h create mode 100644 libs/command_line_parser/CMakeLists.txt create mode 100644 libs/command_line_parser/include/command_line_parser.h create mode 100644 libs/command_line_parser/src/CMakeLists.txt create mode 100644 libs/command_line_parser/src/command_line_parser.c create mode 100644 libs/lpc/CMakeLists.txt create mode 100644 libs/lpc/include/lpc.h create mode 100644 libs/lpc/src/CMakeLists.txt create mode 100644 libs/lpc/src/lpc.c create mode 100644 libs/srla_coder/CMakeLists.txt create mode 100644 libs/srla_coder/include/srla_coder.h create mode 100644 libs/srla_coder/src/CMakeLists.txt create mode 100644 libs/srla_coder/src/srla_coder.c create mode 100644 libs/srla_decoder/CMakeLists.txt create mode 100644 libs/srla_decoder/src/CMakeLists.txt create mode 100644 libs/srla_decoder/src/srla_decoder.c create mode 100644 libs/srla_decoder/src/srla_lpc_synthesize.c create mode 100644 libs/srla_decoder/src/srla_lpc_synthesize.h create mode 100644 libs/srla_encoder/CMakeLists.txt create mode 100644 libs/srla_encoder/src/CMakeLists.txt create mode 100644 libs/srla_encoder/src/srla_encoder.c create mode 100644 libs/srla_encoder/src/srla_lpc_predict.c create mode 100644 libs/srla_encoder/src/srla_lpc_predict.h create mode 100644 libs/srla_internal/CMakeLists.txt create mode 100644 libs/srla_internal/include/srla_internal.h create mode 100644 libs/srla_internal/include/srla_utility.h create mode 100644 libs/srla_internal/src/CMakeLists.txt create mode 100644 libs/srla_internal/src/srla_internal.c create mode 100644 libs/srla_internal/src/srla_utility.c create mode 100644 libs/wav/CMakeLists.txt create mode 100644 libs/wav/include/wav.h create mode 100644 libs/wav/src/CMakeLists.txt create mode 100644 libs/wav/src/wav.c create mode 100644 test/CMakeLists.txt create mode 100644 test/bit_stream/CMakeLists.txt create mode 100644 test/bit_stream/bit_stream_common_test.cpp create mode 100644 test/bit_stream/bit_stream_function_test.cpp create mode 100644 test/bit_stream/bit_stream_macro_test.cpp create mode 100644 test/bit_stream/main.cpp create mode 100644 test/byte_array/CMakeLists.txt create mode 100644 test/byte_array/main.cpp create mode 100644 test/command_line_parser/CMakeLists.txt create mode 100644 test/command_line_parser/main.cpp create mode 100644 test/lpc/CMakeLists.txt create mode 100644 test/lpc/main.cpp create mode 100644 test/srla_coder/CMakeLists.txt create mode 100644 test/srla_coder/PriChanIcon.png create mode 100644 test/srla_coder/main.cpp create mode 100644 test/srla_decoder/CMakeLists.txt create mode 100644 test/srla_decoder/main.cpp create mode 100644 test/srla_decoder/srla_decoder_test.cpp create mode 100644 test/srla_decoder/srla_lpc_synthesize_test.cpp create mode 100644 test/srla_encode_decode/CMakeLists.txt create mode 100644 test/srla_encode_decode/main.cpp create mode 100644 test/srla_encoder/CMakeLists.txt create mode 100644 test/srla_encoder/main.cpp create mode 100644 test/srla_encoder/srla_encoder_test.cpp create mode 100644 test/srla_encoder/srla_lpc_predict_test.cpp create mode 100644 test/srla_internal/CMakeLists.txt create mode 100644 test/srla_internal/PriChanIcon.png create mode 100644 test/srla_internal/a.wav create mode 100644 test/srla_internal/main.cpp create mode 100644 test/wav/16bit.wav create mode 100644 test/wav/16bit_2ch.wav create mode 100644 test/wav/24bit.wav create mode 100644 test/wav/24bit_2ch.wav create mode 100644 test/wav/32bit.wav create mode 100644 test/wav/32bit_2ch.wav create mode 100644 test/wav/8bit.wav create mode 100644 test/wav/8bit_2ch.wav create mode 100644 test/wav/CMakeLists.txt create mode 100644 test/wav/a.wav create mode 100644 test/wav/main.cpp create mode 100644 tools/sfla_codec/CMakeLists.txt create mode 100644 tools/sfla_codec/sfla_codec.c create mode 100644 tools/sfla_player/CMakeLists.txt create mode 100644 tools/sfla_player/sfla_player.c create mode 100644 tools/sfla_player/sfla_player.h create mode 100644 tools/sfla_player/sfla_player_coreaudio.c create mode 100644 tools/sfla_player/sfla_player_pulseaudio.c create mode 100644 tools/sfla_player/sfla_player_wasapi.c diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ea78f75 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.yml] +indent_size = 2 +trim_trailing_whitespace = false + +[*.rb] +indent_size = 2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e464b40 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +build +tmp +data +*.o +*.swp +*.swo +*~ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c7aaeef --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.15) + +# コーデックライブラリ +project(SRLACodecLibrary C) +set(CODEC_LIB_NAME srlacodec) +add_library(${CODEC_LIB_NAME} + STATIC + $ + $ + $ + $ + $ + $ + ) + +# デコーダライブラリ +project(SRLADecoderLibrary C) +set(DECODER_LIB_NAME srladec) +add_library(${DECODER_LIB_NAME} + STATIC + $ + $ + $ + $ + ) + +# 依存するプロジェクト +add_subdirectory(libs) + +# テスト +if(NOT without-test) + enable_testing() + # C++環境でないとgtestがビルドできないので、CXXプロジェクトを作る + # -> Cとの挙動で差異が生じるかもしれない... + project(SRLATest CXX) + if(MSVC) + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + else() + set(CMAKE_CXX_FLAGS "-std=gnu++11") # gtestがGNU独自拡張を使用しているため + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -DDEBUG") + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") + endif() + include(cmake/gtest.cmake) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) + add_subdirectory(test) +endif() diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..4b06cc4 --- /dev/null +++ b/COPYING @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 aikiriao + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e85bfd1 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# SRLA + +aka Soleil Rising Lossless Audio codec + +# How to build + +## Requirement + +* [CMake](https://cmake.org) >= 3.15 + +## Build SRLA Codec + +```bash +git clone https://github.com/ShounoLab/SRLA.git +cd SRLA/tools/srla_codec +cmake -B build +cmake --build build +``` + +# Usage + +## SRLA Codec + +### Encode + +```bash +./srla -e INPUT.wav OUTPUT.srl +``` + +you can change compression mode by `-m` option. +Following example encoding in maximum compression (but slow) option. + +```bash +./srla -e -m 5 INPUT.wav OUTPUT.srl +``` + +### Decode + +```bash +./srla -d INPUT.srl OUTPUT.wav +``` + +## License + +MIT diff --git a/cmake/gtest.cmake b/cmake/gtest.cmake new file mode 100644 index 0000000..f4cd178 --- /dev/null +++ b/cmake/gtest.cmake @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.15) + +# Google Test settings +include(ExternalProject) + +# gtest追加 +ExternalProject_Add(GoogleTest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG release-1.12.0 + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + ) + +# インクルードパス追加 +ExternalProject_Get_Property(GoogleTest source_dir) +include_directories(${source_dir}/googletest/include) + +# 成果物のディレクトリ取得 +ExternalProject_Get_Property(GoogleTest binary_dir) + +# ライブラリ追加 +add_library(gtest STATIC IMPORTED) +if(MSVC) + set_target_properties(gtest + PROPERTIES + IMPORTED_LOCATION "${binary_dir}/lib/Debug/gtest.lib" + IMPORTED_LOCATION_DEBUG "${binary_dir}/lib/Debug/gtest.lib" + IMPORTED_LOCATION_RELEASE "${binary_dir}/lib/Release/gtest.lib" + ) +else() + set_target_properties(gtest + PROPERTIES + IMPORTED_LOCATION ${binary_dir}/lib/libgtest.a + ) +endif() + +# メインエントリ追加 +add_library(gtest_main STATIC IMPORTED) +if(MSVC) + set_target_properties(gtest_main + PROPERTIES + IMPORTED_LOCATION "${binary_dir}/lib/Debug/gtest_main.lib" + IMPORTED_LOCATION_DEBUG "${binary_dir}/lib/Debug/gtest_main.lib" + IMPORTED_LOCATION_RELEASE "${binary_dir}/lib/Release/gtest_main.lib" + ) +else() + set_target_properties(gtest_main + PROPERTIES + IMPORTED_LOCATION ${binary_dir}/lib/libgtest_main.a + ) +endif() diff --git a/evaluation/codec_comparison_summery.csv b/evaluation/codec_comparison_summery.csv new file mode 100644 index 0000000..cc315d9 --- /dev/null +++ b/evaluation/codec_comparison_summery.csv @@ -0,0 +1,19 @@ +,SFLA -m 0,SFLA -m 1,SFLA -m 2,SFLA -m 3,SFLA -m 4,SFLA -m 5 +classic mean encode time,2.1463422375623296,10.07418304959943,1.9410030808785546,8.168703015165022,4.3587425386216365,9.224339659192657 +genre mean encode time,2.12240976190562,9.805849101835305,2.0300083861255915,8.048654987900365,4.000971228283839,8.903252905958409 +jazz mean encode time,2.0901955034801376,10.233647398591351,2.0885893799250352,7.59833719809332,4.047462738277384,9.084297794282588 +popular mean encode time,2.1062993339775824,9.244210549952072,2.073766501603843,8.228736590277194,4.097600123214178,11.380466953318077 +right mean encode time,2.151912552638434,8.792490786101663,2.072541237903354,7.527640951489073,4.104422125150039,9.849197809848953 +total mean encode time,2.115843248752311,9.708067239300949,2.045844317304964,7.978871838339197,4.106302094538328,9.816523363852014 +classic mean decode time,0.23532411995210242,0.24146054144651874,0.18582631588974155,0.18499188976473074,0.1870066425538413,0.19813029993712092 +genre mean decode time,0.23754737758750252,0.2290321044232394,0.1965400700104293,0.18355494589056645,0.18623609007395378,0.18703174084555974 +jazz mean decode time,0.2310707603696749,0.22479188782559598,0.20146217343942385,0.19309912088540826,0.19099264815075956,0.1848804252351176 +popular mean decode time,0.2389101940810997,0.21725211364323724,0.20352851668634508,0.1972963818041787,0.20378588269988956,0.1858582672682349 +right mean decode time,0.24353698084874226,0.21764401628896637,0.2045213652897606,0.19755539783229734,0.21591995601500277,0.19682529757174275 +total mean decode time,0.23649355144538797,0.22564734279752893,0.19866716739334367,0.1912114554595751,0.1949207886774234,0.18865063312297645 +classic mean compression rate,43.94922828916623,43.94465295981446,43.85064224764169,43.84544940647651,43.846626459795914,43.84130142245651 +genre mean compression rate,58.406170090094484,58.35404773195658,58.318265983580794,58.26165970999139,58.30614357904465,58.25151775676188 +jazz mean compression rate,47.93229431056631,47.87342167392149,47.827005209736136,47.76487209475472,47.81897521735741,47.759679420383236 +popular mean compression rate,67.83985786295364,67.77027270365582,67.76775650884096,67.69427274648717,67.75300388322596,67.68276755961523 +right mean compression rate,60.85819586164452,60.806215550493555,60.768906383799134,60.714754945215724,60.75667699000537,60.70506580834179 +total mean compression rate,56.63037195657916,56.57902493722776,56.541321689295316,56.48674564261108,56.53066993209297,56.478361055202626 diff --git a/evaluation/codec_comparison_summery_sse41.csv b/evaluation/codec_comparison_summery_sse41.csv new file mode 100644 index 0000000..c8b05eb --- /dev/null +++ b/evaluation/codec_comparison_summery_sse41.csv @@ -0,0 +1,19 @@ +,SFLA -m 0,SFLA -m 1,SFLA -m 2,SFLA -m 3,SFLA -m 4,SFLA -m 5 +classic mean encode time,1.853644518349601,9.033031663315231,1.9307104294040605,6.774597894822078,3.771602566031967,8.52801475610579 +genre mean encode time,1.8938096272300136,9.380883281063456,1.9619670765323722,6.804070612250814,3.759008462857397,8.591708777157196 +jazz mean encode time,1.8868362771708331,9.543943597586129,1.9369440208780122,6.789060641169558,3.7530082732126586,8.611576517030251 +popular mean encode time,1.9083161670041597,9.28966216323793,1.9433015347541789,7.178663163399555,3.803710867246452,8.738973062562122 +right mean encode time,1.911434825229543,8.939300392415419,1.9494931226247207,6.885123601205838,3.8300126380047117,8.747879459326832 +total mean encode time,1.891338135811271,9.304410133917198,1.9444524662598615,6.915147139081168,3.7782227118327882,8.641923302163663 +classic mean decode time,0.16280584641137985,0.17383497498923337,0.161880264897766,0.16271098867523728,0.16140331657731016,0.16097628480396278 +genre mean decode time,0.16874013178574807,0.17292584458932456,0.16505980603675505,0.1630915347196641,0.1644649594814271,0.16233090020728527 +jazz mean decode time,0.16927131369020393,0.17662810854192657,0.16299880741136044,0.1616782013793746,0.1610726422144156,0.16376791265650223 +popular mean decode time,0.17225964085808726,0.1761409472513793,0.16542970807898155,0.17004469355453866,0.1643255223900824,0.16423267325594415 +right mean decode time,0.1741159126920204,0.17134420686599539,0.17055075810779607,0.1689573280641753,0.17340951382687358,0.17215079964422333 +total mean decode time,0.16935946205455407,0.1748124115833936,0.1645616244337823,0.16522131591907002,0.1637613226058114,0.1637280834557029 +classic mean compression rate,43.94922828916623,43.94465295981446,43.85064224764169,43.84544940647651,43.846626459795914,43.84130142245651 +genre mean compression rate,58.406170090094484,58.35404773195658,58.318265983580794,58.26165970999139,58.30614357904465,58.25151775676188 +jazz mean compression rate,47.93229431056631,47.87342167392149,47.827005209736136,47.76487209475472,47.81897521735741,47.759679420383236 +popular mean compression rate,67.83985786295364,67.77027270365582,67.76775650884096,67.69427274648717,67.75300388322596,67.68276755961523 +right mean compression rate,60.85819586164452,60.806215550493555,60.768906383799134,60.714754945215724,60.75667699000537,60.70506580834179 +total mean compression rate,56.63037195657916,56.57902493722776,56.541321689295316,56.48674564261108,56.53066993209297,56.478361055202626 diff --git a/include/srla.h b/include/srla.h new file mode 100644 index 0000000..6885e14 --- /dev/null +++ b/include/srla.h @@ -0,0 +1,49 @@ +#ifndef SRLA_H_INCLUDED +#define SRLA_H_INCLUDED + +#include "srla_stdint.h" + +/* フォーマットバージョン */ +#define SRLA_FORMAT_VERSION 1 + +/* コーデックバージョン */ +#define SRLA_CODEC_VERSION 1 + +/* ヘッダサイズ */ +#define SRLA_HEADER_SIZE 29 + +/* 処理可能な最大チャンネル数 */ +#define SRLA_MAX_NUM_CHANNELS 8 + +/* 最大係数サイズ */ +#define SRLA_MAX_COEFFICIENT_ORDER 32 + +/* パラメータプリセット数 */ +#define SRLA_NUM_PARAMETER_PRESETS 6 + + +/* API結果型 */ +typedef enum SRLAApiResultTag { + SRLA_APIRESULT_OK = 0, /* 成功 */ + SRLA_APIRESULT_INVALID_ARGUMENT, /* 無効な引数 */ + SRLA_APIRESULT_INVALID_FORMAT, /* 不正なフォーマット */ + SRLA_APIRESULT_INSUFFICIENT_BUFFER, /* バッファサイズが足りない */ + SRLA_APIRESULT_INSUFFICIENT_DATA, /* データが足りない */ + SRLA_APIRESULT_PARAMETER_NOT_SET, /* パラメータがセットされてない */ + SRLA_APIRESULT_DETECT_DATA_CORRUPTION, /* データ破損を検知した */ + SRLA_APIRESULT_NG /* 分類不能な失敗 */ +} SRLAApiResult; + +/* ヘッダ情報 */ +struct SRLAHeader { + uint32_t format_version; /* フォーマットバージョン */ + uint32_t codec_version; /* エンコーダバージョン */ + uint16_t num_channels; /* チャンネル数 */ + uint32_t num_samples; /* 1チャンネルあたり総サンプル数 */ + uint32_t sampling_rate; /* サンプリングレート */ + uint16_t bits_per_sample; /* サンプルあたりビット数 */ + uint32_t num_samples_per_block; /* ブロックあたりサンプル数 */ + uint8_t preset; /* パラメータプリセット */ +}; + +#endif /* SRLA_H_INCLUDED */ diff --git a/include/srla_decoder.h b/include/srla_decoder.h new file mode 100644 index 0000000..fcf59fb --- /dev/null +++ b/include/srla_decoder.h @@ -0,0 +1,55 @@ +#ifndef SRLA_DECODER_H_INCLUDED +#define SRLA_DECODER_H_INCLUDED + +#include "srla.h" +#include "srla_stdint.h" + +/* デコーダコンフィグ */ +struct SRLADecoderConfig { + uint32_t max_num_channels; /* 最大チャンネル数 */ + uint32_t max_num_parameters; /* 最大パラメータ数 */ + uint8_t check_checksum; /* チェックサムによるデータ破損検査を行うか? 1:ON それ以外:OFF */ +}; + +/* デコーダハンドル */ +struct SRLADecoder; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* ヘッダデコード */ +SRLAApiResult SRLADecoder_DecodeHeader( + const uint8_t *data, uint32_t data_size, struct SRLAHeader *header); + +/* デコーダハンドルの作成に必要なワークサイズの計算 */ +int32_t SRLADecoder_CalculateWorkSize(const struct SRLADecoderConfig *condig); + +/* デコーダハンドルの作成 */ +struct SRLADecoder* SRLADecoder_Create(const struct SRLADecoderConfig *condig, void *work, int32_t work_size); + +/* デコーダハンドルの破棄 */ +void SRLADecoder_Destroy(struct SRLADecoder *decoder); + +/* デコーダにヘッダをセット */ +SRLAApiResult SRLADecoder_SetHeader( + struct SRLADecoder *decoder, const struct SRLAHeader *header); + +/* 単一データブロックデコード */ +SRLAApiResult SRLADecoder_DecodeBlock( + struct SRLADecoder *decoder, + const uint8_t *data, uint32_t data_size, + int32_t **buffer, uint32_t buffer_num_channels, uint32_t buffer_num_samples, + uint32_t *decode_size, uint32_t *num_decode_samples); + +/* ヘッダを含めて全ブロックデコード */ +SRLAApiResult SRLADecoder_DecodeWhole( + struct SRLADecoder *decoder, + const uint8_t *data, uint32_t data_size, + int32_t **buffer, uint32_t buffer_num_channels, uint32_t buffer_num_samples); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SRLA_DECODER_H_INCLUDED */ diff --git a/include/srla_encoder.h b/include/srla_encoder.h new file mode 100644 index 0000000..e273503 --- /dev/null +++ b/include/srla_encoder.h @@ -0,0 +1,63 @@ +#ifndef SRLA_ENCODER_H_INCLUDED +#define SRLA_ENCODER_H_INCLUDED + +#include "srla.h" +#include "srla_stdint.h" + +/* エンコードパラメータ */ +struct SRLAEncodeParameter { + uint16_t num_channels; /* 入力波形のチャンネル数 */ + uint16_t bits_per_sample; /* 入力波形のサンプルあたりビット数 */ + uint32_t sampling_rate; /* 入力波形のサンプリングレート */ + uint32_t num_samples_per_block; /* ブロックあたりサンプル数 */ + uint8_t preset; /* エンコードパラメータプリセット */ +}; + +/* エンコーダコンフィグ */ +struct SRLAEncoderConfig { + uint32_t max_num_channels; /* 最大チャンネル数 */ + uint32_t max_num_samples_per_block; /* 最大のブロックあたりサンプル数 */ + uint32_t max_num_parameters; /* 最大のパラメータ数 */ +}; + +/* エンコーダハンドル */ +struct SRLAEncoder; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* ヘッダエンコード */ +SRLAApiResult SRLAEncoder_EncodeHeader( + const struct SRLAHeader *header, uint8_t *data, uint32_t data_size); + +/* エンコーダハンドル作成に必要なワークサイズ計算 */ +int32_t SRLAEncoder_CalculateWorkSize(const struct SRLAEncoderConfig *config); + +/* エンコーダハンドル作成 */ +struct SRLAEncoder *SRLAEncoder_Create(const struct SRLAEncoderConfig *config, void *work, int32_t work_size); + +/* エンコーダハンドルの破棄 */ +void SRLAEncoder_Destroy(struct SRLAEncoder *encoder); + +/* エンコードパラメータの設定 */ +SRLAApiResult SRLAEncoder_SetEncodeParameter( + struct SRLAEncoder *encoder, const struct SRLAEncodeParameter *parameter); + +/* 単一データブロックエンコード */ +SRLAApiResult SRLAEncoder_EncodeBlock( + struct SRLAEncoder *encoder, + const int32_t *const *input, uint32_t num_samples, + uint8_t *data, uint32_t data_size, uint32_t *output_size); + +/* ヘッダ含めファイル全体をエンコード */ +SRLAApiResult SRLAEncoder_EncodeWhole( + struct SRLAEncoder *encoder, + const int32_t *const *input, uint32_t num_samples, + uint8_t *data, uint32_t data_size, uint32_t *output_size); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SRLA_ENCODER_H_INCLUDED */ diff --git a/include/srla_stdint.h b/include/srla_stdint.h new file mode 100644 index 0000000..0f56c41 --- /dev/null +++ b/include/srla_stdint.h @@ -0,0 +1,11 @@ +#ifndef SRLA_STDINT_H_INCLUDED +#define SRLA_STDINT_H_INCLUDED + +/* stdint.hが無い環境向けに +* stdint.h相当の型定義を行う */ + +/* 現在のところは必ずstdint.hを使用する */ +/* 困った場合に定義を追加する */ +#include + +#endif /* SRLA_STDINT_H_INCLUDED */ diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt new file mode 100644 index 0000000..7b369dc --- /dev/null +++ b/libs/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.15) + +add_subdirectory(bit_stream) +add_subdirectory(byte_array) +add_subdirectory(command_line_parser) +add_subdirectory(srla_coder) +add_subdirectory(srla_decoder) +add_subdirectory(srla_encoder) +add_subdirectory(srla_internal) +add_subdirectory(lpc) +add_subdirectory(wav) diff --git a/libs/bit_stream/CMakeLists.txt b/libs/bit_stream/CMakeLists.txt new file mode 100644 index 0000000..a430e09 --- /dev/null +++ b/libs/bit_stream/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# プロジェクト名 +project(BitStream C) + +# ライブラリ名 +set(LIB_NAME bit_stream) + +# 静的ライブラリ指定 +add_library(${LIB_NAME} STATIC) + +# ソースディレクトリ +add_subdirectory(src) + +# インクルードパス +target_include_directories(${LIB_NAME} + PRIVATE + ${PROJECT_ROOT_PATH}/include + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + +# コンパイルオプション +if(MSVC) + target_compile_options(${LIB_NAME} PRIVATE /W4) +else() + target_compile_options(${LIB_NAME} PRIVATE -Wall -Wextra -Wpedantic -Wformat=2 -Wstrict-aliasing=2 -Wconversion -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition) + set(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -DDEBUG") + set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") +endif() +set_target_properties(${LIB_NAME} + PROPERTIES + C_STANDARD 90 C_EXTENSIONS OFF + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) diff --git a/libs/bit_stream/include/bit_stream.h b/libs/bit_stream/include/bit_stream.h new file mode 100644 index 0000000..75a3ca6 --- /dev/null +++ b/libs/bit_stream/include/bit_stream.h @@ -0,0 +1,446 @@ +#ifndef BITSTREAM_H_INCLUDED +#define BITSTREAM_H_INCLUDED + +#include +#include +#include +#include + +#if CHAR_BIT != 8 +#error "This program 8bit/byte system only." +#endif + +/* マクロを使うか否か? */ +#define BITSTREAM_USE_MACROS 1 + +/* BitStream_Seek関数の探索コード */ +#define BITSTREAM_SEEK_SET (int32_t)SEEK_SET +#define BITSTREAM_SEEK_CUR (int32_t)SEEK_CUR +#define BITSTREAM_SEEK_END (int32_t)SEEK_END + +/* 読みモードか?(0で書きモード) */ +#define BITSTREAM_FLAGS_MODE_READ (1 << 0) + +/* valの下位nbitsを取得 */ +#define BITSTREAM_GETLOWERBITS(val, nbits) ((val) & g_bitstream_lower_bits_mask[(nbits)]) + +/* ビットストリーム構造体 */ +struct BitStream { + uint32_t bit_buffer; /* ビットの一時バッファ */ + uint32_t bit_count; /* [Reader]バッファ残りビット数, [Writer]メモリ書き出しまでのビット数 */ + const uint8_t *memory_image; /* メモリ領域先頭 */ + const uint8_t *memory_tail;/* メモリ領域末尾 */ + size_t memory_size; /* メモリ領域サイズ */ + uint8_t *memory_p; /* メモリ読み書き位置 */ + uint8_t flags; /* 内部状態フラグ */ +}; + +/* NLZ(最上位ビットから1に当たるまでのビット数)の計算 */ +#if defined(__GNUC__) +/* ビルトイン関数を使用 */ +#define BITSTREAM_NLZ(x) (((x) > 0) ? (uint32_t)__builtin_clz(x) : 32U) +#elif defined(_MSC_VER) +/* ビルトイン関数を使用 */ +__inline uint32_t BITSTREAM_NLZ(uint32_t x) +{ + unsigned long result; + if (!x) { + return 32U; + } + _BitScanReverse(&result, x); + return result ^ 31U; +} +#else +/* ソフトウェア実装を使用 */ +#define BITSTREAM_NLZ(x) BitStream_NLZSoft(x) +#endif + +/* NLZのソフトウェア実装 */ +#ifdef __cplusplus +extern "C" uint32_t BitStream_NLZSoft(uint32_t x); +#else +uint32_t BitStream_NLZSoft(uint32_t x); +#endif + +#if !defined(BITSTREAM_USE_MACROS) + +#ifdef __cplusplus +extern "C" { +#endif + +/* ビットリーダのオープン */ +void BitReader_Open(struct BitStream *stream, const uint8_t *memory, size_t size); + +/* ビットライタのオープン */ +void BitWriter_Open(struct BitStream *stream, const uint8_t *memory, size_t size); + +/* ビットストリームのクローズ */ +void BitStream_Close(struct BitStream *stream); + +/* シーク(fseek準拠) */ +void BitStream_Seek(struct BitStream *stream, int32_t offset, int32_t origin); + +/* 現在位置(ftell)準拠 */ +void BitStream_Tell(struct BitStream *stream, int32_t *result); + +/* valの右側(下位)nbits 出力(最大32bit出力可能) */ +void BitWriter_PutBits(struct BitStream *stream, uint32_t val, uint32_t nbits); + +/* 0のランに続いて終わりの1を出力 */ +void BitWriter_PutZeroRun(struct BitStream *stream, uint32_t runlength); + +/* nbits 取得(最大32bit)し、その値を右詰めして出力 */ +void BitReader_GetBits(struct BitStream *stream, uint32_t *val, uint32_t nbits); + +/* つぎの1にぶつかるまで読み込み、その間に読み込んだ0のランレングスを取得 */ +void BitReader_GetZeroRunLength(struct BitStream *stream, uint32_t *runlength); + +/* バッファにたまったビットをクリア */ +void BitStream_Flush(struct BitStream *stream); + +#ifdef __cplusplus +} +#endif + +#else /* BITSTREAM_USE_MACROS */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* 下位ビットを取り出すためのマスク */ +extern const uint32_t g_bitstream_lower_bits_mask[33]; + +/* ラン長のパターンテーブル */ +extern const uint32_t g_bitstream_zerobit_runlength_table[0x100]; + +#ifdef __cplusplus +} +#endif + +/* ビットリーダのオープン */ +#define BitReader_Open(stream, memory, size)\ + do {\ + /* 引数チェック */\ + assert((void *)(stream) != NULL);\ + assert((void *)(memory) != NULL);\ + \ + /* 内部状態リセット */\ + (stream)->flags = 0;\ + \ + /* バッファ初期化 */\ + (stream)->bit_count = 0;\ + (stream)->bit_buffer = 0;\ + \ + /* メモリセット */\ + (stream)->memory_image = (memory);\ + (stream)->memory_size = (size);\ + (stream)->memory_tail = (memory) + (size);\ + \ + /* 読み出し位置は先頭に */\ + (stream)->memory_p = (memory);\ + \ + /* 読みモードとしてセット */\ + (stream)->flags |= (uint8_t)BITSTREAM_FLAGS_MODE_READ;\ + } while (0) + +/* ビットライタのオープン */ +#define BitWriter_Open(stream, memory, size)\ + do {\ + /* 引数チェック */\ + assert((void *)(stream) != NULL);\ + assert((void *)(memory) != NULL);\ + \ + /* 内部状態リセット */\ + (stream)->flags = 0;\ + \ + /* バッファ初期化 */\ + (stream)->bit_count = 32;\ + (stream)->bit_buffer = 0;\ + \ + /* メモリセット */\ + (stream)->memory_image = (memory);\ + (stream)->memory_size = (size);\ + (stream)->memory_tail = (memory) + (size);\ + \ + /* 読み出し位置は先頭に */\ + (stream)->memory_p = (memory);\ + \ + /* 書きモードとしてセット */\ + (stream)->flags &= (uint8_t)(~BITSTREAM_FLAGS_MODE_READ);\ + } while (0) + +/* ビットストリームのクローズ */ +#define BitStream_Close(stream)\ + do {\ + /* 引数チェック */\ + assert((void *)(stream) != NULL);\ + \ + /* 残ったデータをフラッシュ */\ + BitStream_Flush(stream);\ + \ + /* バッファのクリア */\ + (stream)->bit_buffer = 0;\ + \ + /* メモリ情報のクリア */\ + (stream)->memory_image = NULL;\ + (stream)->memory_size = 0;\ + \ + /* 内部状態のクリア */\ + (stream)->memory_p = NULL;\ + (stream)->flags = 0;\ + } while (0) + +/* シーク(fseek準拠) */ +#define BitStream_Seek(stream, offset, origin)\ + do {\ + uint8_t* __pos = NULL;\ + \ + /* 引数チェック */\ + assert((void *)(stream) != NULL);\ + \ + /* 内部バッファをクリア(副作用が起こる) */\ + BitStream_Flush(stream);\ + \ + /* 起点をまず定める */\ + switch (origin) {\ + case BITSTREAM_SEEK_CUR:\ + __pos = (stream)->memory_p;\ + break;\ + case BITSTREAM_SEEK_SET:\ + __pos = (uint8_t *)(stream)->memory_image;\ + break;\ + case BITSTREAM_SEEK_END:\ + __pos = (uint8_t *)((stream)->memory_tail - 1);\ + break;\ + default:\ + assert(0);\ + }\ + \ + /* オフセット分動かす */\ + __pos += (offset);\ + \ + /* 範囲チェック */\ + assert(__pos >= (stream)->memory_image);\ + assert(__pos < (stream)->memory_tail);\ + \ + /* 結果の保存 */\ + (stream)->memory_p = __pos;\ + } while (0) + +/* 現在位置(ftell)準拠 */ +#define BitStream_Tell(stream, result)\ + do {\ + /* 引数チェック */\ + assert((void *)(stream) != NULL);\ + assert((void *)(result) != NULL);\ + \ + /* アクセスオフセットを返す */\ + (*result) = (int32_t)\ + ((stream)->memory_p - (stream)->memory_image);\ + } while (0) + +/* valの右側(下位)nbits 出力(最大32bit出力可能) */ +#define BitWriter_PutBits(stream, val, nbits)\ + do {\ + uint32_t __nbits;\ + \ + /* 引数チェック */\ + assert((void *)(stream) != NULL);\ + \ + /* 読み込みモードでは実行不可能 */\ + assert(!((stream)->flags & BITSTREAM_FLAGS_MODE_READ));\ + \ + /* 出力可能な最大ビット数を越えてないか確認 */\ + assert((nbits) <= 32);\ + \ + /* 0ビット出力は何もせず終了 */\ + if ((nbits) == 0) { break; }\ + \ + /* valの上位ビットから順次出力 */\ + __nbits = (nbits);\ + if (__nbits >= (stream)->bit_count) {\ + __nbits -= (stream)->bit_count;\ + (stream)->bit_buffer |= BITSTREAM_GETLOWERBITS((val) >> __nbits, (stream)->bit_count);\ + \ + /* 終端に達していないかチェック */\ + assert((stream)->memory_p >= (stream)->memory_image);\ + assert(((stream)->memory_p + 3) < (stream)->memory_tail);\ + \ + /* メモリに書き出し */\ + (stream)->memory_p[0] = (((stream)->bit_buffer >> 24) & 0xFF);\ + (stream)->memory_p[1] = (((stream)->bit_buffer >> 16) & 0xFF);\ + (stream)->memory_p[2] = (((stream)->bit_buffer >> 8) & 0xFF);\ + (stream)->memory_p[3] = (((stream)->bit_buffer >> 0) & 0xFF);\ + (stream)->memory_p += 4;\ + \ + /* バッファをリセット */\ + (stream)->bit_buffer = 0;\ + (stream)->bit_count = 32;\ + }\ + \ + /* 端数ビットの処理: 残った分をバッファの上位ビットにセット */\ + assert(__nbits <= 32);\ + (stream)->bit_count -= __nbits;\ + (stream)->bit_buffer |= BITSTREAM_GETLOWERBITS(val, __nbits) << (stream)->bit_count;\ + } while (0) + +/* 0のランに続いて終わりの1を出力 */ +#define BitWriter_PutZeroRun(stream, runlength)\ + do {\ + uint32_t __run = ((runlength) + 1);\ + \ + /* 引数チェック */\ + assert((void *)(stream) != NULL);\ + \ + /* 読み込みモードでは実行不可能 */\ + assert(!((stream)->flags & BITSTREAM_FLAGS_MODE_READ));\ + \ + /* 31ビット単位で出力 */\ + while (__run > 31) {\ + BitWriter_PutBits(stream, 0, 31);\ + __run -= 31;\ + }\ + /* 終端の1を出力 */\ + BitWriter_PutBits(stream, 1, __run);\ + } while (0) + +/* nbits 取得(最大32bit)し、その値を右詰めして出力 */ +#define BitReader_GetBits(stream, val, nbits)\ + do {\ + uint32_t __tmp, __nbits;\ + \ + /* 引数チェック */\ + assert((void *)(stream) != NULL);\ + assert((void *)(val) != NULL);\ + \ + /* 読み込みモードでない場合はアサート */\ + assert((stream)->flags & BITSTREAM_FLAGS_MODE_READ);\ + \ + /* 入力可能な最大ビット数を越えてないか確認 */\ + assert((nbits) <= 32);\ + \ + /* 0ビット取得は0を返す */\ + if ((nbits) == 0) {\ + (*(val)) = 0;\ + break;\ + }\ + \ + /* バッファから取り出す */\ + if ((nbits) <= (stream)->bit_count) {\ + (stream)->bit_count -= (nbits);\ + (*(val)) = BITSTREAM_GETLOWERBITS((stream)->bit_buffer >> (stream)->bit_count, (nbits));\ + break;\ + }\ + \ + /* 現在のバッファ容量よりも多くのビットが要求されたらメモリから読み出し */\ + __nbits = (nbits);\ + /* 残りのビットを上位ビットにセット */\ + __nbits -= (stream)->bit_count;\ + __tmp = BITSTREAM_GETLOWERBITS((stream)->bit_buffer, (stream)->bit_count) << __nbits;\ + \ + /* 終端に達していないかチェック */\ + assert((stream)->memory_p >= (stream)->memory_image);\ + assert((stream)->memory_p < (stream)->memory_tail);\ + \ + /* メモリから読み出し */\ + (stream)->bit_buffer\ + = ((uint32_t)(stream)->memory_p[0] << 24) | ((uint32_t)(stream)->memory_p[1] << 16)\ + | ((uint32_t)(stream)->memory_p[2] << 8) | ((uint32_t)(stream)->memory_p[3] << 0);\ + (stream)->memory_p += 4;\ + (stream)->bit_count = 32;\ + \ + /* 端数ビットの処理 残ったビット分をtmpの最上位ビットにセット */\ + (stream)->bit_count -= __nbits;\ + __tmp |= BITSTREAM_GETLOWERBITS((stream)->bit_buffer >> (stream)->bit_count, __nbits);\ + \ + /* 正常終了 */\ + (*(val)) = __tmp;\ + } while (0) + +/* つぎの1にぶつかるまで読み込み、その間に読み込んだ0のランレングスを取得 */ +#define BitReader_GetZeroRunLength(stream, runlength)\ + do {\ + uint32_t __run;\ + \ + /* 引数チェック */\ + assert((void *)(stream) != NULL);\ + assert((void *)(runlength) != NULL);\ + \ + /* 上位ビットからの連続する0を計測 */\ + __run = BITSTREAM_NLZ(BITSTREAM_GETLOWERBITS((stream)->bit_buffer, (stream)->bit_count)) + (stream)->bit_count - 32;\ + \ + /* 読み込んだ分カウントを減らす */\ + assert((stream)->bit_count >= __run);\ + (stream)->bit_count -= __run;\ + \ + /* バッファが空の時 */\ + while ((stream)->bit_count == 0) {\ + /* 1バイト読み込み再度計測 */\ + uint32_t __tmp_run;\ + \ + /* 終端に達していないかチェック */\ + assert((stream)->memory_p >= (stream)->memory_image);\ + assert((stream)->memory_p < (stream)->memory_tail);\ + \ + /* メモリから読み出し ビットバッファにセットし直して再度ランを計測 */\ + (stream)->bit_buffer = (stream)->memory_p[0];\ + (stream)->memory_p++;\ + /* テーブルによりラン長を取得 */\ + __tmp_run = g_bitstream_zerobit_runlength_table[(stream)->bit_buffer];\ + (stream)->bit_count = 8 - __tmp_run;\ + /* ランを加算 */\ + __run += __tmp_run;\ + }\ + \ + /* 続く1を空読み */\ + assert((stream)->bit_count >= 1);\ + (stream)->bit_count -= 1;\ + \ + /* 正常終了 */\ + (*(runlength)) = __run;\ + } while (0) + +/* バッファにたまったビットをクリア */ +#define BitStream_Flush(stream)\ + do {\ + /* 引数チェック */\ + assert((void *)(stream) != NULL);\ + \ + if ((stream)->flags & BITSTREAM_FLAGS_MODE_READ) {\ + /* バッファに余ったバイト分だけ読み出し位置を戻し、バッファクリア */\ + (stream)->memory_p -= ((stream)->bit_count >> 3);\ + (stream)->bit_buffer = 0;\ + (stream)->bit_count = 0;\ + } else {\ + if ((stream)->bit_count < 32) {\ + /* 次のバイト境界まで出力 */\ + const uint32_t __remainbits = 32 - (stream)->bit_count;\ + if (__remainbits > 24) {\ + (stream)->memory_p[0] = (((stream)->bit_buffer >> 24) & 0xFF);\ + (stream)->memory_p[1] = (((stream)->bit_buffer >> 16) & 0xFF);\ + (stream)->memory_p[2] = (((stream)->bit_buffer >> 8) & 0xFF);\ + (stream)->memory_p[3] = (((stream)->bit_buffer >> 0) & 0xFF);\ + (stream)->memory_p += 4;\ + } else if (__remainbits > 16) {\ + (stream)->memory_p[0] = (((stream)->bit_buffer >> 24) & 0xFF);\ + (stream)->memory_p[1] = (((stream)->bit_buffer >> 16) & 0xFF);\ + (stream)->memory_p[2] = (((stream)->bit_buffer >> 8) & 0xFF);\ + (stream)->memory_p += 3;\ + } else if (__remainbits > 8) {\ + (stream)->memory_p[0] = (((stream)->bit_buffer >> 24) & 0xFF);\ + (stream)->memory_p[1] = (((stream)->bit_buffer >> 16) & 0xFF);\ + (stream)->memory_p += 2;\ + } else {\ + (stream)->memory_p[0] = (((stream)->bit_buffer >> 24) & 0xFF);\ + (stream)->memory_p += 1;\ + }\ + (stream)->bit_count = 32;\ + (stream)->bit_buffer = 0;\ + }\ + }\ + } while (0) + +#endif /* BITSTREAM_USE_MACROS */ + +#endif /* BITSTREAM_H_INCLUDED */ diff --git a/libs/bit_stream/src/CMakeLists.txt b/libs/bit_stream/src/CMakeLists.txt new file mode 100644 index 0000000..5e63ab7 --- /dev/null +++ b/libs/bit_stream/src/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/bit_stream.c + ) diff --git a/libs/bit_stream/src/bit_stream.c b/libs/bit_stream/src/bit_stream.c new file mode 100644 index 0000000..11ead91 --- /dev/null +++ b/libs/bit_stream/src/bit_stream.c @@ -0,0 +1,388 @@ +#include "bit_stream.h" +#include + +/* 下位ビットを取り出すマスク 32bitまで */ +const uint32_t g_bitstream_lower_bits_mask[33] = { + 0x00000000U, + 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000FU, + 0x0000001FU, 0x0000003FU, 0x0000007FU, 0x000000FFU, + 0x000001FFU, 0x000003FFU, 0x000007FFU, 0x00000FFFU, + 0x00001FFFU, 0x00003FFFU, 0x00007FFFU, 0x0000FFFFU, + 0x0001FFFFU, 0x0003FFFFU, 0x0007FFFFU, 0x000FFFFFU, + 0x001FFFFFU, 0x003FFFFFU, 0x007FFFFFU, 0x00FFFFFFU, + 0x01FFFFFFU, 0x03FFFFFFU, 0x07FFFFFFU, 0x0FFFFFFFU, + 0x1FFFFFFFU, 0x3FFFFFFFU, 0x7FFFFFFFU, 0xFFFFFFFFU +}; + +/* 0のラン長パターンテーブル(注意:上位ビットからのラン長) */ +const uint32_t g_bitstream_zerobit_runlength_table[256] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* NLZ計算のためのテーブル */ +#define UNUSED 99 +static const uint32_t st_nlz10_table[64] = { + 32, 20, 19, UNUSED, UNUSED, 18, UNUSED, 7, + 10, 17, UNUSED, UNUSED, 14, UNUSED, 6, UNUSED, + UNUSED, 9, UNUSED, 16, UNUSED, UNUSED, 1, 26, + UNUSED, 13, UNUSED, UNUSED, 24, 5, UNUSED, UNUSED, + UNUSED, 21, UNUSED, 8, 11, UNUSED, 15, UNUSED, + UNUSED, UNUSED, UNUSED, 2, 27, 0, 25, UNUSED, + 22, UNUSED, 12, UNUSED, UNUSED, 3, 28, UNUSED, + 23, UNUSED, 4, 29, UNUSED, UNUSED, 30, 31 +}; +#undef UNUSED + +#if !defined(BITSTREAM_USE_MACROS) + +/* ビットリーダのオープン */ +void BitReader_Open(struct BitStream *stream, const uint8_t *memory, size_t size) +{ + /* 引数チェック */ + assert(stream != NULL); + assert(memory != NULL); + + /* 内部状態リセット */ + stream->flags = 0; + + /* バッファ初期化 */ + stream->bit_count = 0; + stream->bit_buffer = 0; + + /* メモリセット */ + stream->memory_image = memory; + stream->memory_size = size; + stream->memory_tail = memory + size; + + /* 読み出し位置は先頭に */ + stream->memory_p = (uint8_t *)(memory); + + /* 読みモードとしてセット */ + stream->flags |= (uint8_t)BITSTREAM_FLAGS_MODE_READ; +} + +/* ビットライタのオープン */ +void BitWriter_Open(struct BitStream *stream, const uint8_t *memory, size_t size) +{ + /* 引数チェック */ + assert(stream != NULL); + assert(memory != NULL); + + /* 内部状態リセット */ + stream->flags = 0; + + /* バッファ初期化 */ + stream->bit_count = 32; + stream->bit_buffer = 0; + + /* メモリセット */ + stream->memory_image = memory; + stream->memory_size = size; + stream->memory_tail = memory + size; + + /* 読み出し位置は先頭に */ + stream->memory_p = (uint8_t *)(memory); + + /* 書きモードとしてセット */ + stream->flags &= (uint8_t)(~BITSTREAM_FLAGS_MODE_READ); +} + +/* ビットストリームのクローズ */ +void BitStream_Close(struct BitStream *stream) +{ + /* 引数チェック */ + assert(stream != NULL); + + /* 残ったデータをフラッシュ */ + BitStream_Flush(stream); + + /* バッファのクリア */ + stream->bit_buffer = 0; + + /* メモリ情報のクリア */ + stream->memory_image = NULL; + stream->memory_size = 0; + + /* 内部状態のクリア */ + stream->memory_p = NULL; + stream->flags = 0; +} + +/* シーク(fseek準拠) */ +void BitStream_Seek(struct BitStream *stream, int32_t offset, int32_t origin) +{ + uint8_t *pos = NULL; + + /* 引数チェック */ + assert(stream != NULL); + + /* 内部バッファをクリア(副作用が起こる) */ + BitStream_Flush(stream); + + /* 起点をまず定める */ + switch (origin) { + case BITSTREAM_SEEK_CUR: + pos = stream->memory_p; + break; + case BITSTREAM_SEEK_SET: + pos = (uint8_t *)stream->memory_image; + break; + case BITSTREAM_SEEK_END: + pos = (uint8_t *)((stream)->memory_tail - 1); + break; + default: + assert(0); + } + + /* オフセット分動かす */ + pos += (offset); + + /* 範囲チェック */ + assert(pos >= stream->memory_image); + assert(pos < (stream)->memory_tail); + + /* 結果の保存 */ + stream->memory_p = pos; +} + +/* 現在位置(ftell)準拠 */ +void BitStream_Tell(struct BitStream *stream, int32_t *result) +{ + /* 引数チェック */ + assert(stream != NULL); + assert(result != NULL); + + /* アクセスオフセットを返す */ + (*result) = (int32_t)(stream->memory_p - stream->memory_image); +} + +/* valの右側(下位)nbits 出力(最大32bit出力可能) */ +void BitWriter_PutBits(struct BitStream *stream, uint32_t val, uint32_t nbits) +{ + /* 引数チェック */ + assert(stream != NULL); + + /* 読み込みモードでは実行不可能 */ + assert(!(stream->flags & BITSTREAM_FLAGS_MODE_READ)); + + /* 出力可能な最大ビット数を越えてないか確認 */ + assert(nbits <= 32); + + /* 0ビット出力は何もせず終了 */ + if (nbits == 0) { return; } + + /* valの上位ビットから順次出力 */ + if (nbits >= stream->bit_count) { + nbits -= stream->bit_count; + stream->bit_buffer |= BITSTREAM_GETLOWERBITS(val >> nbits, stream->bit_count); + + /* 終端に達していないかチェック */ + assert(stream->memory_p >= stream->memory_image); + assert((stream->memory_p + 3) < stream->memory_tail); + + /* メモリに書き出し */ + stream->memory_p[0] = ((stream->bit_buffer >> 24) & 0xFF); + stream->memory_p[1] = ((stream->bit_buffer >> 16) & 0xFF); + stream->memory_p[2] = ((stream->bit_buffer >> 8) & 0xFF); + stream->memory_p[3] = ((stream->bit_buffer >> 0) & 0xFF); + stream->memory_p += 4; + + /* バッファをリセット */ + stream->bit_buffer = 0; + stream->bit_count = 32; + } + + /* 端数ビットの処理: 残った分をバッファの上位ビットにセット */ + assert(nbits <= 32); + stream->bit_count -= nbits; + stream->bit_buffer |= BITSTREAM_GETLOWERBITS(val, nbits) << stream->bit_count; +} + +/* 0のランに続いて終わりの1を出力 */ +void BitWriter_PutZeroRun(struct BitStream *stream, uint32_t runlength) +{ + uint32_t run = runlength + 1; + + /* 引数チェック */ + assert(stream != NULL); + + /* 読み込みモードでは実行不可能 */ + assert(!(stream->flags & BITSTREAM_FLAGS_MODE_READ)); + + /* 31ビット単位で出力 */ + while (run > 31) { + BitWriter_PutBits(stream, 0, 31); + run -= 31; + } + + /* 終端の1を出力 */ + BitWriter_PutBits(stream, 1, run); +} + +/* nbits 取得(最大32bit)し、その値を右詰めして出力 */ +void BitReader_GetBits(struct BitStream *stream, uint32_t *val, uint32_t nbits) +{ + uint32_t tmp = 0; + + /* 引数チェック */ + assert(stream != NULL); + assert(val != NULL); + + /* 読み込みモードでない場合はアサート */ + assert(stream->flags & BITSTREAM_FLAGS_MODE_READ); + + /* 入力可能な最大ビット数を越えてないか確認 */ + assert(nbits <= 32); + + /* 0ビット取得は0を返す */ + if (nbits == 0) { + (*val) = 0; + return; + } + + /* バッファから取り出す */ + if (nbits <= stream->bit_count) { + stream->bit_count -= nbits; + (*val) = BITSTREAM_GETLOWERBITS(stream->bit_buffer >> stream->bit_count, nbits); + return; + } + + /* 現在のバッファ容量よりも多くのビットが要求されたらメモリから読み出し */ + + /* 残りのビットを上位ビットにセット */ + nbits -= stream->bit_count; + tmp = BITSTREAM_GETLOWERBITS(stream->bit_buffer, stream->bit_count) << nbits; + + /* 終端に達していないかチェック */ + assert(stream->memory_p >= stream->memory_image); + assert(stream->memory_p < stream->memory_tail); + + /* メモリから読み出し */ + stream->bit_buffer + = ((uint32_t)stream->memory_p[0] << 24) | ((uint32_t)stream->memory_p[1] << 16) + | ((uint32_t)stream->memory_p[2] << 8) | ((uint32_t)stream->memory_p[3] << 0); + stream->memory_p += 4; + stream->bit_count = 32; + + /* 端数ビットの処理 残ったビット分をtmpの最上位ビットにセット */ + stream->bit_count -= nbits; + tmp |= BITSTREAM_GETLOWERBITS(stream->bit_buffer >> stream->bit_count, nbits); + + /* 正常終了 */ + (*val) = tmp; +} + +/* つぎの1にぶつかるまで読み込み、その間に読み込んだ0のランレングスを取得 */ +void BitReader_GetZeroRunLength(struct BitStream *stream, uint32_t *runlength) +{ + uint32_t run; + + /* 引数チェック */ + assert(stream != NULL); + assert(runlength != NULL); + + /* 上位ビットからの連続する0を計測 */ + run = BITSTREAM_NLZ(BITSTREAM_GETLOWERBITS(stream->bit_buffer, stream->bit_count)) + stream->bit_count - 32; + + /* 読み込んだ分カウントを減らす */ + assert(stream->bit_count >= run); + stream->bit_count -= run; + + /* バッファが空の時 */ + while (stream->bit_count == 0) { + /* 1バイト読み込み再度計測 */ + uint32_t tmp_run; + + /* 終端に達していないかチェック */ + assert(stream->memory_p >= stream->memory_image); + assert(stream->memory_p < stream->memory_tail); + + /* メモリから読み出し ビットバッファにセットし直して再度ランを計測 */ + stream->bit_buffer = stream->memory_p[0]; + stream->memory_p++; + /* テーブルによりラン長を取得 */ + tmp_run = g_bitstream_zerobit_runlength_table[stream->bit_buffer]; + stream->bit_count = 8 - tmp_run; + /* ランを加算 */ + run += tmp_run; + } + + /* 続く1を空読み */ + assert(stream->bit_count >= 1); + stream->bit_count -= 1; + + /* 正常終了 */ + (*runlength) = run; +} + +/* バッファにたまったビットをクリア(読み込み/書き込み位置を次のバイト境界に移動) */ +void BitStream_Flush(struct BitStream *stream) +{ + /* 引数チェック */ + assert(stream != NULL); + + if (stream->flags & BITSTREAM_FLAGS_MODE_READ) { + /* バッファに余ったバイト分だけ読み出し位置を戻し、バッファクリア */ + stream->memory_p -= (stream->bit_count >> 3); + stream->bit_buffer = 0; + stream->bit_count = 0; + } else { + if (stream->bit_count < 32) { + /* 次のバイト境界まで出力 */ + const uint32_t remainbits = 32 - stream->bit_count; + if (remainbits > 24) { + stream->memory_p[0] = ((stream->bit_buffer >> 24) & 0xFF); + stream->memory_p[1] = ((stream->bit_buffer >> 16) & 0xFF); + stream->memory_p[2] = ((stream->bit_buffer >> 8) & 0xFF); + stream->memory_p[3] = ((stream->bit_buffer >> 0) & 0xFF); + stream->memory_p += 4; + } else if (remainbits > 16) { + stream->memory_p[0] = ((stream->bit_buffer >> 24) & 0xFF); + stream->memory_p[1] = ((stream->bit_buffer >> 16) & 0xFF); + stream->memory_p[2] = ((stream->bit_buffer >> 8) & 0xFF); + stream->memory_p += 3; + } else if (remainbits > 8) { + stream->memory_p[0] = ((stream->bit_buffer >> 24) & 0xFF); + stream->memory_p[1] = ((stream->bit_buffer >> 16) & 0xFF); + stream->memory_p += 2; + } else { + stream->memory_p[0] = ((stream->bit_buffer >> 24) & 0xFF); + stream->memory_p += 1; + } + stream->bit_count = 32; + stream->bit_buffer = 0; + } + } +} + +#endif /* BITSTREAM_USE_MACROS */ + +/* NLZ(最上位ビットから1に当たるまでのビット数)の計算 */ +uint32_t BitStream_NLZSoft(uint32_t x) +{ + /* ハッカーのたのしみ参照 */ + x = x | (x >> 1); + x = x | (x >> 2); + x = x | (x >> 4); + x = x | (x >> 8); + x = x & ~(x >> 16); + x = (x << 9) - x; + x = (x << 11) - x; + x = (x << 14) - x; + return st_nlz10_table[x >> 26]; +} diff --git a/libs/byte_array/CMakeLists.txt b/libs/byte_array/CMakeLists.txt new file mode 100644 index 0000000..3e9d924 --- /dev/null +++ b/libs/byte_array/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.15) + +# プロジェクト名 +project(ByteArray C) + +# ライブラリ名 +set(LIB_NAME byte_array) + +# ライブラリ +add_library(${LIB_NAME} INTERFACE) + +# インクルードパス +target_include_directories(${LIB_NAME} + INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) diff --git a/libs/byte_array/include/byte_array.h b/libs/byte_array/include/byte_array.h new file mode 100644 index 0000000..5bdb437 --- /dev/null +++ b/libs/byte_array/include/byte_array.h @@ -0,0 +1,210 @@ +#ifndef BYTEARRAY_H_INCLUDED +#define BYTEARRAY_H_INCLUDED + +#include + +/* 1バイト読み出し */ +#define ByteArray_ReadUint8(p_array)\ + (uint8_t)((p_array)[0]) + +/* 2バイト読み出し(ビッグエンディアン) */ +#define ByteArray_ReadUint16BE(p_array)\ + (uint16_t)(\ + (((uint16_t)((p_array)[0])) << 8) |\ + (((uint16_t)((p_array)[1])) << 0)\ + ) + +/* 3バイト読み出し(ビッグエンディアン) */ +#define ByteArray_ReadUint24BE(p_array)\ + (uint32_t)(\ + (((uint32_t)((p_array)[0])) << 16) |\ + (((uint32_t)((p_array)[1])) << 8) |\ + (((uint32_t)((p_array)[2])) << 0)\ + ) + +/* 4バイト読み出し(ビッグエンディアン) */ +#define ByteArray_ReadUint32BE(p_array)\ + (uint32_t)(\ + (((uint32_t)((p_array)[0])) << 24) |\ + (((uint32_t)((p_array)[1])) << 16) |\ + (((uint32_t)((p_array)[2])) << 8) |\ + (((uint32_t)((p_array)[3])) << 0)\ + ) + +/* 2バイト読み出し(リトルエンディアン) */ +#define ByteArray_ReadUint16LE(p_array)\ + (uint16_t)(\ + (((uint16_t)((p_array)[0])) << 0) |\ + (((uint16_t)((p_array)[1])) << 8)\ + ) + +/* 3バイト読み出し(リトルエンディアン) */ +#define ByteArray_ReadUint24LE(p_array)\ + (uint32_t)(\ + (((uint32_t)((p_array)[0])) << 0) |\ + (((uint32_t)((p_array)[1])) << 8) |\ + (((uint32_t)((p_array)[2])) << 16)\ + ) + +/* 4バイト読み出し(リトルエンディアン) */ +#define ByteArray_ReadUint32LE(p_array)\ + (uint32_t)(\ + (((uint32_t)((p_array)[0])) << 0) |\ + (((uint32_t)((p_array)[1])) << 8) |\ + (((uint32_t)((p_array)[2])) << 16) |\ + (((uint32_t)((p_array)[3])) << 24)\ + ) + +/* 1バイト取得 */ +#define ByteArray_GetUint8(p_array, p_u8val)\ + do {\ + (*(p_u8val)) = ByteArray_ReadUint8(p_array);\ + (p_array) += 1;\ + } while (0); + +/* 2バイト取得(ビッグエンディアン) */ +#define ByteArray_GetUint16BE(p_array, p_u16val)\ + do {\ + (*(p_u16val)) = ByteArray_ReadUint16BE(p_array);\ + (p_array) += 2;\ + } while (0); + +/* 3バイト取得(ビッグエンディアン) */ +#define ByteArray_GetUint24BE(p_array, p_u32val)\ + do {\ + (*(p_u32val)) = ByteArray_ReadUint24BE(p_array);\ + (p_array) += 3;\ + } while (0); + +/* 4バイト取得(ビッグエンディアン) */ +#define ByteArray_GetUint32BE(p_array, p_u32val)\ + do {\ + (*(p_u32val)) = ByteArray_ReadUint32BE(p_array);\ + (p_array) += 4;\ + } while (0); + +/* 2バイト取得(リトルエンディアン) */ +#define ByteArray_GetUint16LE(p_array, p_u16val)\ + do {\ + (*(p_u16val)) = ByteArray_ReadUint16LE(p_array);\ + (p_array) += 2;\ + } while (0); + +/* 3バイト取得(リトルエンディアン) */ +#define ByteArray_GetUint24LE(p_array, p_u32val)\ + do {\ + (*(p_u32val)) = ByteArray_ReadUint24LE(p_array);\ + (p_array) += 3;\ + } while (0); + +/* 4バイト取得(リトルエンディアン) */ +#define ByteArray_GetUint32LE(p_array, p_u32val)\ + do {\ + (*(p_u32val)) = ByteArray_ReadUint32LE(p_array);\ + (p_array) += 4;\ + } while (0); + +/* 1バイト書き出し */ +#define ByteArray_WriteUint8(p_array, u8val)\ + do {\ + ((p_array)[0]) = (uint8_t)(u8val);\ + } while (0); + +/* 2バイト書き出し(ビッグエンディアン) */ +#define ByteArray_WriteUint16BE(p_array, u16val)\ + do {\ + ((p_array)[0]) = (uint8_t)(((u16val) >> 8) & 0xFF);\ + ((p_array)[1]) = (uint8_t)(((u16val) >> 0) & 0xFF);\ + } while (0); + +/* 3バイト書き出し(ビッグエンディアン) */ +#define ByteArray_WriteUint24BE(p_array, u32val)\ + do {\ + ((p_array)[0]) = (uint8_t)(((u32val) >> 16) & 0xFF);\ + ((p_array)[1]) = (uint8_t)(((u32val) >> 8) & 0xFF);\ + ((p_array)[2]) = (uint8_t)(((u32val) >> 0) & 0xFF);\ + } while (0); + +/* 4バイト書き出し(ビッグエンディアン) */ +#define ByteArray_WriteUint32BE(p_array, u32val)\ + do {\ + ((p_array)[0]) = (uint8_t)(((u32val) >> 24) & 0xFF);\ + ((p_array)[1]) = (uint8_t)(((u32val) >> 16) & 0xFF);\ + ((p_array)[2]) = (uint8_t)(((u32val) >> 8) & 0xFF);\ + ((p_array)[3]) = (uint8_t)(((u32val) >> 0) & 0xFF);\ + } while (0); + +/* 2バイト書き出し(リトルエンディアン) */ +#define ByteArray_WriteUint16LE(p_array, u16val)\ + do {\ + ((p_array)[0]) = (uint8_t)(((u16val) >> 0) & 0xFF);\ + ((p_array)[1]) = (uint8_t)(((u16val) >> 8) & 0xFF);\ + } while (0); + +/* 3バイト書き出し(リトルエンディアン) */ +#define ByteArray_WriteUint24LE(p_array, u32val)\ + do {\ + ((p_array)[0]) = (uint8_t)(((u32val) >> 0) & 0xFF);\ + ((p_array)[1]) = (uint8_t)(((u32val) >> 8) & 0xFF);\ + ((p_array)[2]) = (uint8_t)(((u32val) >> 16) & 0xFF);\ + } while (0); + +/* 4バイト書き出し(リトルエンディアン) */ +#define ByteArray_WriteUint32LE(p_array, u32val)\ + do {\ + ((p_array)[0]) = (uint8_t)(((u32val) >> 0) & 0xFF);\ + ((p_array)[1]) = (uint8_t)(((u32val) >> 8) & 0xFF);\ + ((p_array)[2]) = (uint8_t)(((u32val) >> 16) & 0xFF);\ + ((p_array)[3]) = (uint8_t)(((u32val) >> 24) & 0xFF);\ + } while (0); + +/* 1バイト出力 */ +#define ByteArray_PutUint8(p_array, u8val)\ + do {\ + ByteArray_WriteUint8(p_array, u8val);\ + (p_array) += 1;\ + } while (0); + +/* 2バイト出力(ビッグエンディアン) */ +#define ByteArray_PutUint16BE(p_array, u16val)\ + do {\ + ByteArray_WriteUint16BE(p_array, u16val);\ + (p_array) += 2;\ + } while (0); + +/* 3バイト出力(ビッグエンディアン) */ +#define ByteArray_PutUint24BE(p_array, u32val)\ + do {\ + ByteArray_WriteUint24BE(p_array, u32val);\ + (p_array) += 3;\ + } while (0); + +/* 4バイト出力(ビッグエンディアン) */ +#define ByteArray_PutUint32BE(p_array, u32val)\ + do {\ + ByteArray_WriteUint32BE(p_array, u32val);\ + (p_array) += 4;\ + } while (0); + +/* 2バイト出力(リトルエンディアン) */ +#define ByteArray_PutUint16LE(p_array, u16val)\ + do {\ + ByteArray_WriteUint16LE(p_array, u16val);\ + (p_array) += 2;\ + } while (0); + +/* 3バイト出力(リトルエンディアン) */ +#define ByteArray_PutUint24LE(p_array, u32val)\ + do {\ + ByteArray_WriteUint24LE(p_array, u32val);\ + (p_array) += 3;\ + } while (0); + +/* 4バイト出力(リトルエンディアン) */ +#define ByteArray_PutUint32LE(p_array, u32val)\ + do {\ + ByteArray_WriteUint32LE(p_array, u32val);\ + (p_array) += 4;\ + } while (0); + +#endif /* BYTEARRAY_H_INCLUDED */ diff --git a/libs/command_line_parser/CMakeLists.txt b/libs/command_line_parser/CMakeLists.txt new file mode 100644 index 0000000..8810271 --- /dev/null +++ b/libs/command_line_parser/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.15) + +# プロジェクト名 +project(CommandLineParser C) + +# ライブラリ名 +set(LIB_NAME command_line_parser) + +# 静的ライブラリ指定 +add_library(${LIB_NAME} STATIC) + +# ソースディレクトリ +add_subdirectory(src) + +# インクルードパス +target_include_directories(${LIB_NAME} + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + +# コンパイルオプション +if(MSVC) + target_compile_options(${LIB_NAME} PRIVATE /W4) +else() + target_compile_options(${LIB_NAME} PRIVATE -Wall -Wextra -Wpedantic -Wformat=2 -Wstrict-aliasing=2 -Wconversion -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition) + set(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -DDEBUG") + set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") +endif() +set_target_properties(${LIB_NAME} + PROPERTIES + C_STANDARD 90 C_EXTENSIONS OFF + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) diff --git a/libs/command_line_parser/include/command_line_parser.h b/libs/command_line_parser/include/command_line_parser.h new file mode 100644 index 0000000..42a3c14 --- /dev/null +++ b/libs/command_line_parser/include/command_line_parser.h @@ -0,0 +1,61 @@ +#ifndef COMMAND_LINE_PARSER_H_INCLDED +#define COMMAND_LINE_PARSER_H_INCLDED + +#include + +/* 取得結果 */ +typedef enum CommandLineParserResultTag { + COMMAND_LINE_PARSER_RESULT_OK, /* 正常終了 */ + COMMAND_LINE_PARSER_RESULT_INVALID_ARGUMENT, /* 不正な引数 */ + COMMAND_LINE_PARSER_RESULT_INSUFFICIENT_OTHER_STRING_ARRAY_SIZE, /* その他の文字列が入った配列サイズが足らない */ + COMMAND_LINE_PARSER_RESULT_NOT_SPECIFY_ARGUMENT_TO_OPTION, /* 引数の指定が必須のオプションで引数の指定がない */ + COMMAND_LINE_PARSER_RESULT_UNKNOWN_OPTION, /* 定義にないオプションが指定された */ + COMMAND_LINE_PARSER_RESULT_OPTION_MULTIPLY_SPECIFIED, /* オプションが複数回指定された */ + COMMAND_LINE_PARSER_RESULT_INVALID_SPECIFICATION, /* 無効な仕様 */ + COMMAND_LINE_PARSER_RESULT_INVAILD_SHORT_OPTION_ARGUMENT /* ショートオプションの引数の指定が不適切 */ +} CommandLineParserResult; + +/* 論理定数 */ +typedef enum CommandLineParserBoolTag { + COMMAND_LINE_PARSER_FALSE = 0, /* 偽 */ + COMMAND_LINE_PARSER_TRUE /* 真 */ +} CommandLineParserBool; + +/* コマンドラインパーサ仕様 */ +/* 補足)コマンドラインパーサ仕様の配列の最後の要素の短いオプションに0, 長いオプションにNULLを指定して下さい */ +struct CommandLineParserSpecification { + char short_option; /* [in] 短いオプション文字列 */ + const char* long_option; /* [in] 長いオプション文字列 */ + const char* description; /* [in] 引数の説明 */ + CommandLineParserBool need_argument; /* [in] オプションに引数は必要か? */ + const char* argument_string; /* [in,out] 得られた文字列 */ + CommandLineParserBool acquired; /* [out] オプションが指定されたか? */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* 引数説明の印字 */ +void CommandLineParser_PrintDescription( + const struct CommandLineParserSpecification* clps); + +/* オプション名からそのオプションが指定されたか取得 */ +CommandLineParserBool CommandLineParser_GetOptionAcquired( + const struct CommandLineParserSpecification* clps, const char* option_name); + +/* オプション名からそのオプション引数を取得 */ +const char* CommandLineParser_GetArgumentString( + const struct CommandLineParserSpecification* clps, const char* option_name); + +/* 引数のパース */ +CommandLineParserResult CommandLineParser_ParseArguments( + struct CommandLineParserSpecification* clps, + int32_t argc, const char* const* argv, + const char** other_string_array, uint32_t other_string_array_size); + +#ifdef __cplusplus +} +#endif + +#endif /* COMMAND_LINE_PARSER_H_INCLDED */ diff --git a/libs/command_line_parser/src/CMakeLists.txt b/libs/command_line_parser/src/CMakeLists.txt new file mode 100644 index 0000000..eaad33b --- /dev/null +++ b/libs/command_line_parser/src/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/command_line_parser.c + ) diff --git a/libs/command_line_parser/src/command_line_parser.c b/libs/command_line_parser/src/command_line_parser.c new file mode 100644 index 0000000..a77b123 --- /dev/null +++ b/libs/command_line_parser/src/command_line_parser.c @@ -0,0 +1,331 @@ +#include "command_line_parser.h" + +#include +#include +#include + +/* 仕様リストサイズを計測 */ +static uint32_t CommandLineParser_GetNumSpecifications( + const struct CommandLineParserSpecification* clps) +{ + uint32_t num_specs; + + assert(clps != NULL); + + /* リスト終端の0にぶつかるまでポインタを進める */ + num_specs = 0; + while ((clps->short_option != 0) || (clps->long_option != NULL)) { + num_specs++; + clps++; + } + + return num_specs; +} + +/* コマンドラインパーサ仕様のチェック */ +static CommandLineParserBool CommandLineParser_CheckSpecification( + const struct CommandLineParserSpecification* clps) +{ + uint32_t spec_no; + uint32_t num_specs; + + assert(clps != NULL); + + /* 仕様数の取得 */ + num_specs = CommandLineParser_GetNumSpecifications(clps); + + for (spec_no = 0; spec_no < num_specs; spec_no++) { + uint32_t j; + for (j = 0; j < num_specs; j++) { + if (j == spec_no) { + continue; + } + /* 同じオプション文字列を持つものがいたら不正 */ + if (clps[j].short_option == clps[spec_no].short_option) { + return COMMAND_LINE_PARSER_FALSE; + } else if ((clps[j].long_option != NULL) && (clps[spec_no].long_option != NULL)) { + if (strcmp(clps[j].long_option, clps[spec_no].long_option) == 0) { + return COMMAND_LINE_PARSER_FALSE; + } + } + } + } + + /* 問題なし */ + return COMMAND_LINE_PARSER_TRUE; +} + +/* 引数説明の印字 */ +void CommandLineParser_PrintDescription(const struct CommandLineParserSpecification* clps) +{ + uint32_t spec_no; + char arg_option_attr[256]; + char command_str[256]; + uint32_t num_specs; + + /* 引数チェック */ + if (clps == NULL) { + fprintf(stderr, "Pointer to command-line specification is NULL. \n"); + return; + } + + /* 仕様をチェックしておく */ + if (CommandLineParser_CheckSpecification(clps) != COMMAND_LINE_PARSER_TRUE) { + fprintf(stderr, "Warning: Command-line specification is invalid. (Unable to parse) \n"); + } + + /* 仕様数の取得 */ + num_specs = CommandLineParser_GetNumSpecifications(clps); + + /* 仕様を順番に表示 */ + for (spec_no = 0; spec_no < num_specs; spec_no++) { + const struct CommandLineParserSpecification* pspec = &clps[spec_no]; + /* 引数の属性文字列を作成 */ + if (pspec->need_argument == COMMAND_LINE_PARSER_TRUE) { + sprintf(arg_option_attr, "(needs argument)"); + } else { + strcpy(arg_option_attr, ""); + } + + /* コマンド文字列を作成 */ + if (pspec->long_option != NULL) { + sprintf(command_str, " -%c, --%s", pspec->short_option, pspec->long_option); + } else { + sprintf(command_str, " -%c", pspec->short_option); + } + + /* 説明を付加して全てを印字 */ + printf("%-20s %-18s %s \n", + command_str, arg_option_attr, + (pspec->description != NULL) ? pspec->description : ""); + } +} + +/* オプション名からインデックスを取得 */ +static CommandLineParserResult CommandLineParser_GetSpecificationIndex( + const struct CommandLineParserSpecification* clps, + const char* option_name, uint32_t* index) +{ + uint32_t spec_no; + uint32_t num_specs; + + /* 引数チェック */ + if (clps == NULL || option_name == NULL || index == NULL) { + return COMMAND_LINE_PARSER_RESULT_INVALID_ARGUMENT; + } + + /* 仕様数の取得 */ + num_specs = CommandLineParser_GetNumSpecifications(clps); + + /* ショートオプションから検索 */ + if (strlen(option_name) == 1) { + for (spec_no = 0; spec_no < num_specs; spec_no++) { + if (option_name[0] == clps[spec_no].short_option) { + *index = spec_no; + return COMMAND_LINE_PARSER_RESULT_OK; + } + } + } + + /* ロングオプションから検索 */ + for (spec_no = 0; spec_no < num_specs; spec_no++) { + if (strcmp(option_name, clps[spec_no].long_option) == 0) { + *index = spec_no; + return COMMAND_LINE_PARSER_RESULT_OK; + } + } + + /* 見つからなかった */ + return COMMAND_LINE_PARSER_RESULT_UNKNOWN_OPTION; +} + +/* オプション名からそのオプションが指定されたか取得 */ +CommandLineParserBool CommandLineParser_GetOptionAcquired( + const struct CommandLineParserSpecification* clps, + const char* option_name) +{ + uint32_t spec_no; + + /* インデックス取得 */ + if (CommandLineParser_GetSpecificationIndex(clps, option_name, &spec_no) != COMMAND_LINE_PARSER_RESULT_OK) { + return COMMAND_LINE_PARSER_FALSE; + } + + return clps[spec_no].acquired; +} + +/* オプション名からそのオプション引数を取得 */ +const char* CommandLineParser_GetArgumentString( + const struct CommandLineParserSpecification* clps, + const char* option_name) +{ + uint32_t spec_no; + + /* インデックス取得 */ + if (CommandLineParser_GetSpecificationIndex(clps, option_name, &spec_no) != COMMAND_LINE_PARSER_RESULT_OK) { + return NULL; + } + + return clps[spec_no].argument_string; +} + +/* 引数のパース */ +CommandLineParserResult CommandLineParser_ParseArguments( + struct CommandLineParserSpecification* clps, + int32_t argc, const char* const* argv, + const char** other_string_array, uint32_t other_string_array_size) +{ + int32_t count; + uint32_t spec_no; + const char* arg_str; + uint32_t other_string_index; + uint32_t num_specs; + + /* 引数チェック */ + if (argv == NULL || clps == NULL) { + return COMMAND_LINE_PARSER_RESULT_INVALID_ARGUMENT; + } + + /* 仕様数の取得 */ + num_specs = CommandLineParser_GetNumSpecifications(clps); + + /* コマンドライン仕様のチェック */ + if (CommandLineParser_CheckSpecification(clps) != COMMAND_LINE_PARSER_TRUE) { + return COMMAND_LINE_PARSER_RESULT_INVALID_SPECIFICATION; + } + + /* 全てのオプションを未取得状態にセット */ + for (spec_no = 0; spec_no < num_specs; spec_no++) { + clps[spec_no].acquired = COMMAND_LINE_PARSER_FALSE; + } + + /* argv[0]はプログラム名だから飛ばす */ + other_string_index = 0; + for (count = 1; count < argc; count++) { + /* 文字列配列の要素を取得 */ + arg_str = argv[count]; + /* オプション文字列を検査 */ + if (strncmp(arg_str, "--", 2) == 0) { + /* ロングオプション */ + for (spec_no = 0; spec_no < num_specs; spec_no++) { + uint32_t long_option_len; + struct CommandLineParserSpecification* pspec = &clps[spec_no]; + /* ロングオプション文字列がNULLなら飛ばす */ + if (pspec->long_option == NULL) { + continue; + } + long_option_len = (uint32_t)strlen(pspec->long_option); + if (strncmp(&arg_str[2], pspec->long_option, long_option_len) == 0) { + /* ロングオプションの後はナル終端かオプション指定のための'='が来なければならない */ + if (arg_str[2 + long_option_len] == '\0') { + /* 既に取得済みのオプションが指定された */ + if (pspec->acquired == COMMAND_LINE_PARSER_TRUE) { + fprintf(stderr, "%s: Option \"%s\" multiply specified. \n", argv[0], pspec->long_option); + return COMMAND_LINE_PARSER_RESULT_OPTION_MULTIPLY_SPECIFIED; + } + if (pspec->need_argument == COMMAND_LINE_PARSER_TRUE) { + /* 引数を取るオプションの場合は、そのまま引数を取りに行く */ + if ((count + 1) == argc) { + /* 終端に達している */ + fprintf(stderr, "%s: Option \"%s\" needs argument. \n", argv[0], pspec->long_option); + return COMMAND_LINE_PARSER_RESULT_NOT_SPECIFY_ARGUMENT_TO_OPTION; + } else if ((strncmp(argv[count + 1], "--", 2) == 0) || argv[count + 1][0] == '-') { + /* 他のオプション指定が入っている */ + /* (オプション引数文字列として"--", '-'が先頭にくるものは認めない) */ + fprintf(stderr, "%s: Option \"%s\" needs argument. \n", argv[0], pspec->long_option); + return COMMAND_LINE_PARSER_RESULT_NOT_SPECIFY_ARGUMENT_TO_OPTION; + } + /* オプション文字列を取得しつつ次の引数文字列に移動 */ + count++; + pspec->argument_string = argv[count]; + } + } else if (arg_str[2 + long_option_len] == '=') { + if (pspec->need_argument != COMMAND_LINE_PARSER_TRUE) { + /* '='を含むオプションかもしれない... */ + continue; + } + /* 既に取得済みのオプションが指定された */ + if (pspec->acquired == COMMAND_LINE_PARSER_TRUE) { + fprintf(stderr, "%s: Option \"%s\" multiply specified. \n", argv[0], pspec->long_option); + return COMMAND_LINE_PARSER_RESULT_OPTION_MULTIPLY_SPECIFIED; + } + /* オプション文字列を取得 */ + pspec->argument_string = &arg_str[2 + long_option_len + 1]; + } else { + /* より長い文字が指定されている. 他のオプションで一致するかもしれないので読み飛ばす. */ + continue; + } + /* 取得済み状態にセット */ + pspec->acquired = COMMAND_LINE_PARSER_TRUE; + break; + } + } + /* オプションが見つからなかった */ + if (spec_no == num_specs) { + fprintf(stderr, "%s: Unknown long option - \"%s\" \n", argv[0], &arg_str[2]); + return COMMAND_LINE_PARSER_RESULT_UNKNOWN_OPTION; + } + } else if (arg_str[0] == '-') { + /* ショートオプション(の連なり) */ + uint32_t str_index; + for (str_index = 1; arg_str[str_index] != '\0'; str_index++) { + for (spec_no = 0; spec_no < num_specs; spec_no++) { + struct CommandLineParserSpecification* pspec = &clps[spec_no]; + if (arg_str[str_index] == pspec->short_option) { + /* 既に取得済みのオプションが指定された */ + if (pspec->acquired == COMMAND_LINE_PARSER_TRUE) { + fprintf(stderr, "%s: Option \'%c\' multiply specified. \n", argv[0], pspec->short_option); + return COMMAND_LINE_PARSER_RESULT_OPTION_MULTIPLY_SPECIFIED; + } + /* 引数ありのオプション */ + if (pspec->need_argument == COMMAND_LINE_PARSER_TRUE) { + /* 引数を取るオプションの場合は、そのまま引数を取りに行く */ + if (arg_str[str_index + 1] != '\0') { + /* 引数を取るに当たり、現在注目しているオプションが末尾である必要がある */ + fprintf(stderr, "%s: Option \'%c\' needs argument. " + "Please specify tail of short option sequence.\n", argv[0], pspec->short_option); + return COMMAND_LINE_PARSER_RESULT_INVAILD_SHORT_OPTION_ARGUMENT; + } + if ((count + 1) == argc) { + /* 終端に達している */ + fprintf(stderr, "%s: Option \'%c\' needs argument. \n", argv[0], pspec->short_option); + return COMMAND_LINE_PARSER_RESULT_NOT_SPECIFY_ARGUMENT_TO_OPTION; + } else if ((strncmp(argv[count + 1], "--", 2) == 0) || argv[count + 1][0] == '-') { + /* 他のオプション指定が入っている */ + /* (引数として"--", '-'が先頭にくるものは認めない) */ + fprintf(stderr, "%s: Option \'%c\' needs argument. \n", argv[0], pspec->short_option); + return COMMAND_LINE_PARSER_RESULT_NOT_SPECIFY_ARGUMENT_TO_OPTION; + } + /* オプション文字列を取得しつつ次の引数文字列に移動 */ + count++; + pspec->argument_string = argv[count]; + } + /* 取得済み状態にセット */ + pspec->acquired = COMMAND_LINE_PARSER_TRUE; + break; + } + } + /* オプションが見つからなかった */ + if (spec_no == num_specs) { + fprintf(stderr, "%s: Unknown short option - \'%c\' \n", argv[0], arg_str[str_index]); + return COMMAND_LINE_PARSER_RESULT_UNKNOWN_OPTION; + } + } + } else { + /* オプションでもオプション引数でもない文字列 */ + if (other_string_array == NULL) { + /* バッファにアクセスできない */ + return COMMAND_LINE_PARSER_RESULT_INVALID_ARGUMENT; + } else if (other_string_index >= other_string_array_size) { + /* バッファサイズ不足 */ + fprintf(stderr, "%s: Too many strings specified. \n", argv[0]); + return COMMAND_LINE_PARSER_RESULT_INSUFFICIENT_OTHER_STRING_ARRAY_SIZE; + } + /* 文字列取得 */ + other_string_array[other_string_index] = arg_str; + other_string_index++; + } + } + + return COMMAND_LINE_PARSER_RESULT_OK; +} diff --git a/libs/lpc/CMakeLists.txt b/libs/lpc/CMakeLists.txt new file mode 100644 index 0000000..2690b74 --- /dev/null +++ b/libs/lpc/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# プロジェクト名 +project(LPC C) + +# ライブラリ名 +set(LIB_NAME lpc) + +# 静的ライブラリ指定 +add_library(${LIB_NAME} STATIC) + +# ソースディレクトリ +add_subdirectory(src) + +# インクルードパス +target_include_directories(${LIB_NAME} + PRIVATE + ${PROJECT_ROOT_PATH}/include + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + +# コンパイルオプション +if(MSVC) + target_compile_options(${LIB_NAME} PRIVATE /W4) +else() + target_compile_options(${LIB_NAME} PRIVATE -Wall -Wextra -Wpedantic -Wformat=2 -Wstrict-aliasing=2 -Wconversion -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition) + set(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -DDEBUG") + set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") +endif() +set_target_properties(${LIB_NAME} + PROPERTIES + C_STANDARD 90 C_EXTENSIONS OFF + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) diff --git a/libs/lpc/include/lpc.h b/libs/lpc/include/lpc.h new file mode 100644 index 0000000..84b1c71 --- /dev/null +++ b/libs/lpc/include/lpc.h @@ -0,0 +1,118 @@ +#ifndef LPC_H_INCLUDED +#define LPC_H_INCLUDED + +#include + +/* API結果型 */ +typedef enum LPCApiResultTag { + LPC_APIRESULT_OK = 0, /* OK */ + LPC_APIRESULT_NG, /* 分類不能なエラー */ + LPC_APIRESULT_INVALID_ARGUMENT, /* 不正な引数 */ + LPC_APIRESULT_EXCEED_MAX_ORDER, /* 最大次数を超えた */ + LPC_APIRESULT_EXCEED_MAX_NUM_SAMPLES, /* 最大入力サンプル数を超えた */ + LPC_APIRESULT_FAILED_TO_CALCULATION /* 計算に失敗 */ +} LPCApiResult; + +/* 窓関数の種類 */ +typedef enum LPCWindowTypeTag { + LPC_WINDOWTYPE_RECTANGULAR = 0, /* 矩形窓 */ + LPC_WINDOWTYPE_SIN, /* サイン窓 */ + LPC_WINDOWTYPE_WELCH /* Welch窓 */ +} LPCWindowType; + +/* LPC係数計算ハンドル */ +struct LPCCalculator; + +/* 初期化コンフィグ */ +struct LPCCalculatorConfig { + uint32_t max_order; /* 最大次数 */ + uint32_t max_num_samples; /* 最大入力サンプル数 */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* LPC係数計算ハンドルのワークサイズ計算 */ +int32_t LPCCalculator_CalculateWorkSize(const struct LPCCalculatorConfig *config); + +/* LPC係数計算ハンドルの作成 */ +struct LPCCalculator *LPCCalculator_Create(const struct LPCCalculatorConfig *config, void *work, int32_t work_size); + +/* LPC係数計算ハンドルの破棄 */ +void LPCCalculator_Destroy(struct LPCCalculator *lpcc); + +/* Levinson-Durbin再帰計算によりLPC係数を求める */ +LPCApiResult LPCCalculator_CalculateLPCCoefficients( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, double *coef, uint32_t coef_order, + LPCWindowType window_type, double regular_term); + +/* Levinson-Durbin再帰計算により与えられた次数まで全てのLPC係数を求める(倍精度) */ +LPCApiResult LPCCalculator_CalculateMultipleLPCCoefficients( + struct LPCCalculator* lpcc, + const double* data, uint32_t num_samples, double **lpc_coefs, uint32_t max_coef_order, + LPCWindowType window_type, double regular_term); + +/* Levinson-Durbin再帰計算により与えられた次数までの残差分散を求める(倍精度) */ +/* 0次の誤差分散(分散)からmax_coef_order次の分散まで求めるためerror_varsのサイズはmax_coef_order+1要する */ +LPCApiResult LPCCalculator_CalculateErrorVariances( + struct LPCCalculator* lpcc, + const double* data, uint32_t num_samples, double *error_vars, uint32_t max_coef_order, + LPCWindowType window_type, double regular_term); + +/* 補助関数法よりLPC係数を求める(倍精度) */ +LPCApiResult LPCCalculator_CalculateLPCCoefficientsAF( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, double *coef, uint32_t coef_order, + uint32_t max_num_iteration, LPCWindowType window_type, double regular_term); + +/* Burg法によりLPC係数を求める(倍精度) */ +LPCApiResult LPCCalculator_CalculateLPCCoefficientsBurg( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, double *coef, uint32_t coef_order); + +/* SVRよりLPC係数を求める(倍精度) */ +LPCApiResult LPCCalculator_CalculateLPCCoefficientsSVR( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, double *coef, uint32_t coef_order, + uint32_t max_num_iteration, LPCWindowType window_type, + double regular_term, const double *margin_list, uint32_t margin_list_size); + +/* 入力データからサンプルあたりの推定符号長を求める */ +LPCApiResult LPCCalculator_EstimateCodeLength( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, uint32_t bits_per_sample, + uint32_t coef_order, double *length_per_sample_bits, LPCWindowType window_type); + +/* MDL(最小記述長)を計算 */ +LPCApiResult LPCCalculator_CalculateMDL( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, uint32_t coef_order, double *mdl, + LPCWindowType window_type); + +/* LPC係数をPARCOR係数に変換して量子化する */ +LPCApiResult LPC_QuantizeCoefficientsAsPARCOR( + struct LPCCalculator *lpcc, + const double *lpc_coef, uint32_t coef_order, uint32_t nbits_precision, int32_t *int_coef); + +/* LPC係数の整数量子化 */ +LPCApiResult LPC_QuantizeCoefficients( + const double *double_coef, uint32_t coef_order, uint32_t nbits_precision, uint32_t max_bits, + int32_t *int_coef, uint32_t *coef_rshift); + +/* LPC係数により予測/誤差出力 */ +LPCApiResult LPC_Predict( + const int32_t *data, uint32_t num_samples, + const int32_t *coef, uint32_t coef_order, int32_t *residual, uint32_t coef_rshift); + +/* LPC係数により合成(in-place) */ +LPCApiResult LPC_Synthesize( + int32_t *data, uint32_t num_samples, + const int32_t *coef, uint32_t coef_order, uint32_t coef_rshift); + +#ifdef __cplusplus +} +#endif + +#endif /* LPC_H_INCLUDED */ diff --git a/libs/lpc/src/CMakeLists.txt b/libs/lpc/src/CMakeLists.txt new file mode 100644 index 0000000..63e5ae0 --- /dev/null +++ b/libs/lpc/src/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/lpc.c + ) diff --git a/libs/lpc/src/lpc.c b/libs/lpc/src/lpc.c new file mode 100644 index 0000000..b1b35ad --- /dev/null +++ b/libs/lpc/src/lpc.c @@ -0,0 +1,1440 @@ +#include "lpc.h" + +#include +#include +#include +#include +#include +#include + +/* メモリアラインメント */ +#define LPC_ALIGNMENT 16 +/* 円周率 */ +#define LPC_PI 3.1415926535897932384626433832795029 +/* 残差絶対値の最小値 */ +#define LPCAF_RESIDUAL_EPSILON 1e-6 + +/* nの倍数切り上げ */ +#define LPC_ROUNDUP(val, n) ((((val) + ((n) - 1)) / (n)) * (n)) +/* 符号関数 */ +#define LPC_SIGN(val) (((val) > 0) - ((val) < 0)) +/* 最大値の取得 */ +#define LPC_MAX(a,b) (((a) > (b)) ? (a) : (b)) +/* 絶対値の取得 */ +#define LPC_ABS(val) (((val) > 0) ? (val) : -(val)) +/* 軟閾値作用素 */ +#define LPC_SOFT_THRESHOLD(in, epsilon) (LPC_SIGN(in) * LPC_MAX(LPC_ABS(in) - (epsilon), 0.0)) + +/* 内部エラー型 */ +typedef enum LPCErrorTag { + LPC_ERROR_OK = 0, + LPC_ERROR_NG, + LPC_ERROR_SINGULAR_MATRIX, + LPC_ERROR_INVALID_ARGUMENT +} LPCError; + +/* LPC計算ハンドル */ +struct LPCCalculator { + uint32_t max_order; /* 最大次数 */ + uint32_t max_num_buffer_samples; /* 最大バッファサンプル数 */ + /* 内部的な計算結果は精度を担保するため全てdoubleで持つ */ + /* floatだとサンプル数を増やすと標本自己相関値の誤差に起因して出力の計算結果がnanになる */ + double **a_vecs; /* 各次数の係数ベクトル */ + double *u_vec; /* 計算用ベクトル3 */ + double *v_vec; /* 計算用ベクトル4 */ + double **r_mat; /* 補助関数法/Burg法で使用する行列((max_order + 1)次) */ + double *auto_corr; /* 標本自己相関 */ + double **lpc_coefs; /* 各次数のLPC係数ベクトル */ + double *parcor_coef; /* PARCOR係数ベクトル */ + double *error_vars; /* 残差分散 */ + double *buffer; /* 入力信号のバッファ領域 */ + uint8_t alloced_by_own; /* 自分で領域確保したか? */ + void *work; /* ワーク領域先頭ポインタ */ +}; + +/* round関数(C89で定義されていない) */ +static double LPC_Round(double d) +{ + return (d >= 0.0) ? floor(d + 0.5) : -floor(-d + 0.5); +} + +/* log2関数(C89で定義されていない) */ +static double LPC_Log2(double d) +{ +#define INV_LOGE2 (1.4426950408889634) /* 1 / log(2) */ + return log(d) * INV_LOGE2; +#undef INV_LOGE2 +} + +/* LPC係数計算ハンドルのワークサイズ計算 */ +int32_t LPCCalculator_CalculateWorkSize(const struct LPCCalculatorConfig *config) +{ + int32_t work_size; + + /* 引数チェック */ + if (config == NULL) { + return -1; + } + + work_size = sizeof(struct LPCCalculator) + LPC_ALIGNMENT; + /* a_vecで使用する領域 */ + work_size += (int32_t)(sizeof(double *) * (config->max_order + 1)); + work_size += (int32_t)(sizeof(double) * (config->max_order + 1) * (config->max_order + 2)); + /* u, v ベクトル分の領域 */ + work_size += (int32_t)(sizeof(double) * (config->max_order + 2) * 2); + /* 標本自己相関の領域 */ + work_size += (int32_t)(sizeof(double) * (config->max_order + 1)); + /* LPC係数ベクトルの領域 */ + work_size += (int32_t)(sizeof(double *) * (config->max_order + 1)); + work_size += (int32_t)(sizeof(double) * (config->max_order + 1) * (config->max_order + 1)); + /* PARCOR係数ベクトルの領域 */ + work_size += (int32_t)(sizeof(double) * (config->max_order + 1)); + /* 残差分散の領域 */ + work_size += (int32_t)(sizeof(double) * (config->max_order + 1)); + /* 補助関数法で使用する行列領域 */ + work_size += (int32_t)(sizeof(double *) * (config->max_order + 1)); + work_size += (int32_t)(sizeof(double) * (config->max_order + 1) * (config->max_order + 1)); + /* 入力信号バッファ領域 */ + work_size += (int32_t)(sizeof(double) * config->max_num_samples); + + return work_size; +} + +/* LPC係数計算ハンドルの作成 */ +struct LPCCalculator* LPCCalculator_Create(const struct LPCCalculatorConfig *config, void *work, int32_t work_size) +{ + struct LPCCalculator *lpcc; + uint8_t *work_ptr; + uint8_t tmp_alloc_by_own = 0; + + /* 自前でワーク領域確保 */ + if ((work == NULL) && (work_size == 0)) { + if ((work_size = LPCCalculator_CalculateWorkSize(config)) < 0) { + return NULL; + } + work = malloc((uint32_t)work_size); + tmp_alloc_by_own = 1; + } + + /* 引数チェック */ + if ((config == NULL) || (work == NULL) + || (work_size < LPCCalculator_CalculateWorkSize(config)) + || (config->max_order == 0) || (config->max_num_samples == 0)) { + if (tmp_alloc_by_own == 1) { + free(work); + } + return NULL; + } + + /* ワーク領域取得 */ + work_ptr = (uint8_t *)work; + + /* ハンドル領域確保 */ + work_ptr = (uint8_t *)LPC_ROUNDUP((uintptr_t)work_ptr, LPC_ALIGNMENT); + lpcc = (struct LPCCalculator *)work_ptr; + work_ptr += sizeof(struct LPCCalculator); + + /* ハンドルメンバの設定 */ + lpcc->max_order = config->max_order; + lpcc->max_num_buffer_samples = config->max_num_samples; + lpcc->work = work; + lpcc->alloced_by_own = tmp_alloc_by_own; + + /* 計算用ベクトルの領域割当 */ + { + uint32_t ord; + lpcc->a_vecs = (double **)work_ptr; + work_ptr += sizeof(double *) * (config->max_order + 1); + for (ord = 0; ord < config->max_order + 1; ord++) { + lpcc->a_vecs[ord] = (double *)work_ptr; + work_ptr += sizeof(double) * (config->max_order + 2); /* a_0, a_k+1を含めるとmax_order+2 */ + } + } + lpcc->u_vec = (double *)work_ptr; + work_ptr += sizeof(double) * (config->max_order + 2); + lpcc->v_vec = (double *)work_ptr; + work_ptr += sizeof(double) * (config->max_order + 2); + + /* 標本自己相関の領域割当 */ + lpcc->auto_corr = (double *)work_ptr; + work_ptr += sizeof(double) * (config->max_order + 1); + + /* LPC係数ベクトルの領域割当 */ + { + uint32_t ord; + lpcc->lpc_coefs = (double **)work_ptr; + work_ptr += sizeof(double *) * (config->max_order + 1); + for (ord = 0; ord < config->max_order + 1; ord++) { + lpcc->lpc_coefs[ord] = (double *)work_ptr; + work_ptr += sizeof(double) * (config->max_order + 1); + } + } + + /* PARCOR係数ベクトルの領域割当 */ + lpcc->parcor_coef = (double *)work_ptr; + work_ptr += sizeof(double) * (config->max_order + 1); + + /* 残差分散の領域割り当て */ + lpcc->error_vars = (double *)work_ptr; + work_ptr += sizeof(double) * (config->max_order + 1); + + /* 補助関数法/Burg法で使用する行列領域 */ + { + uint32_t ord; + lpcc->r_mat = (double **)work_ptr; + work_ptr += sizeof(double *) * (config->max_order + 1); + for (ord = 0; ord < config->max_order + 1; ord++) { + lpcc->r_mat[ord] = (double *)work_ptr; + work_ptr += sizeof(double) * (config->max_order + 1); + } + } + + /* 入力信号バッファの領域 */ + lpcc->buffer = (double *)work_ptr; + work_ptr += sizeof(double) * config->max_num_samples; + + /* バッファオーバーフローチェック */ + assert((work_ptr - (uint8_t *)work) <= work_size); + + return lpcc; +} + +/* LPC係数計算ハンドルの破棄 */ +void LPCCalculator_Destroy(struct LPCCalculator *lpcc) +{ + if (lpcc != NULL) { + /* ワーク領域を時前確保していたときは開放 */ + if (lpcc->alloced_by_own == 1) { + free(lpcc->work); + } + } +} + +/* 窓関数の適用 */ +static LPCError LPC_ApplyWindow( + LPCWindowType window_type, const double *input, uint32_t num_samples, double *output) +{ + /* 引数チェック */ + if (input == NULL || output == NULL) { + return LPC_ERROR_INVALID_ARGUMENT; + } + + switch (window_type) { + case LPC_WINDOWTYPE_RECTANGULAR: + memcpy(output, input, sizeof(double) * num_samples); + break; + case LPC_WINDOWTYPE_SIN: + { + uint32_t smpl; + for (smpl = 0; smpl < num_samples; smpl++) { + output[smpl] = input[smpl] * sin((LPC_PI * smpl) / (num_samples - 1)); + } + } + break; + case LPC_WINDOWTYPE_WELCH: + { + uint32_t smpl; + const double divisor = 4.0 * pow(num_samples - 1, -2.0); + for (smpl = 0; smpl < (num_samples >> 1); smpl++) { + const double weight = divisor * smpl * (num_samples - 1 - smpl); + output[smpl] = input[smpl] * weight; + output[num_samples - smpl - 1] = input[num_samples - smpl - 1] * weight; + } + } + break; + default: + return LPC_ERROR_NG; + } + + return LPC_ERROR_OK; +} + +/*(標本)自己相関の計算 */ +static LPCError LPC_CalculateAutoCorrelation( + const double *data, uint32_t num_samples, double *auto_corr, uint32_t order) +{ + uint32_t i, lag; + double tmp; + + assert(num_samples >= order); + + /* 引数チェック */ + if (data == NULL || auto_corr == NULL) { + return LPC_ERROR_INVALID_ARGUMENT; + } + + /* 係数初期化 */ + for (lag = 0; lag < order; lag++) { + auto_corr[lag] = 0.0; + } + + /* 次数の代わりにデータ側のラグに注目した自己相関係数計算 */ + for (i = 0; i <= num_samples - order; i++) { + tmp = data[i]; + /* 同じラグを持ったデータ積和を取る */ + for (lag = 0; lag < order; lag++) { + auto_corr[lag] += tmp * data[i + lag]; + } + } + for (; i < num_samples; i++) { + tmp = data[i]; + for (lag = 0; lag < num_samples - i; lag++) { + auto_corr[lag] += tmp * data[i + lag]; + } + } + + return LPC_ERROR_OK; +} + +/* Levinson-Durbin再帰計算 */ +static LPCError LPC_LevinsonDurbinRecursion(struct LPCCalculator *lpcc, + const double *auto_corr, uint32_t coef_order, double **lpc_coefs, double *parcor_coef, double *error_vars) +{ + uint32_t k, i; + double gamma; /* 反射係数 */ + + /* オート変数にポインタをコピー */ + double **a_vecs = lpcc->a_vecs; + double *u_vec = lpcc->u_vec; + double *v_vec = lpcc->v_vec; + + /* 引数チェック */ + if ((lpcc == NULL) || (auto_corr == NULL) || (lpc_coefs == NULL) || (parcor_coef == NULL)) { + return LPC_ERROR_INVALID_ARGUMENT; + } + + /* 0次自己相関(信号の二乗和)が小さい場合 + * => 係数は全て0として無音出力システムを予測 */ + if (fabs(auto_corr[0]) < FLT_EPSILON) { + for (i = 0; i < coef_order + 1; i++) { + parcor_coef[i] = 0.0; + } + for (k = 0; k < coef_order; k++) { + for (i = 0; i < coef_order + 1; i++) { + lpc_coefs[k][i] = 0.0; + } + } + return LPC_ERROR_OK; + } + + /* 初期化 */ + for (i = 0; i < coef_order + 2; i++) { + u_vec[i] = v_vec[i] = 0.0; + } + for (k = 0; k < coef_order + 1; k++) { + for (i = 0; i < coef_order + 2; i++) { + a_vecs[k][i] = 0.0; + } + } + + /* 最初のステップの係数をセット */ + a_vecs[0][0] = 1.0; + error_vars[0] = auto_corr[0]; + a_vecs[0][1] = - auto_corr[1] / auto_corr[0]; + parcor_coef[0] = auto_corr[1] / error_vars[0]; + error_vars[1] = error_vars[0] + auto_corr[1] * a_vecs[0][1]; + u_vec[0] = 1.0; u_vec[1] = 0.0; + v_vec[0] = 0.0; v_vec[1] = 1.0; + + /* 再帰処理 */ + for (k = 1; k < coef_order; k++) { + gamma = 0.0; + for (i = 0; i < k + 1; i++) { + gamma += a_vecs[k - 1][i] * auto_corr[k + 1 - i]; + } + gamma /= -error_vars[k]; + error_vars[k + 1] = error_vars[k] * (1.0 - gamma * gamma); + /* 誤差分散(パワー)は非負 */ + assert(error_vars[k + 1] >= 0.0); + + /* u_vec, v_vecの更新 */ + for (i = 0; i < k; i++) { + u_vec[i + 1] = v_vec[k - i] = a_vecs[k - 1][i + 1]; + } + u_vec[0] = 1.0; u_vec[k + 1] = 0.0; + v_vec[0] = 0.0; v_vec[k + 1] = 1.0; + + /* 係数の更新 */ + for (i = 0; i < k + 2; i++) { + a_vecs[k][i] = u_vec[i] + gamma * v_vec[i]; + } + /* PARCOR係数は反射係数の符号反転 */ + parcor_coef[k] = -gamma; + /* PARCOR係数の絶対値は1未満(収束条件) */ + assert(fabs(gamma) < 1.0); + } + + /* 結果を取得 */ + for (k = 0; k < coef_order; k++) { + memcpy(lpc_coefs[k], &a_vecs[k][1], sizeof(double) * coef_order); + } + + return LPC_ERROR_OK; +} + +/* 係数計算の共通関数 */ +static LPCError LPC_CalculateCoef( + struct LPCCalculator *lpcc, const double *data, uint32_t num_samples, uint32_t coef_order, + LPCWindowType window_type, double regular_term) +{ + /* 引数チェック */ + if (lpcc == NULL) { + return LPC_ERROR_INVALID_ARGUMENT; + } + + /* 窓関数を適用 */ + if (LPC_ApplyWindow(window_type, data, num_samples, lpcc->buffer) != LPC_ERROR_OK) { + return LPC_ERROR_NG; + } + + /* 自己相関を計算 */ + if (LPC_CalculateAutoCorrelation( + lpcc->buffer, num_samples, lpcc->auto_corr, coef_order + 1) != LPC_ERROR_OK) { + return LPC_ERROR_NG; + } + + /* 入力サンプル数が少ないときは、係数が発散することが多数 + * => 無音データとして扱い、係数はすべて0とする */ + if (num_samples < coef_order) { + uint32_t i, k; + for (i = 0; i < coef_order + 1; i++) { + lpcc->parcor_coef[i] = 0.0; + } + for (k = 0; k < coef_order + 1; k++) { + for (i = 0; i < coef_order + 1; i++) { + lpcc->lpc_coefs[k][i] = 0.0; + } + } + return LPC_ERROR_OK; + } + + /* 0次相関を強調(Ridge正則化) */ + lpcc->auto_corr[0] *= (1.0 + regular_term); + + /* 再帰計算を実行 */ + if (LPC_LevinsonDurbinRecursion(lpcc, lpcc->auto_corr, coef_order, lpcc->lpc_coefs, lpcc->parcor_coef, lpcc->error_vars) != LPC_ERROR_OK) { + return LPC_ERROR_NG; + } + + return LPC_ERROR_OK; +} + +/* Levinson-Durbin再帰計算によりLPC係数を求める(倍精度) */ +LPCApiResult LPCCalculator_CalculateLPCCoefficients( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, double *lpc_coef, uint32_t coef_order, + LPCWindowType window_type, double regular_term) +{ + /* 引数チェック */ + if ((data == NULL) || (lpc_coef == NULL)) { + return LPC_APIRESULT_INVALID_ARGUMENT; + } + + /* 次数チェック */ + if (coef_order > lpcc->max_order) { + return LPC_APIRESULT_EXCEED_MAX_ORDER; + } + + /* 入力サンプル数チェック */ + if (num_samples > lpcc->max_num_buffer_samples) { + return LPC_APIRESULT_EXCEED_MAX_NUM_SAMPLES; + } + + /* 係数計算 */ + if (LPC_CalculateCoef(lpcc, data, num_samples, coef_order, window_type, regular_term) != LPC_ERROR_OK) { + return LPC_APIRESULT_FAILED_TO_CALCULATION; + } + + /* 計算成功時は結果をコピー */ + memmove(lpc_coef, lpcc->lpc_coefs[coef_order - 1], sizeof(double) * coef_order); + + return LPC_APIRESULT_OK; +} + +/* Levinson-Durbin再帰計算により与えられた次数まで全てのLPC係数を求める(倍精度) */ +LPCApiResult LPCCalculator_CalculateMultipleLPCCoefficients( + struct LPCCalculator* lpcc, + const double* data, uint32_t num_samples, double **lpc_coefs, uint32_t max_coef_order, + LPCWindowType window_type, double regular_term) +{ + uint32_t k; + + /* 引数チェック */ + if ((data == NULL) || (lpc_coefs == NULL)) { + return LPC_APIRESULT_INVALID_ARGUMENT; + } + + /* 次数チェック */ + if (max_coef_order > lpcc->max_order) { + return LPC_APIRESULT_EXCEED_MAX_ORDER; + } + + /* 入力サンプル数チェック */ + if (num_samples > lpcc->max_num_buffer_samples) { + return LPC_APIRESULT_EXCEED_MAX_NUM_SAMPLES; + } + + /* 係数計算 */ + if (LPC_CalculateCoef(lpcc, data, num_samples, max_coef_order, window_type, regular_term) != LPC_ERROR_OK) { + return LPC_APIRESULT_FAILED_TO_CALCULATION; + } + + /* 計算成功時は結果をコピー */ + for (k = 0; k < max_coef_order; k++) { + memmove(lpc_coefs[k], lpcc->lpc_coefs[k], sizeof(double) * max_coef_order); + } + + return LPC_APIRESULT_OK; +} + +/* Levinson-Durbin再帰計算により与えられた次数までの残差分散を求める(倍精度) */ +LPCApiResult LPCCalculator_CalculateErrorVariances( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, double *error_vars, uint32_t max_coef_order, + LPCWindowType window_type, double regular_term) +{ + /* 引数チェック */ + if ((data == NULL) || (error_vars == NULL)) { + return LPC_APIRESULT_INVALID_ARGUMENT; + } + + /* 次数チェック */ + if (max_coef_order > lpcc->max_order) { + return LPC_APIRESULT_EXCEED_MAX_ORDER; + } + + /* 入力サンプル数チェック */ + if (num_samples > lpcc->max_num_buffer_samples) { + return LPC_APIRESULT_EXCEED_MAX_NUM_SAMPLES; + } + + /* 係数計算 */ + if (LPC_CalculateCoef(lpcc, data, num_samples, max_coef_order, window_type, regular_term) != LPC_ERROR_OK) { + return LPC_APIRESULT_FAILED_TO_CALCULATION; + } + + /* 計算成功時は結果をコピー */ + memmove(error_vars, lpcc->error_vars, sizeof(double) * (max_coef_order + 1)); + + return LPC_APIRESULT_OK; +} + +/* コレスキー分解 */ +static LPCError LPC_CholeskyDecomposition( + double **Amat, int32_t dim, double *inv_diag) +{ + int32_t i, j, k; + double sum; + + /* 引数チェック */ + assert((Amat != NULL) && (inv_diag != NULL)); + + for (i = 0; i < dim; i++) { + sum = Amat[i][i]; + for (k = i - 1; k >= 0; k--) { + sum -= Amat[i][k] * Amat[i][k]; + } + if (sum <= 0.0) { + return LPC_ERROR_SINGULAR_MATRIX; + } + /* 1.0 / sqrt(sum) は除算により桁落ちするためpowを使用 */ + inv_diag[i] = pow(sum, -0.5); + for (j = i + 1; j < dim; j++) { + sum = Amat[i][j]; + for (k = i - 1; k >= 0; k--) { + sum -= Amat[i][k] * Amat[j][k]; + } + Amat[j][i] = sum * inv_diag[i]; + } + } + + return LPC_ERROR_OK; +} + +/* コレスキー分解により Amat * xvec = bvec を解く */ +static LPCError LPC_SolveByCholeskyDecomposition( + const double * const* Amat, int32_t dim, double *xvec, const double *bvec, const double *inv_diag) +{ + int32_t i, j; + double sum; + + /* 引数チェック */ + assert((Amat != NULL) && (inv_diag != NULL) && (bvec != NULL) && (xvec != NULL)); + + /* 分解を用いて線形一次方程式を解く */ + for (i = 0; i < dim; i++) { + sum = bvec[i]; + for (j = i - 1; j >= 0; j--) { + sum -= Amat[i][j] * xvec[j]; + } + xvec[i] = sum * inv_diag[i]; + } + for (i = dim - 1; i >= 0; i--) { + sum = xvec[i]; + for (j = i + 1; j < dim; j++) { + sum -= Amat[j][i] * xvec[j]; + } + xvec[i] = sum * inv_diag[i]; + } + + return LPC_ERROR_OK; +} + +#if 1 +/* 補助関数法(前向き残差)による係数行列計算 */ +static LPCError LPCAF_CalculateCoefMatrixAndVector( + const double *data, uint32_t num_samples, + const double *a_vec, double **r_mat, double *r_vec, + uint32_t coef_order, double *pobj_value) +{ + double obj_value; + uint32_t smpl, i, j; + + assert(data != NULL); + assert(a_vec != NULL); + assert(r_mat != NULL); + assert(r_vec != NULL); + assert(pobj_value != NULL); + assert(num_samples > coef_order); + + /* 行列を0初期化 */ + for (i = 0; i < coef_order; i++) { + r_vec[i] = 0.0; + for (j = 0; j < coef_order; j++) { + r_mat[i][j] = 0.0; + } + } + + obj_value = 0.0; + + for (smpl = coef_order; smpl < num_samples; smpl++) { + /* 残差計算 */ + double residual = data[smpl]; + double inv_residual; + for (i = 0; i < coef_order; i++) { + residual += a_vec[i] * data[smpl - i - 1]; + } + residual = fabs(residual); + obj_value += residual; + /* 小さすぎる残差は丸め込む(ゼERO割回避、正則化) */ + residual = (residual < LPCAF_RESIDUAL_EPSILON) ? LPCAF_RESIDUAL_EPSILON : residual; + inv_residual = 1.0 / residual; + /* 係数行列に蓄積 */ + for (i = 0; i < coef_order; i++) { + r_vec[i] -= data[smpl] * data[smpl - i - 1] * inv_residual; + for (j = i; j < coef_order; j++) { + r_mat[i][j] += data[smpl - i - 1] * data[smpl - j - 1] * inv_residual; + } + } + } + + /* 対称要素に拡張 */ + for (i = 0; i < coef_order; i++) { + for (j = i + 1; j < coef_order; j++) { + r_mat[j][i] = r_mat[i][j]; + } + } + + /* 目的関数値のセット */ + (*pobj_value) = obj_value / (num_samples - coef_order); + + return LPC_ERROR_OK; +} +#else +/* 補助関数法(前向き後ろ向き残差)による係数行列計算 */ +static LPCError LPCAF_CalculateCoefMatrixAndVector( + const double *data, uint32_t num_samples, + const double *a_vec, double **r_mat, double *r_vec, + uint32_t coef_order, double *pobj_value) +{ + double obj_value; + uint32_t smpl, i, j; + + assert(data != NULL); + assert(a_vec != NULL); + assert(r_mat != NULL); + assert(r_vec != NULL); + assert(pobj_value != NULL); + assert(num_samples > coef_order); + + /* 行列を0初期化 */ + for (i = 0; i < coef_order; i++) { + r_vec[i] = 0.0; + for (j = 0; j < coef_order; j++) { + r_mat[i][j] = 0.0; + } + } + + obj_value = 0.0; + + for (smpl = coef_order; smpl < num_samples - coef_order; smpl++) { + /* 残差計算 */ + double forward = data[smpl], backward = data[smpl]; + double inv_forward, inv_backward; + for (i = 0; i < coef_order; i++) { + forward += a_vec[i] * data[smpl - i - 1]; + backward += a_vec[i] * data[smpl + i + 1]; + } + forward = fabs(forward); + backward = fabs(backward); + obj_value += (forward + backward); + /* 小さすぎる残差は丸め込む(ゼERO割回避、正則化) */ + forward = (forward < LPCAF_RESIDUAL_EPSILON) ? LPCAF_RESIDUAL_EPSILON : forward; + backward = (backward < LPCAF_RESIDUAL_EPSILON) ? LPCAF_RESIDUAL_EPSILON : backward; + inv_forward = 1.0 / forward; + inv_backward = 1.0 / backward; + /* 係数行列に足し込み */ + for (i = 0; i < coef_order; i++) { + r_vec[i] -= data[smpl] * data[smpl - i - 1] * inv_forward; + r_vec[i] -= data[smpl] * data[smpl + i + 1] * inv_backward; + for (j = i; j < coef_order; j++) { + r_mat[i][j] += data[smpl - i - 1] * data[smpl - j - 1] * inv_forward; + r_mat[i][j] += data[smpl + i + 1] * data[smpl + j + 1] * inv_backward; + } + } + } + + /* 対称要素に拡張 */ + for (i = 0; i < coef_order; i++) { + for (j = i + 1; j < coef_order; j++) { + r_mat[j][i] = r_mat[i][j]; + } + } + + (*pobj_value) = obj_value / (2.0 * (num_samples - (2.0 * coef_order))); + + return LPC_ERROR_OK; +} +#endif + +/* 補助関数法による係数計算 */ +static LPCError LPC_CalculateCoefAF( + struct LPCCalculator *lpcc, const double *data, uint32_t num_samples, uint32_t coef_order, + const uint32_t max_num_iteration, const double obj_epsilon, LPCWindowType window_type, double regular_term) +{ + uint32_t itr, i; + double *a_vec = lpcc->a_vecs[0]; + double *r_vec = lpcc->u_vec; + double **r_mat = lpcc->r_mat; + double obj_value, prev_obj_value; + LPCError err; + + /* 係数をLebinson-Durbin法で初期化 */ + if ((err = LPC_CalculateCoef(lpcc, data, num_samples, coef_order, window_type, regular_term)) != LPC_ERROR_OK) { + return err; + } + memcpy(a_vec, lpcc->lpc_coefs[coef_order - 1], sizeof(double) * coef_order); + + /* 0次自己相関(信号の二乗和)が小さい場合 + * => 係数は全て0として無音出力システムを予測 */ + if (fabs(lpcc->auto_corr[0]) < FLT_EPSILON) { + for (i = 0; i < coef_order + 1; i++) { + lpcc->lpc_coefs[coef_order - 1][i] = 0.0; + } + return LPC_ERROR_OK; + } + + prev_obj_value = FLT_MAX; + for (itr = 0; itr < max_num_iteration; itr++) { + /* 係数行列要素の計算 */ + if ((err = LPCAF_CalculateCoefMatrixAndVector( + data, num_samples, a_vec, r_mat, r_vec, coef_order, &obj_value)) != LPC_ERROR_OK) { + return err; + } + /* コレスキー分解 */ + if ((err = LPC_CholeskyDecomposition( + r_mat, (int32_t)coef_order, lpcc->v_vec)) == LPC_ERROR_SINGULAR_MATRIX) { + /* 特異行列になるのは理論上入力が全部0のとき。係数を0クリアして終わる */ + for (i = 0; i < coef_order; i++) { + lpcc->lpc_coefs[coef_order - 1][i] = 0.0; + } + return LPC_ERROR_OK; + } + /* コレスキー分解で r_mat @ avec = r_vec を解く */ + if ((err = LPC_SolveByCholeskyDecomposition( + r_mat, (int32_t)coef_order, a_vec, r_vec, lpcc->v_vec)) != LPC_ERROR_OK) { + return err; + } + assert(err == LPC_ERROR_OK); + /* 収束判定 */ + if (fabs(prev_obj_value - obj_value) < obj_epsilon) { + break; + } + prev_obj_value = obj_value; + } + + /* 解を設定 */ + memmove(lpcc->lpc_coefs[coef_order - 1], a_vec, sizeof(double) * coef_order); + + return LPC_ERROR_OK; +} + +/* 補助関数法よりLPC係数を求める(倍精度) */ +LPCApiResult LPCCalculator_CalculateLPCCoefficientsAF( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, double *coef, uint32_t coef_order, + uint32_t max_num_iteration, LPCWindowType window_type, double regular_term) +{ + /* 引数チェック */ + if ((lpcc == NULL) || (data == NULL) || (coef == NULL)) { + return LPC_APIRESULT_INVALID_ARGUMENT; + } + + /* 次数チェック */ + if (coef_order > lpcc->max_order) { + return LPC_APIRESULT_EXCEED_MAX_ORDER; + } + + /* 係数計算 */ + if (LPC_CalculateCoefAF(lpcc, data, num_samples, coef_order, + max_num_iteration, 1e-8, window_type, regular_term) != LPC_ERROR_OK) { + return LPC_APIRESULT_FAILED_TO_CALCULATION; + } + + /* 計算成功時は結果をコピー */ + memmove(coef, lpcc->lpc_coefs[coef_order - 1], sizeof(double) * coef_order); + + return LPC_APIRESULT_OK; +} + +/* Burg法による係数計算 */ +static LPCError LPC_CalculateCoefBurg( + struct LPCCalculator *lpcc, const double *data, uint32_t num_samples, uint32_t coef_order) +{ +#if 1 + uint32_t i, j, k; + double *a_vec = lpcc->a_vecs[0]; + double **cov = lpcc->r_mat; + LPCError err; + + /* 自己共分散行列計算 */ + for (i = 0; i <= coef_order; i++) { + if ((err = LPC_CalculateAutoCorrelation( + data, num_samples - i, &cov[i][i], coef_order + 1 - i)) != LPC_ERROR_OK) { + return err; + } + for (j = i + 1; j <= coef_order; j++) { + cov[j][i] = cov[i][j]; + } + } + + /* 係数初期化 */ + for (i = 0; i <= coef_order; i++) { + a_vec[i] = 0.0; + } + a_vec[0] = 1.0; + + /* 次数ごとに計算 */ + for (k = 0; k < coef_order; k++) { + double mu; + double FkpBk = 0.0, sum = 0.0, Ck = 0.0; + /* Fk + Bk */ + for (i = 0; i <= k; i++) { + FkpBk += a_vec[i] * a_vec[i] * (cov[i][i] + cov[k + 1 - i][k + 1 - i]); + /* 対角成分以外は対称性を使って半分だけ計算 */ + for (j = i + 1; j <= k; j++) { + sum += a_vec[i] * a_vec[j] * (cov[i][j] + cov[k + 1 - i][k + 1 - j]); + } + } + FkpBk += 2.0 * sum; + /* Ck */ + for (i = 0; i <= k; i++) { + for (j = 0; j <= k; j++) { + Ck += a_vec[i] * a_vec[j] * cov[i][k + 1 - j]; + } + } + /* 反射係数の負号 */ + mu = - 2.0 * Ck / FkpBk; + assert(fabs(mu) <= 1.0); + /* 係数更新 */ + for (i = 0; i <= (k + 1) / 2; i++) { + double tmp1, tmp2; + tmp1 = a_vec[i]; tmp2 = a_vec[k + 1 - i]; + a_vec[i] = tmp1 + mu * tmp2; + a_vec[k + 1 - i] = mu * tmp1 + tmp2; + } + } + + /* 解を設定 */ + memmove(lpcc->lpc_coefs[coef_order - 1], &a_vec[1], sizeof(double) * coef_order); +#else + uint32_t i, k; + double *a_vec = lpcc->a_vec; + double *f_vec, *b_vec; + double Dk, mu; + double tmp1, tmp2; + + /* ベクトル領域割り当て */ + f_vec = malloc(sizeof(double) * num_samples); + b_vec = malloc(sizeof(double) * num_samples); + + /* 各ベクトル初期化 */ + for (k = 0; k < coef_order + 1; k++) { + a_vec[k] = 0.0; + } + a_vec[0] = 1.0; + memcpy(f_vec, data, sizeof(double) * num_samples); + memcpy(b_vec, data, sizeof(double) * num_samples); + + /* Dkの初期化 */ + Dk = 0.0; + for (i = 0; i < num_samples; i++) { + Dk += 2.0 * f_vec[i] * f_vec[i]; + } + Dk -= f_vec[0] * f_vec[0] + f_vec[num_samples - 1] * f_vec[num_samples - 1]; + + /* Burg 再帰アルゴリズム */ + for (k = 0; k < coef_order; k++) { + /* 反射(PARCOR)係数の計算 */ + mu = 0.0; + for (i = 0; i < num_samples - k - 1; i++) { + mu += f_vec[i + k + 1] * b_vec[i]; + } + mu *= -2.0 / Dk; + assert(fabs(mu) < 1.0); + /* a_vecの更新 */ + for (i = 0; i <= (k + 1) / 2; i++) { + tmp1 = a_vec[i]; tmp2 = a_vec[k + 1 - i]; + a_vec[i] = tmp1 + mu * tmp2; + a_vec[k + 1 - i] = mu * tmp1 + tmp2; + } + /* f_vec, b_vecの更新 */ + for (i = 0; i < num_samples - k - 1; i++) { + tmp1 = f_vec[i + k + 1]; tmp2 = b_vec[i]; + f_vec[i + k + 1] = tmp1 + mu * tmp2; + b_vec[i] = mu * tmp1 + tmp2; + } + /* Dkの更新 */ + Dk = (1.0 - mu * mu) * Dk - f_vec[k + 1] * f_vec[k + 1] - b_vec[num_samples - k - 2] * b_vec[num_samples - k - 2]; + } + + /* 係数コピー */ + memcpy(lpcc->lpc_coef, &a_vec[1], sizeof(double) * coef_order); + + free(b_vec); + free(f_vec); +#endif + return LPC_ERROR_OK; +} + +/* Burg法によりLPC係数を求める(倍精度) */ +LPCApiResult LPCCalculator_CalculateLPCCoefficientsBurg( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, double *coef, uint32_t coef_order) +{ + /* 引数チェック */ + if ((lpcc == NULL) || (data == NULL) || (coef == NULL)) { + return LPC_APIRESULT_INVALID_ARGUMENT; + } + + /* 次数チェック */ + if (coef_order > lpcc->max_order) { + return LPC_APIRESULT_EXCEED_MAX_ORDER; + } + + /* 係数計算 */ + if (LPC_CalculateCoefBurg(lpcc, data, num_samples, coef_order) != LPC_ERROR_OK) { + return LPC_APIRESULT_FAILED_TO_CALCULATION; + } + + /* 計算成功時は結果をコピー */ + memmove(coef, lpcc->lpc_coefs[coef_order - 1], sizeof(double) * coef_order); + + return LPC_APIRESULT_OK; +} + +/* 共分散行列の計算 */ +static LPCError LPCSVR_CalculateCovarianceMatrix( + const double *data, uint32_t num_samples, double **cov, uint32_t dim) +{ + uint32_t i, j, smpl; + + /* 引数チェック */ + if ((data == NULL) || (cov == NULL)) { + return LPC_ERROR_INVALID_ARGUMENT; + } + + for (i = 0; i < dim; i++) { + for (j = i; j < dim; j++) { + cov[i][j] = 0.0; + } + } + + for (smpl = 0; smpl < num_samples - dim; smpl++) { + const double *pdata = &data[smpl]; + for (i = 0; i < dim; i++) { + const double s = pdata[i]; + for (j = i; j < dim; j++) { + cov[i][j] += s * pdata[j]; + } + } + } + + for (i = 0; i < dim; i++) { + for (j = i + 1; j < dim; j++) { + cov[j][i] = cov[i][j]; + } + } + + return LPC_ERROR_OK; +} + +/* Recursive Golomb-Rice符号の平均符号長 */ +static double LPCSVR_CalculateRGRMeanCodeLength(double mean_abs_error, uint32_t bps) +{ + const double intmean = mean_abs_error * (1 << bps); /* 整数量子化した時の平均値 */ + const double rho = 1.0 / (1.0 + intmean); + const uint32_t k2 = (uint32_t)LPC_MAX(0, LPC_Log2(log(0.5127629514) / log(1.0 - rho))); + const uint32_t k1 = k2 + 1; + const double k1factor = pow(1.0 - rho, (double)(1 << k1)); + const double k2factor = pow(1.0 - rho, (double)(1 << k2)); + return (1.0 + k1) * (1.0 - k1factor) + (1.0 + k2 + (1.0 / (1.0 - k2factor))) * k1factor; +} + +/* SVRによる係数計算 */ +static LPCError LPC_CalculateCoefSVR( + struct LPCCalculator *lpcc, const double *data, uint32_t num_samples, uint32_t coef_order, + const uint32_t max_num_iteration, const double obj_epsilon, LPCWindowType window_type, + double regular_term, const double *margin_list, uint32_t margin_list_size) +{ +#define BITS_PER_SAMPLE 16 + uint32_t itr, i, j, smpl; + double *coef = lpcc->a_vecs[0]; + double *r_vec = lpcc->u_vec; + double *low = lpcc->v_vec; + double *best_coef = lpcc->lpc_coefs[0]; + double *delta = lpcc->parcor_coef; + double *init_coef = lpcc->auto_corr; + double **cov = lpcc->r_mat; + double *residual = lpcc->buffer; + double obj_value, prev_obj_value, min_obj_value; + LPCError err; + + /* 引数チェック */ + if ((lpcc == NULL) || (data == NULL) || (margin_list == NULL) || (margin_list_size == 0)) { + return LPC_ERROR_INVALID_ARGUMENT; + } + + /* Levinson-Durbin法で係数を求める */ + if ((err = LPC_CalculateCoef(lpcc, data, num_samples, coef_order, window_type, 0.0)) != LPC_ERROR_OK) { + return err; + } + /* 0次自己相関(信号の二乗和)が小さい場合 + * => 係数は全て0として無音出力システムを予測 */ + if (fabs(lpcc->auto_corr[0]) < FLT_EPSILON) { + for (i = 0; i < coef_order + 1; i++) { + lpcc->lpc_coefs[coef_order - 1][i] = 0.0; + } + return LPC_ERROR_OK; + } + + /* 学習しない場合はLevinson-Durbin法の結果をそのまま採用 */ + if (max_num_iteration == 0) { + return LPC_ERROR_OK; + } + + /* 共分散行列の計算 */ + if ((err = LPCSVR_CalculateCovarianceMatrix(data, num_samples, cov, coef_order)) != LPC_ERROR_OK) { + return err; + } + /* Ridge正則化 */ + for (i = 0; i < coef_order; i++) { + cov[i][i] += regular_term; + } + /* コレスキー分解 */ + if ((err = LPC_CholeskyDecomposition(cov, (int32_t)coef_order, low)) == LPC_ERROR_SINGULAR_MATRIX) { + /* 特異行列になるのは理論上入力が全部0のとき。係数を0クリアして終わる */ + for (i = 0; i < coef_order; i++) { + lpcc->lpc_coefs[coef_order - 1][i] = 0.0; + } + return LPC_ERROR_OK; + } + + /* 初期値をLevinson-Durbin法の係数に設定 */ + memcpy(init_coef, lpcc->lpc_coefs[coef_order - 1], sizeof(double) * coef_order); + + /* TODO: 係数は順序反転した方がresidualの計算が早そう(要検証) */ + + min_obj_value = FLT_MAX; + for (j = 0; j < margin_list_size; j++) { + const double margin = margin_list[j]; + prev_obj_value = FLT_MAX; + memcpy(coef, init_coef, sizeof(double) * coef_order); + for (itr = 0; itr < max_num_iteration; itr++) { + double mabse = 0.0; + /* 残差計算/残差ソフトスレッショルド */ + memcpy(residual, data, sizeof(double) * num_samples); + for (i = 0; i < coef_order; i++) { + r_vec[i] = 0.0; + } + for (smpl = coef_order; smpl < num_samples; smpl++) { + for (i = 0; i < coef_order; i++) { + residual[smpl] += coef[i] * data[smpl - i - 1]; + } + mabse += LPC_ABS(residual[smpl]); + residual[smpl] = LPC_SOFT_THRESHOLD(residual[smpl], margin); + for (i = 0; i < coef_order; i++) { + r_vec[i] += residual[smpl] * data[smpl - i - 1]; + } + } + obj_value = LPCSVR_CalculateRGRMeanCodeLength(mabse / num_samples, BITS_PER_SAMPLE); + /* コレスキー分解で cov @ delta = r_vec を解く */ + if ((err = LPC_SolveByCholeskyDecomposition( + cov, (int32_t)coef_order, delta, r_vec, low)) != LPC_ERROR_OK) { + return err; + } + /* 最善係数の更新 */ + if (obj_value < min_obj_value) { + memcpy(best_coef, coef, sizeof(double) * coef_order); + min_obj_value = obj_value; + } + /* 収束判定 */ + if ((prev_obj_value < obj_value) || (fabs(prev_obj_value - obj_value) < obj_epsilon)) { + break; + } + /* 係数更新 */ + for (i = 0; i < coef_order; i++) { + coef[i] += delta[i]; + } + prev_obj_value = obj_value; + } + } + + /* 解を設定 */ + memmove(lpcc->lpc_coefs[coef_order - 1], best_coef, sizeof(double) * coef_order); + + return LPC_ERROR_OK; +#undef BITS_PER_SAMPLE +} + +/* SVRよりLPC係数を求める(倍精度) */ +LPCApiResult LPCCalculator_CalculateLPCCoefficientsSVR( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, double *coef, uint32_t coef_order, + uint32_t max_num_iteration, LPCWindowType window_type, + double regular_term, const double *margin_list, uint32_t margin_list_size) +{ + /* 引数チェック */ + if ((lpcc == NULL) || (data == NULL) || (coef == NULL) + || (margin_list == NULL) || (margin_list_size == 0)) { + return LPC_APIRESULT_INVALID_ARGUMENT; + } + + /* 次数チェック */ + if (coef_order > lpcc->max_order) { + return LPC_APIRESULT_EXCEED_MAX_ORDER; + } + + /* 係数計算 */ + if (LPC_CalculateCoefSVR(lpcc, data, num_samples, coef_order, + max_num_iteration, 1e-8, window_type, regular_term, margin_list, margin_list_size) != LPC_ERROR_OK) { + return LPC_APIRESULT_FAILED_TO_CALCULATION; + } + + /* 計算成功時は結果をコピー */ + memmove(coef, lpcc->lpc_coefs[coef_order - 1], sizeof(double) * coef_order); + + return LPC_APIRESULT_OK; +} + +/* 入力データからサンプルあたりの推定符号長を求める */ +LPCApiResult LPCCalculator_EstimateCodeLength( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, uint32_t bits_per_sample, + uint32_t coef_order, double *length_per_sample_bits, LPCWindowType window_type) +{ + uint32_t ord; + double log2_mean_res_power, log2_var_ratio; + + /* 定数値 */ +#define BETA_CONST_FOR_LAPLACE_DIST (1.9426950408889634) /* sqrt(2 * E * E) */ +#define BETA_CONST_FOR_GAUSS_DIST (2.047095585180641) /* sqrt(2 * E * PI) */ + + /* 引数チェック */ + if ((lpcc == NULL) || (data == NULL) || (length_per_sample_bits == NULL)) { + return LPC_APIRESULT_INVALID_ARGUMENT; + } + + /* 係数計算 */ + if (LPC_CalculateCoef(lpcc, data, num_samples, coef_order, window_type, 0.0) != LPC_ERROR_OK) { + return LPC_APIRESULT_FAILED_TO_CALCULATION; + } + + /* log2(パワー平均)の計算 */ + log2_mean_res_power = lpcc->auto_corr[0]; /* 0次標本自己相関はパワー */ + /* 整数PCMの振幅に変換(doubleの密度保障) */ + log2_mean_res_power *= pow(2, (double)(2.0 * (bits_per_sample - 1))); + if (fabs(log2_mean_res_power) <= FLT_MIN) { + /* ほぼ無音だった場合は符号長を0とする */ + (*length_per_sample_bits) = 0.0; + return LPC_APIRESULT_OK; + } + log2_mean_res_power = LPC_Log2((double)log2_mean_res_power) - LPC_Log2((double)num_samples); + + /* sum(log2(1 - (parcor * parcor)))の計算 */ + log2_var_ratio = 0.0; + for (ord = 0; ord < coef_order; ord++) { + log2_var_ratio += LPC_Log2(1.0 - lpcc->parcor_coef[ord] * lpcc->parcor_coef[ord]); + } + + /* エントロピー計算 */ + /* →サンプルあたりの最小のビット数が得られる */ + (*length_per_sample_bits) = BETA_CONST_FOR_LAPLACE_DIST + 0.5f * (log2_mean_res_power + log2_var_ratio); + + /* 推定ビット数が負値の場合は、1サンプルあたり1ビットで符号化できることを期待する */ + /* 補足)このケースは入力音声パワーが非常に低い */ + if ((*length_per_sample_bits) <= 0) { + (*length_per_sample_bits) = 1.0; + return LPC_APIRESULT_OK; + } + +#undef BETA_CONST_FOR_LAPLACE_DIST +#undef BETA_CONST_FOR_GAUSS_DIST + + return LPC_APIRESULT_OK; +} + +/* MDL(最小記述長)を計算 */ +LPCApiResult LPCCalculator_CalculateMDL( + struct LPCCalculator *lpcc, + const double *data, uint32_t num_samples, uint32_t coef_order, double *mdl, + LPCWindowType window_type) +{ + uint32_t k; + double tmp; + + /* 引数チェック */ + if ((lpcc == NULL) || (data == NULL) || (mdl == NULL)) { + return LPC_APIRESULT_INVALID_ARGUMENT; + } + + /* 係数計算 */ + if (LPC_CalculateCoef(lpcc, data, num_samples, coef_order, window_type, 0.0) != LPC_ERROR_OK) { + return LPC_APIRESULT_FAILED_TO_CALCULATION; + } + + /* 第一項の計算 */ + /* 1次の係数は0で確定だから飛ばす */ + tmp = 0.0; + for (k = 1; k <= coef_order; k++) { + tmp += log(1.0 - lpcc->parcor_coef[k] * lpcc->parcor_coef[k]); + } + tmp *= num_samples; + + /* 第二項の計算 */ + tmp += coef_order * log(num_samples); + + (*mdl) = tmp; + + return LPC_APIRESULT_OK; +} + +/* LPC係数をPARCOR係数に変換 */ +static LPCError LPC_ConvertLPCtoPARCORDouble( + struct LPCCalculator *lpcc, const double *lpc_coef, uint32_t coef_order, double *parcor_coef) +{ + int32_t i, k; + double *tmplpc_coef, *a_vec; + + /* 引数チェック */ + if ((lpcc == NULL) || (lpc_coef == NULL) || (parcor_coef == NULL)) { + return LPC_ERROR_INVALID_ARGUMENT; + } + + /* 次数チェック */ + assert(coef_order <= lpcc->max_order); + + /* 作業領域を割り当て */ + tmplpc_coef = lpcc->lpc_coefs[0]; + a_vec = lpcc->a_vecs[0]; + + memcpy(tmplpc_coef, lpc_coef, sizeof(double) * coef_order); + + /* PARCOR係数に変換 */ + for (i = (int32_t)(coef_order - 1); i >= 0; i--) { + const double gamma = tmplpc_coef[i]; + assert(fabs(gamma) < 1.0); + parcor_coef[i] = -gamma; + for (k = 0; k < i; k++) { + a_vec[k] = tmplpc_coef[k]; + } + for (k = 0; k < i; k++) { + tmplpc_coef[k] = (a_vec[k] - gamma * a_vec[i - k - 1]) / (1.0 - gamma * gamma); + } + } + + return LPC_ERROR_OK; +} + +/* LPC係数をPARCOR係数に変換して量子化 */ +LPCApiResult LPC_QuantizeCoefficientsAsPARCOR( + struct LPCCalculator *lpcc, + const double *lpc_coef, uint32_t coef_order, uint32_t nbits_precision, int32_t *int_coef) +{ + uint32_t ord; + int32_t qtmp; + const int32_t qmax = (1 << (nbits_precision - 1)); + + /* 引数チェック */ + if ((lpcc == NULL) || (lpc_coef == NULL) + || (int_coef == NULL) || (nbits_precision == 0)) { + return LPC_APIRESULT_INVALID_ARGUMENT; + } + + /* 次数チェック */ + if (coef_order > lpcc->max_order) { + return LPC_APIRESULT_EXCEED_MAX_ORDER; + } + + /* PARCOR係数に変換 */ + if (LPC_ConvertLPCtoPARCORDouble(lpcc, lpc_coef, coef_order, lpcc->parcor_coef) != LPC_ERROR_OK) { + return LPC_APIRESULT_NG; + } + + /* PARCOR係数を量子化して出力 */ + for (ord = 0; ord < coef_order; ord++) { + assert(fabs(lpcc->parcor_coef[ord]) < 1.0); + qtmp = (int32_t)LPC_Round(lpcc->parcor_coef[ord] * pow(2.0, nbits_precision - 1)); + /* 正負境界の丸め込み */ + if (qtmp >= qmax) { + qtmp = qmax - 1; + } else if (qtmp < -qmax) { + qtmp = -qmax; + } + int_coef[ord] = qtmp; + } + + return LPC_APIRESULT_OK; +} + +/* LPC係数の整数量子化 */ +LPCApiResult LPC_QuantizeCoefficients( + const double *double_coef, uint32_t coef_order, uint32_t nbits_precision, uint32_t max_bits, + int32_t *int_coef, uint32_t *coef_rshift) +{ + uint32_t rshift; + int32_t ord, ndigit, qtmp; + double max, qerror; + const int32_t qmax = (1 << (nbits_precision - 1)); + + /* 引数チェック */ + if ((double_coef == NULL) || (int_coef == NULL) + || (coef_rshift == NULL) || (nbits_precision == 0)) { + return LPC_APIRESULT_INVALID_ARGUMENT; + } + + /* 係数絶対値の計算 */ + max = 0.0; + for (ord = 0; ord < (int32_t)coef_order; ord++) { + if (max < fabs(double_coef[ord])) { + max = fabs(double_coef[ord]); + } + } + + /* 与えられたビット数で表現できないほど小さいときは0とみなす */ + if (max <= pow(2.0, -(int32_t)(nbits_precision - 1))) { + (*coef_rshift) = nbits_precision; + memset(int_coef, 0, sizeof(int32_t) * coef_order); + return LPC_APIRESULT_OK; + } + + /* 最大値を[1/2, 1)に収めるための右シフト量の計算 */ + /* max = x * 2^ndigit, |x| in [1/2, 1)を計算 */ + (void)frexp(max, &ndigit); + /* 符号ビットを落とす */ + nbits_precision--; + /* nbits_precisionで表現可能にするためのシフト量計算 */ + assert((int32_t)nbits_precision >= ndigit); + rshift = (uint32_t)((int32_t)nbits_precision - ndigit); + + /* 右シフト量が最大を越えている場合は切り捨て(係数最大値が小さい場合) */ + if (rshift >= max_bits) { + rshift = max_bits - 1; + } + + /* 量子化 */ + qerror = 0.0; + for (ord = (int32_t)coef_order - 1; ord >= 0; ord--) { + /* 前の係数の誤差を取り込んで量子化 */ + /* インパルスの先頭部分には誤差を入れたくないため、末尾から処理 */ + qerror += double_coef[ord] * pow(2.0, rshift); + qtmp = (int32_t)LPC_Round(qerror); + /* 正負境界の丸め込み */ + if (qtmp >= qmax) { + qtmp = qmax - 1; + } else if (qtmp < -qmax) { + qtmp = -qmax; + } + /* 引いた分が量子化誤差として残る */ + qerror -= qtmp; + int_coef[ord] = qtmp; + } + (*coef_rshift) = rshift; + + return LPC_APIRESULT_OK; +} + +/* LPC係数により予測/誤差出力 */ +LPCApiResult LPC_Predict( + const int32_t *data, uint32_t num_samples, + const int32_t *coef, uint32_t coef_order, int32_t *residual, uint32_t coef_rshift) +{ + uint32_t smpl, ord; + + /* 引数チェック */ + if ((data == NULL) || (coef == NULL) + || (residual == NULL) || (coef_rshift == 0)) { + return LPC_APIRESULT_INVALID_ARGUMENT; + } + + memcpy(residual, data, sizeof(int32_t) * num_samples); + + /* LPC係数による予測 */ + for (smpl = 1; smpl < coef_order; smpl++) { + int32_t predict = (1 << (coef_rshift - 1)); + for (ord = 0; ord < smpl; ord++) { + predict += (coef[ord] * data[smpl - ord - 1]); + } + residual[smpl] += (predict >> coef_rshift); + } + for (smpl = coef_order; smpl < num_samples; smpl++) { + int32_t predict = (1 << (coef_rshift - 1)); + for (ord = 0; ord < coef_order; ord++) { + predict += (coef[ord] * data[smpl - ord - 1]); + } + residual[smpl] += (predict >> coef_rshift); + } + + return LPC_APIRESULT_OK; +} + +/* LPC係数により合成(in-place) */ +LPCApiResult LPC_Synthesize( + int32_t *data, uint32_t num_samples, + const int32_t *coef, uint32_t coef_order, uint32_t coef_rshift) +{ + uint32_t smpl, ord; + + /* 引数チェック */ + if ((data == NULL) || (coef == NULL) || (coef_rshift == 0)) { + return LPC_APIRESULT_INVALID_ARGUMENT; + } + + /* LPC係数による予測 */ + for (smpl = 1; smpl < coef_order; smpl++) { + int32_t predict = (1 << (coef_rshift - 1)); + for (ord = 0; ord < smpl; ord++) { + predict += (coef[ord] * data[smpl - ord - 1]); + } + data[smpl] -= (predict >> coef_rshift); + } + for (smpl = coef_order; smpl < num_samples; smpl++) { + int32_t predict = (1 << (coef_rshift - 1)); + for (ord = 0; ord < coef_order; ord++) { + predict += (coef[ord] * data[smpl - ord - 1]); + } + data[smpl] -= (predict >> coef_rshift); + } + + return LPC_APIRESULT_OK; +} diff --git a/libs/srla_coder/CMakeLists.txt b/libs/srla_coder/CMakeLists.txt new file mode 100644 index 0000000..d11c687 --- /dev/null +++ b/libs/srla_coder/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# プロジェクト名 +project(SRLACoder C) + +# ライブラリ名 +set(LIB_NAME srla_coder) + +# 静的ライブラリ指定 +add_library(${LIB_NAME} STATIC) + +# ソースディレクトリ +add_subdirectory(src) + +# インクルードパス +target_include_directories(${LIB_NAME} + PRIVATE + ${PROJECT_ROOT_PATH}/include + ${PROJECT_ROOT_PATH}/libs/bit_stream/include + ${PROJECT_ROOT_PATH}/libs/srla_internal/include + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + +# コンパイルオプション +if(MSVC) + target_compile_options(${LIB_NAME} PRIVATE /W4) +else() + target_compile_options(${LIB_NAME} PRIVATE -Wall -Wextra -Wpedantic -Wformat=2 -Wstrict-aliasing=2 -Wconversion -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition) + set(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -DDEBUG") + set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") +endif() +set_target_properties(${LIB_NAME} + PROPERTIES + C_STANDARD 90 C_EXTENSIONS OFF + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) diff --git a/libs/srla_coder/include/srla_coder.h b/libs/srla_coder/include/srla_coder.h new file mode 100644 index 0000000..dd69940 --- /dev/null +++ b/libs/srla_coder/include/srla_coder.h @@ -0,0 +1,33 @@ +#ifndef SRLACODER_H_INCLUDED +#define SRLACODER_H_INCLUDED + +#include +#include "bit_stream.h" + +/* 符号化ハンドル */ +struct SRLACoder; + +#ifdef __cplusplus +extern "C" { +#endif + +/* 符号化ハンドルの作成に必要なワークサイズの計算 */ +int32_t SRLACoder_CalculateWorkSize(void); + +/* 符号化ハンドルの作成 */ +struct SRLACoder* SRLACoder_Create(void *work, int32_t work_size); + +/* 符号化ハンドルの破棄 */ +void SRLACoder_Destroy(struct SRLACoder *coder); + +/* 符号付き整数配列の符号化 */ +void SRLACoder_Encode(struct SRLACoder *coder, struct BitStream *stream, const int32_t *data, uint32_t num_samples); + +/* 符号付き整数配列の復号 */ +void SRLACoder_Decode(struct BitStream *stream, int32_t *data, uint32_t num_samples); + +#ifdef __cplusplus +} +#endif + +#endif /* SRLACODER_H_INCLUDED */ diff --git a/libs/srla_coder/src/CMakeLists.txt b/libs/srla_coder/src/CMakeLists.txt new file mode 100644 index 0000000..368db87 --- /dev/null +++ b/libs/srla_coder/src/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/srla_coder.c + ) diff --git a/libs/srla_coder/src/srla_coder.c b/libs/srla_coder/src/srla_coder.c new file mode 100644 index 0000000..a00ba9c --- /dev/null +++ b/libs/srla_coder/src/srla_coder.c @@ -0,0 +1,586 @@ +#include "srla_coder.h" + +#include +#include +#include +#include + +#include "srla_internal.h" +#include "srla_utility.h" + +/* マクロ展開を使用する */ +#define SRLACODER_USE_MACROS 1 + +/* メモリアラインメント */ +#define SRLACODER_MEMORY_ALIGNMENT 16 +/* log2(最大分割数) */ +#define SRLACODER_LOG2_MAX_NUM_PARTITIONS 10 +/* 最大分割数 */ +#define SRLACODER_MAX_NUM_PARTITIONS (1 << SRLACODER_LOG2_MAX_NUM_PARTITIONS) +/* パラメータ記録領域ビット数 */ +#define SRLACODER_RICE_PARAMETER_BITS 5 +/* ガンマ符号長サイズ */ +#define SRLACODER_GAMMA_BITS(uint) (((uint) == 0) ? 1 : ((2 * SRLAUTILITY_LOG2CEIL(uint + 2)) - 1)) + +/* 符号の区別 */ +typedef enum SRLACoderCodeTypeTag { + SRLACODER_CODE_TYPE_RICE = 0, /* TODO: 将来的にGolombにするべきかも */ + SRLACODER_CODE_TYPE_RECURSIVE_RICE = 1, + SRLACODER_CODE_TYPE_INVALID +} SRLACoderCodeType; + + +/* 符号化ハンドル */ +struct SRLACoder { + uint8_t alloced_by_own; + double part_mean[SRLACODER_LOG2_MAX_NUM_PARTITIONS + 1][SRLACODER_MAX_NUM_PARTITIONS]; + void *work; +}; + +/* 符号化ハンドルの作成に必要なワークサイズの計算 */ +int32_t SRLACoder_CalculateWorkSize(void) +{ + int32_t work_size; + + /* ハンドル分のサイズ */ + work_size = sizeof(struct SRLACoder) + SRLACODER_MEMORY_ALIGNMENT; + + return work_size; +} + +/* 符号化ハンドルの作成 */ +struct SRLACoder* SRLACoder_Create(void *work, int32_t work_size) +{ + struct SRLACoder *coder; + uint8_t tmp_alloc_by_own = 0; + uint8_t *work_ptr; + + /* ワーク領域時前確保の場合 */ + if ((work == NULL) && (work_size == 0)) { + /* 引数を自前の計算値に差し替える */ + if ((work_size = SRLACoder_CalculateWorkSize()) < 0) { + return NULL; + } + work = malloc((uint32_t)work_size); + tmp_alloc_by_own = 1; + } + + /* 引数チェック */ + if ((work == NULL) || (work_size < SRLACoder_CalculateWorkSize())) { + return NULL; + } + + /* ワーク領域先頭取得 */ + work_ptr = (uint8_t *)work; + + /* ハンドル領域確保 */ + work_ptr = (uint8_t *)SRLAUTILITY_ROUNDUP((uintptr_t)work_ptr, SRLACODER_MEMORY_ALIGNMENT); + coder = (struct SRLACoder *)work_ptr; + work_ptr += sizeof(struct SRLACoder); + + /* ハンドルメンバ設定 */ + coder->alloced_by_own = tmp_alloc_by_own; + coder->work = work; + + return coder; +} + +/* 符号化ハンドルの破棄 */ +void SRLACoder_Destroy(struct SRLACoder *coder) +{ + if (coder != NULL) { + /* 自前確保していたら領域開放 */ + if (coder->alloced_by_own == 1) { + free(coder->work); + } + } +} + +/* ガンマ符号の出力 */ +static void Gamma_PutCode(struct BitStream *stream, uint32_t val) +{ + uint32_t ndigit; + + SRLA_ASSERT(stream != NULL); + + if (val == 0) { + /* 符号化対象が0ならば1を出力して終了 */ + BitWriter_PutBits(stream, 1, 1); + return; + } + + /* 桁数を取得 */ + ndigit = SRLAUTILITY_LOG2CEIL(val + 2); + /* 桁数-1だけ0を続ける */ + BitWriter_PutBits(stream, 0, ndigit - 1); + /* 桁数を使用して符号語を2進数で出力 */ + BitWriter_PutBits(stream, val + 1, ndigit); +} + +/* ガンマ符号の取得 */ +static uint32_t Gamma_GetCode(struct BitStream *stream) +{ + uint32_t ndigit; + uint32_t bitsbuf; + + SRLA_ASSERT(stream != NULL); + + /* 桁数を取得 */ + /* 1が出現するまで桁数を増加 */ + BitReader_GetZeroRunLength(stream, &ndigit); + /* 最低でも1のため下駄を履かせる */ + ndigit++; + + /* 桁数が1のときは0 */ + if (ndigit == 1) { + return 0; + } + + /* 桁数から符号語を出力 */ + BitReader_GetBits(stream, &bitsbuf, ndigit - 1); + return (uint32_t)((1UL << (ndigit - 1)) + bitsbuf - 1); +} + +/* Rice符号の出力 */ +static void Rice_PutCode(struct BitStream *stream, uint32_t k, uint32_t uval) +{ + const uint32_t mask = (1U << k) - 1; + + SRLA_ASSERT(stream != NULL); + + BitWriter_PutZeroRun(stream, uval >> k); + BitWriter_PutBits(stream, uval & mask, k); +} + +/* 再帰的Rice符号の出力 */ +static void RecursiveRice_PutCode(struct BitStream *stream, uint32_t k1, uint32_t k2, uint32_t uval) +{ + const uint32_t k1pow = 1U << k1; + const uint32_t k2mask = (1U << k2) - 1; + + SRLA_ASSERT(stream != NULL); + + if (uval < k1pow) { + /* 1段目で符号化 */ + BitWriter_PutBits(stream, 1, 1); + BitWriter_PutBits(stream, uval, k1); + } else { + /* 1段目のパラメータで引き、2段目のパラメータでRice符号化 */ + uval -= k1pow; + BitWriter_PutZeroRun(stream, 1 + (uval >> k2)); + BitWriter_PutBits(stream, uval & k2mask, k2); + } +} + +/* Rice符号の取得 */ +static uint32_t Rice_GetCode(struct BitStream *stream, uint32_t k) +{ + uint32_t quot, uval; + + SRLA_ASSERT(stream != NULL); + + /* 商(alpha符号)の取得 */ + BitReader_GetZeroRunLength(stream, "); + + /* 剰余の取得 */ + BitReader_GetBits(stream, &uval, k); + + return (quot << k) + uval; +} + +/* 再帰的Rice符号の取得 */ +#if defined(SRLACODER_USE_MACROS) +#define RecursiveRice_GetCode(stream, k1, k2, uval)\ + do {\ + uint32_t __quot;\ + \ + SRLA_ASSERT(stream != NULL);\ + SRLA_ASSERT(uval != NULL);\ + \ + /* 商(alpha符号)の取得 */\ + BitReader_GetZeroRunLength(stream, &__quot);\ + \ + /* 商で場合分け */\ + if (__quot == 0) {\ + BitReader_GetBits(stream, uval, k1);\ + } else {\ + BitReader_GetBits(stream, uval, k2);\ + (*(uval)) += (1U << (k1)) + ((__quot - 1) << (k2));\ + }\ + } while (0); +#else +static void RecursiveRice_GetCode(struct BitStream *stream, uint32_t k1, uint32_t k2, uint32_t *uval) +{ + uint32_t quot; + + SRLA_ASSERT(stream != NULL); + SRLA_ASSERT(uval != NULL); + + /* 商(alpha符号)の取得 */ + BitReader_GetZeroRunLength(stream, "); + + /* 商で場合分け */ + if (quot == 0) { + BitReader_GetBits(stream, uval, k1); + } else { + BitReader_GetBits(stream, uval, k2); + (*uval) += (1U << k1) + ((quot - 1) << k2); + } +} +#endif + +/* 最適な符号化パラメータの計算 */ +static void SRLACoder_CalculateOptimalRiceParameter( + const double mean, uint32_t *optk, double *bits_per_sample) +{ + uint32_t k; + double rho, fk, bps; +#define OPTX 0.5127629514437670454896078808815218508243560791015625 /* (x - 1)^2 + ln(2) x ln(x) = 0 の解 */ + + /* 幾何分布のパラメータを最尤推定 */ + rho = 1.0 / (1.0 + mean); + + /* 最適なパラメータの計算 */ + k = (uint32_t)SRLAUTILITY_MAX(0, SRLAUtility_Round(SRLAUtility_Log2(log(OPTX) / log(1.0 - rho)))); + + /* 平均符号長の計算 */ + fk = pow(1.0 - rho, (double)(1 << k)); + bps = k + (1.0 / (1.0 - fk)); + + /* 結果出力 */ + (*optk) = k; + + if (bits_per_sample != NULL) { + (*bits_per_sample) = bps; + } + +#undef OPTX +} + +/* k1に関する偏微分係数の計算 */ +static double SRLACoder_CalculateMeanCodelength(double rho, uint32_t k1, uint32_t k2) +{ + const double fk1 = pow(1.0 - rho, (double)(1 << k1)); + const double fk2 = pow(1.0 - rho, (double)(1 << k2)); + return (1.0 + k1) * (1.0 - fk1) + (1.0 + k2 + (1.0 / (1.0 - fk2))) * fk1; +} + +/* k1に関する偏微分係数の計算 */ +static double SRLACoder_CalculateDiffk1(double rho, double k1, double k2) +{ + const double k1pow = pow(2.0, k1); + const double fk1 = pow(1.0 - rho, k1pow); + const double fk2 = pow(1.0 - rho, pow(2.0, k2)); + const double fk1d = k1pow * fk1 * log(1.0 - rho) * log(2.0); + return 1.0 - fk1 + (k2 - k1 + 1.0 / (1.0 - fk2)) * fk1d; +} + +/* 最適な符号化パラメータの計算 */ +static void SRLACoder_CalculateOptimalRecursiveRiceParameter( + const double mean, uint32_t *optk1, uint32_t *optk2, double *bits_per_sample) +{ + uint32_t k1, k2; + double rho, fk1, fk2, bps; +#define OPTX 0.5127629514437670454896078808815218508243560791015625 /* (x - 1)^2 + ln(2) x ln(x) = 0 の解 */ + + /* 幾何分布のパラメータを最尤推定 */ + rho = 1.0 / (1.0 + mean); + + /* 最適なパラメータの計算 */ +#if 1 + /* 簡易版 */ + k2 = (uint32_t)SRLAUTILITY_MAX(0, floor(SRLAUtility_Log2(log(OPTX) / log(1.0 - rho)))); + k1 = k2 + 1; +#else + /* k1を2分法で求める */ + /* note: 一般にk1 = k2 + 1が成り立たなくなり符号化で不利! */ + { + uint32_t i; + double k1tmp, d1, d2; + const double k2tmp = SRLAUtility_Log2(log(OPTX) / log(1.0 - rho)); + double k1min = k2tmp - 1.5; + double k1max = k2tmp + 1.5; + for (i = 0; i < 5; i++) { + k1tmp = (k1max + k1min) / 2.0; + d1 = SRLACoder_CalculateDiffk1(rho, k1tmp, k2tmp); + d2 = SRLACoder_CalculateDiffk1(rho, k1min, k2tmp); + if (SRLAUTILITY_SIGN(d1) == SRLAUTILITY_SIGN(d2)) { + k1min = k1tmp; + } else { + k1max = k1tmp; + } + } + k1 = (uint32_t)SRLAUTILITY_MAX(0, ceil(k1tmp)); + k2 = (uint32_t)SRLAUTILITY_MAX(0, floor(k2tmp)); + } +#endif + + /* 平均符号長の計算 */ + bps = SRLACoder_CalculateMeanCodelength(rho, k1, k2); + + /* 結果出力 */ + (*optk1) = k1; + (*optk2) = k2; + + if (bits_per_sample != NULL) { + (*bits_per_sample) = bps; + } + +#undef OPTX +} + +/* Rice符号長の出力 */ +static uint32_t Rice_GetCodeLength(uint32_t k, uint32_t uval) +{ + return 1 + k + (uval >> k); +} + +/* 再帰的Rice符号長の出力 */ +static uint32_t RecursiveRice_GetCodeLength(uint32_t k1, uint32_t k2, uint32_t uval) +{ + const uint32_t k1pow = 1U << k1; + + if (uval < k1pow) { + /* 1段目で符号化 */ + return k1 + 1; + } else { + /* 1段目のパラメータで引き、2段目のパラメータでRice符号化 */ + return k2 + 2 + ((uval - k1pow) >> k2); + } +} + +/* 符号付き整数配列の符号化 */ +static void SRLACoder_EncodePartitionedRecursiveRice(struct SRLACoder *coder, struct BitStream *stream, const int32_t *data, uint32_t num_samples) +{ + uint32_t max_porder, max_num_partitions; + uint32_t porder, part, best_porder, smpl; + SRLACoderCodeType code_type = SRLACODER_CODE_TYPE_INVALID; + + /* 最大分割数の決定 */ + max_porder = 1; + while ((num_samples % (1 << max_porder)) == 0) { + max_porder++; + } + max_porder = SRLAUTILITY_MIN(max_porder - 1, SRLACODER_LOG2_MAX_NUM_PARTITIONS); + max_num_partitions = (1 << max_porder); + + /* 各分割での平均を計算 */ + { + int32_t i; + + /* 最も細かい分割時の平均値 */ + for (part = 0; part < max_num_partitions; part++) { + const uint32_t nsmpl = num_samples / max_num_partitions; + double part_sum = 0.0; + for (smpl = 0; smpl < nsmpl; smpl++) { + part_sum += SRLAUTILITY_SINT32_TO_UINT32(data[part * nsmpl + smpl]); + } + coder->part_mean[max_porder][part] = part_sum / nsmpl; + } + + /* より大きい分割の平均は、小さい分割の平均をマージして計算 */ + for (i = (int32_t)(max_porder - 1); i >= 0; i--) { + for (part = 0; part < (1 << i); part++) { + coder->part_mean[i][part] = (coder->part_mean[i + 1][2 * part] + coder->part_mean[i + 1][2 * part + 1]) / 2.0; + } + } + } + + /* 全体平均を元に符号を切り替え */ + if (coder->part_mean[0][0] < 2) { + code_type = SRLACODER_CODE_TYPE_RICE; + } else { + code_type = SRLACODER_CODE_TYPE_RECURSIVE_RICE; + } + + /* 各分割での符号長を計算し、最適な分割を探索 */ + { + uint32_t min_bits = UINT32_MAX; + best_porder = max_porder + 1; + + switch (code_type) { + case SRLACODER_CODE_TYPE_RICE: + { + for (porder = 0; porder <= max_porder; porder++) { + const uint32_t nsmpl = (num_samples >> porder); + uint32_t k, prevk; + uint32_t bits = 0; + for (part = 0; part < (1 << porder); part++) { + SRLACoder_CalculateOptimalRiceParameter(coder->part_mean[porder][part], &k, NULL); + for (smpl = 0; smpl < nsmpl; smpl++) { + bits += Rice_GetCodeLength(k, SRLAUTILITY_SINT32_TO_UINT32(data[part * nsmpl + smpl])); + } + if (part == 0) { + bits += SRLACODER_RICE_PARAMETER_BITS; + } else { + const int32_t diff = (int32_t)k - (int32_t)prevk; + const uint32_t udiff = SRLAUTILITY_SINT32_TO_UINT32(diff); + bits += SRLACODER_GAMMA_BITS(udiff); + } + prevk = k; + } + if (min_bits > bits) { + min_bits = bits; + best_porder = porder; + } + } + } + break; + case SRLACODER_CODE_TYPE_RECURSIVE_RICE: + { + for (porder = 0; porder <= max_porder; porder++) { + const uint32_t nsmpl = (num_samples >> porder); + uint32_t k1, k2, prevk2; + uint32_t bits = 0; + for (part = 0; part < (1 << porder); part++) { + SRLACoder_CalculateOptimalRecursiveRiceParameter(coder->part_mean[porder][part], &k1, &k2, NULL); + for (smpl = 0; smpl < nsmpl; smpl++) { + bits += RecursiveRice_GetCodeLength(k1, k2, SRLAUTILITY_SINT32_TO_UINT32(data[part * nsmpl + smpl])); + } + if (part == 0) { + bits += SRLACODER_RICE_PARAMETER_BITS; + } else { + const int32_t diff = (int32_t)k2 - (int32_t)prevk2; + const uint32_t udiff = SRLAUTILITY_SINT32_TO_UINT32(diff); + bits += SRLACODER_GAMMA_BITS(udiff); + } + prevk2 = k2; + } + if (min_bits > bits) { + min_bits = bits; + best_porder = porder; + } + } + } + break; + default: + SRLA_ASSERT(0); + } + + SRLA_ASSERT(best_porder != (max_porder + 1)); + } + + /* 最適な分割を用いて符号化 */ + { + uint32_t smpl; + const uint32_t nsmpl = num_samples >> best_porder; + + SRLA_ASSERT(code_type != SRLACODER_CODE_TYPE_INVALID); + BitWriter_PutBits(stream, code_type, 1); + BitWriter_PutBits(stream, best_porder, SRLACODER_LOG2_MAX_NUM_PARTITIONS); + + switch (code_type) { + case SRLACODER_CODE_TYPE_RICE: + { + uint32_t k, prevk; + for (part = 0; part < (1 << best_porder); part++) { + SRLACoder_CalculateOptimalRiceParameter(coder->part_mean[best_porder][part], &k, NULL); + if (part == 0) { + BitWriter_PutBits(stream, k, SRLACODER_RICE_PARAMETER_BITS); + } else { + const int32_t diff = (int32_t)k - (int32_t)prevk; + Gamma_PutCode(stream, SRLAUTILITY_SINT32_TO_UINT32(diff)); + } + prevk = k; + for (smpl = 0; smpl < nsmpl; smpl++) { + const uint32_t uval = SRLAUTILITY_SINT32_TO_UINT32(data[part * nsmpl + smpl]); + Rice_PutCode(stream, k, uval); + } + } + } + break; + case SRLACODER_CODE_TYPE_RECURSIVE_RICE: + { + uint32_t k1, k2, prevk2; + for (part = 0; part < (1 << best_porder); part++) { + SRLACoder_CalculateOptimalRecursiveRiceParameter(coder->part_mean[best_porder][part], &k1, &k2, NULL); + if (part == 0) { + BitWriter_PutBits(stream, k2, SRLACODER_RICE_PARAMETER_BITS); + } else { + const int32_t diff = (int32_t)k2 - (int32_t)prevk2; + Gamma_PutCode(stream, SRLAUTILITY_SINT32_TO_UINT32(diff)); + } + prevk2 = k2; + for (smpl = 0; smpl < nsmpl; smpl++) { + const uint32_t uval = SRLAUTILITY_SINT32_TO_UINT32(data[part * nsmpl + smpl]); + RecursiveRice_PutCode(stream, k1, k2, uval); + } + } + } + break; + default: + SRLA_ASSERT(0); + } + } +} + +/* 符号付き整数配列の復号 */ +static void SRLACoder_DecodePartitionedRecursiveRice(struct BitStream *stream, int32_t *data, uint32_t num_samples) +{ + uint32_t smpl, part, nsmpl, best_porder; + + SRLACoderCodeType code_type = SRLACODER_CODE_TYPE_INVALID; + + BitReader_GetBits(stream, (uint32_t *)&code_type, 1); + BitReader_GetBits(stream, &best_porder, SRLACODER_LOG2_MAX_NUM_PARTITIONS); + nsmpl = num_samples >> best_porder; + + switch (code_type) { + case SRLACODER_CODE_TYPE_RICE: + { + uint32_t k; + for (part = 0; part < (1 << best_porder); part++) { + if (part == 0) { + BitReader_GetBits(stream, &k, SRLACODER_RICE_PARAMETER_BITS); + } else { + const uint32_t udiff = Gamma_GetCode(stream); + k = (uint32_t)((int32_t)k + SRLAUTILITY_UINT32_TO_SINT32(udiff)); + } + for (smpl = 0; smpl < nsmpl; smpl++) { + const uint32_t uval = Rice_GetCode(stream, k); + data[part * nsmpl + smpl] = SRLAUTILITY_UINT32_TO_SINT32(uval); + } + } + } + break; + case SRLACODER_CODE_TYPE_RECURSIVE_RICE: + { + uint32_t k1, k2; + for (part = 0; part < (1 << best_porder); part++) { + if (part == 0) { + BitReader_GetBits(stream, &k2, SRLACODER_RICE_PARAMETER_BITS); + } else { + const uint32_t udiff = Gamma_GetCode(stream); + k2 = (uint32_t)((int32_t)k2 + SRLAUTILITY_UINT32_TO_SINT32(udiff)); + } + k1 = k2 + 1; + for (smpl = 0; smpl < nsmpl; smpl++) { + uint32_t uval; + RecursiveRice_GetCode(stream, k1, k2, &uval); + data[part * nsmpl + smpl] = SRLAUTILITY_UINT32_TO_SINT32(uval); + } + } + } + break; + default: + SRLA_ASSERT(0); + } +} + +/* 符号付き整数配列の符号化 */ +void SRLACoder_Encode(struct SRLACoder *coder, struct BitStream *stream, const int32_t *data, uint32_t num_samples) +{ + SRLA_ASSERT((stream != NULL) && (data != NULL) && (coder != NULL)); + SRLA_ASSERT(num_samples != 0); + + SRLACoder_EncodePartitionedRecursiveRice(coder, stream, data, num_samples); +} + +/* 符号付き整数配列の復号 */ +void SRLACoder_Decode(struct BitStream *stream, int32_t *data, uint32_t num_samples) +{ + SRLA_ASSERT((stream != NULL) && (data != NULL)); + SRLA_ASSERT(num_samples != 0); + + SRLACoder_DecodePartitionedRecursiveRice(stream, data, num_samples); +} diff --git a/libs/srla_decoder/CMakeLists.txt b/libs/srla_decoder/CMakeLists.txt new file mode 100644 index 0000000..3ba92de --- /dev/null +++ b/libs/srla_decoder/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# プロジェクト名 +project(SRLADecoder C) + +# ライブラリ名 +set(LIB_NAME srla_decoder) + +# 静的ライブラリ指定 +add_library(${LIB_NAME} STATIC) + +# ソースディレクトリ +add_subdirectory(src) + +# インクルードパス +target_include_directories(${LIB_NAME} + PRIVATE + ${PROJECT_ROOT_PATH}/include + ${PROJECT_ROOT_PATH}/libs/byte_array/include + ${PROJECT_ROOT_PATH}/libs/bit_stream/include + ${PROJECT_ROOT_PATH}/libs/lpc/include + ${PROJECT_ROOT_PATH}/libs/srla_internal/include + ${PROJECT_ROOT_PATH}/libs/srla_coder/include + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + +# コンパイルオプション +if(MSVC) + target_compile_options(${LIB_NAME} PRIVATE /W4) +else() + target_compile_options(${LIB_NAME} PRIVATE -Wall -Wextra -Wpedantic -Wformat=2 -Wstrict-aliasing=2 -Wconversion -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition) + set(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -DDEBUG") + set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") +endif() +set_target_properties(${LIB_NAME} + PROPERTIES + C_STANDARD 90 C_EXTENSIONS OFF + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) diff --git a/libs/srla_decoder/src/CMakeLists.txt b/libs/srla_decoder/src/CMakeLists.txt new file mode 100644 index 0000000..071cdc1 --- /dev/null +++ b/libs/srla_decoder/src/CMakeLists.txt @@ -0,0 +1,6 @@ +target_sources(${LIB_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/srla_decoder.c + ${CMAKE_CURRENT_SOURCE_DIR}/srla_lpc_synthesize.c + ${CMAKE_CURRENT_SOURCE_DIR}/srla_lpc_synthesize.h + ) diff --git a/libs/srla_decoder/src/srla_decoder.c b/libs/srla_decoder/src/srla_decoder.c new file mode 100644 index 0000000..e634027 --- /dev/null +++ b/libs/srla_decoder/src/srla_decoder.c @@ -0,0 +1,714 @@ +#include "srla_decoder.h" + +#include +#include +#include "srla_lpc_synthesize.h" +#include "srla_internal.h" +#include "srla_utility.h" +#include "srla_coder.h" +#include "byte_array.h" +#include "bit_stream.h" +#include "lpc.h" + +/* 内部状態フラグ */ +#define SRLADECODER_STATUS_FLAG_ALLOCED_BY_OWN (1 << 0) /* 領域を自己割当した */ +#define SRLADECODER_STATUS_FLAG_SET_HEADER (1 << 1) /* ヘッダセット済み */ +#define SRLADECODER_STATUS_FLAG_CHECKSUM_CHECK (1 << 2) /* チェックサムの検査を行う */ + +/* 内部状態フラグ操作マクロ */ +#define SRLADECODER_SET_STATUS_FLAG(decoder, flag) ((decoder->status_flags) |= (flag)) +#define SRLADECODER_CLEAR_STATUS_FLAG(decoder, flag) ((decoder->status_flags) &= ~(flag)) +#define SRLADECODER_GET_STATUS_FLAG(decoder, flag) ((decoder->status_flags) & (flag)) + +/* デコーダハンドル */ +struct SRLADecoder { + struct SRLAHeader header; /* ヘッダ */ + uint32_t max_num_channels; /* デコード可能な最大チャンネル数 */ + uint32_t max_num_parameters; /* 最大パラメータ数 */ + struct SRLAPreemphasisFilter **de_emphasis; /* デエンファシスフィルタ */ + int32_t **params_int; /* 各チャンネルのLPC係数(int) */ + uint32_t *rshifts; /* 各チャンネルのLPC係数右シフト量 */ + uint32_t *coef_order; /* 各チャンネルのLPC係数次数 */ + const struct SRLAParameterPreset *parameter_preset; /* パラメータプリセット */ + uint8_t status_flags; /* 内部状態フラグ */ + void *work; /* ワーク領域先頭ポインタ */ +}; + +/* 生データブロックデコード */ +static SRLAApiResult SRLADecoder_DecodeRawData( + struct SRLADecoder *decoder, + const uint8_t *data, uint32_t data_size, + int32_t **buffer, uint32_t num_channels, uint32_t num_decode_samples, + uint32_t *decode_size); +/* 圧縮データブロックデコード */ +static SRLAApiResult SRLADecoder_DecodeCompressData( + struct SRLADecoder *decoder, + const uint8_t *data, uint32_t data_size, + int32_t **buffer, uint32_t num_channels, uint32_t num_decode_samples, + uint32_t *decode_size); +/* 無音データブロックデコード */ +static SRLAApiResult SRLADecoder_DecodeSilentData( + struct SRLADecoder *decoder, + const uint8_t *data, uint32_t data_size, + int32_t **buffer, uint32_t num_channels, uint32_t num_decode_samples, + uint32_t *decode_size); + +/* ヘッダデコード */ +SRLAApiResult SRLADecoder_DecodeHeader( + const uint8_t *data, uint32_t data_size, struct SRLAHeader *header) +{ + const uint8_t *data_pos; + uint32_t u32buf; + uint16_t u16buf; + uint8_t u8buf; + struct SRLAHeader tmp_header; + + /* 引数チェック */ + if ((data == NULL) || (header == NULL)) { + return SRLA_APIRESULT_INVALID_ARGUMENT; + } + + /* データサイズが足りない */ + if (data_size < SRLA_HEADER_SIZE) { + return SRLA_APIRESULT_INSUFFICIENT_DATA; + } + + /* 読み出し用ポインタ設定 */ + data_pos = data; + + /* シグネチャ */ + { + uint8_t buf[4]; + ByteArray_GetUint8(data_pos, &buf[0]); + ByteArray_GetUint8(data_pos, &buf[1]); + ByteArray_GetUint8(data_pos, &buf[2]); + ByteArray_GetUint8(data_pos, &buf[3]); + if ((buf[0] != '1') || (buf[1] != '2') + || (buf[2] != '4') || (buf[3] != '9')) { + return SRLA_APIRESULT_INVALID_FORMAT; + } + } + + /* シグネチャ検査に通ったら、エラーを起こさずに読み切る */ + + /* フォーマットバージョン */ + ByteArray_GetUint32BE(data_pos, &u32buf); + tmp_header.format_version = u32buf; + /* エンコーダバージョン */ + ByteArray_GetUint32BE(data_pos, &u32buf); + tmp_header.codec_version = u32buf; + /* チャンネル数 */ + ByteArray_GetUint16BE(data_pos, &u16buf); + tmp_header.num_channels = u16buf; + /* サンプル数 */ + ByteArray_GetUint32BE(data_pos, &u32buf); + tmp_header.num_samples = u32buf; + /* サンプリングレート */ + ByteArray_GetUint32BE(data_pos, &u32buf); + tmp_header.sampling_rate = u32buf; + /* サンプルあたりビット数 */ + ByteArray_GetUint16BE(data_pos, &u16buf); + tmp_header.bits_per_sample = u16buf; + /* ブロックあたりサンプル数 */ + ByteArray_GetUint32BE(data_pos, &u32buf); + tmp_header.num_samples_per_block = u32buf; + /* パラメータプリセット */ + ByteArray_GetUint8(data_pos, &u8buf); + tmp_header.preset = u8buf; + + /* ヘッダサイズチェック */ + SRLA_ASSERT((data_pos - data) == SRLA_HEADER_SIZE); + + /* 成功終了 */ + (*header) = tmp_header; + return SRLA_APIRESULT_OK; +} + +/* ヘッダのフォーマットチェック */ +static SRLAError SRLADecoder_CheckHeaderFormat(const struct SRLAHeader *header) +{ + /* 内部モジュールなのでNULLが渡されたら落とす */ + SRLA_ASSERT(header != NULL); + + /* フォーマットバージョン */ + /* 補足)今のところは不一致なら無条件でエラー */ + if (header->format_version != SRLA_FORMAT_VERSION) { + return SRLA_ERROR_INVALID_FORMAT; + } + /* コーデックバージョン */ + /* 補足)今のところは不一致なら無条件でエラー */ + if (header->codec_version != SRLA_CODEC_VERSION) { + return SRLA_ERROR_INVALID_FORMAT; + } + /* チャンネル数 */ + if (header->num_channels == 0) { + return SRLA_ERROR_INVALID_FORMAT; + } + /* サンプル数 */ + if (header->num_samples == 0) { + return SRLA_ERROR_INVALID_FORMAT; + } + /* サンプリングレート */ + if (header->sampling_rate == 0) { + return SRLA_ERROR_INVALID_FORMAT; + } + /* ビット深度 */ + if (header->bits_per_sample == 0) { + return SRLA_ERROR_INVALID_FORMAT; + } + /* ブロックあたりサンプル数 */ + if (header->num_samples_per_block == 0) { + return SRLA_ERROR_INVALID_FORMAT; + } + /* パラメータプリセット */ + if (header->preset >= SRLA_NUM_PARAMETER_PRESETS) { + return SRLA_ERROR_INVALID_FORMAT; + } + + return SRLA_ERROR_OK; +} + +/* デコーダハンドルの作成に必要なワークサイズの計算 */ +int32_t SRLADecoder_CalculateWorkSize(const struct SRLADecoderConfig *config) +{ + int32_t work_size; + + /* 引数チェック */ + if (config == NULL) { + return -1; + } + + /* コンフィグチェック */ + if ((config->max_num_channels == 0) + || (config->max_num_parameters == 0)) { + return -1; + } + + /* 構造体サイズ(+メモリアラインメント) */ + work_size = sizeof(struct SRLADecoder) + SRLA_MEMORY_ALIGNMENT; + /* デエンファシスフィルタのサイズ */ + work_size += SRLA_CALCULATE_2DIMARRAY_WORKSIZE(struct SRLAPreemphasisFilter, config->max_num_channels, SRLA_NUM_PREEMPHASIS_FILTERS); + /* パラメータ領域 */ + /* LPC係数(int) */ + work_size += SRLA_CALCULATE_2DIMARRAY_WORKSIZE(int32_t, config->max_num_channels, config->max_num_parameters); + /* 各チャンネルのLPC係数右シフト量 */ + work_size += SRLA_MEMORY_ALIGNMENT + sizeof(uint32_t) * config->max_num_channels; + /* 各チャンネルのLPC係数次数 */ + work_size += SRLA_MEMORY_ALIGNMENT + sizeof(uint32_t) * config->max_num_channels; + + return work_size; +} + +/* デコーダハンドル作成 */ +struct SRLADecoder *SRLADecoder_Create(const struct SRLADecoderConfig *config, void *work, int32_t work_size) +{ + uint32_t ch, l; + struct SRLADecoder *decoder; + uint8_t *work_ptr; + uint8_t tmp_alloc_by_own = 0; + + /* 領域自前確保の場合 */ + if ((work == NULL) && (work_size == 0)) { + if ((work_size = SRLADecoder_CalculateWorkSize(config)) < 0) { + return NULL; + } + work = malloc((uint32_t)work_size); + tmp_alloc_by_own = 1; + } + + /* 引数チェック */ + if ((config == NULL) || (work == NULL) + || (work_size < SRLADecoder_CalculateWorkSize(config))) { + return NULL; + } + + /* コンフィグチェック */ + if ((config->max_num_channels == 0) + || (config->max_num_parameters == 0)) { + return NULL; + } + + /* ワーク領域先頭ポインタ取得 */ + work_ptr = (uint8_t *)work; + + /* 構造体領域確保 */ + work_ptr = (uint8_t *)SRLAUTILITY_ROUNDUP((uintptr_t)work_ptr, SRLA_MEMORY_ALIGNMENT); + decoder = (struct SRLADecoder *)work_ptr; + work_ptr += sizeof(struct SRLADecoder); + + /* 構造体メンバセット */ + decoder->work = work; + decoder->max_num_channels = config->max_num_channels; + decoder->max_num_parameters = config->max_num_parameters; + decoder->status_flags = 0; /* 状態クリア */ + if (tmp_alloc_by_own == 1) { + SRLADECODER_SET_STATUS_FLAG(decoder, SRLADECODER_STATUS_FLAG_ALLOCED_BY_OWN); + } + if (config->check_checksum == 1) { + SRLADECODER_SET_STATUS_FLAG(decoder, SRLADECODER_STATUS_FLAG_CHECKSUM_CHECK); + } + + /* デエンファシスフィルタの作成 */ + SRLA_ALLOCATE_2DIMARRAY(decoder->de_emphasis, + work_ptr, struct SRLAPreemphasisFilter, config->max_num_channels, SRLA_NUM_PREEMPHASIS_FILTERS); + + /* バッファ領域の確保 全てのポインタをアラインメント */ + /* LPC係数(int) */ + SRLA_ALLOCATE_2DIMARRAY(decoder->params_int, + work_ptr, int32_t, config->max_num_channels, config->max_num_parameters); + /* 各層のLPC係数右シフト量 */ + work_ptr = (uint8_t*)SRLAUTILITY_ROUNDUP((uintptr_t)work_ptr, SRLA_MEMORY_ALIGNMENT); + decoder->rshifts = (uint32_t*)work_ptr; + work_ptr += config->max_num_channels * sizeof(uint32_t); + /* 各層のLPC係数次数 */ + work_ptr = (uint8_t *)SRLAUTILITY_ROUNDUP((uintptr_t)work_ptr, SRLA_MEMORY_ALIGNMENT); + decoder->coef_order = (uint32_t *)work_ptr; + work_ptr += config->max_num_channels * sizeof(uint32_t); + + /* バッファオーバーランチェック */ + /* 補足)既にメモリを破壊している可能性があるので、チェックに失敗したら落とす */ + SRLA_ASSERT((work_ptr - (uint8_t *)work) <= work_size); + + /* プリエンファシスフィルタ初期化 */ + for (ch = 0; ch < config->max_num_channels; ch++) { + for (l = 0; l < SRLA_NUM_PREEMPHASIS_FILTERS; l++) { + SRLAPreemphasisFilter_Initialize(&decoder->de_emphasis[ch][l]); + } + } + + return decoder; +} + +/* デコーダハンドルの破棄 */ +void SRLADecoder_Destroy(struct SRLADecoder *decoder) +{ + if (decoder != NULL) { + if (SRLADECODER_GET_STATUS_FLAG(decoder, SRLADECODER_STATUS_FLAG_ALLOCED_BY_OWN)) { + free(decoder->work); + } + } +} + +/* デコーダにヘッダをセット */ +SRLAApiResult SRLADecoder_SetHeader( + struct SRLADecoder *decoder, const struct SRLAHeader *header) +{ + /* 引数チェック */ + if ((decoder == NULL) || (header == NULL)) { + return SRLA_APIRESULT_INVALID_ARGUMENT; + } + + /* ヘッダの有効性チェック */ + if (SRLADecoder_CheckHeaderFormat(header) != SRLA_ERROR_OK) { + return SRLA_APIRESULT_INVALID_FORMAT; + } + + /* デコーダの容量を越えてないかチェック */ + if (decoder->max_num_channels < header->num_channels) { + return SRLA_APIRESULT_INSUFFICIENT_BUFFER; + } + + /* 最大レイヤー数/パラメータ数のチェック */ + { + const struct SRLAParameterPreset* preset = &g_srla_parameter_preset[header->preset]; + if (decoder->max_num_parameters < preset->max_num_parameters) { + return SRLA_APIRESULT_INSUFFICIENT_BUFFER; + } + } + + /* エンコードプリセットを取得 */ + SRLA_ASSERT(header->preset < SRLA_NUM_PARAMETER_PRESETS); + decoder->parameter_preset = &g_srla_parameter_preset[header->preset]; + + /* ヘッダセット */ + decoder->header = (*header); + SRLADECODER_SET_STATUS_FLAG(decoder, SRLADECODER_STATUS_FLAG_SET_HEADER); + + return SRLA_APIRESULT_OK; +} + +/* 生データブロックデコード */ +static SRLAApiResult SRLADecoder_DecodeRawData( + struct SRLADecoder *decoder, + const uint8_t *data, uint32_t data_size, + int32_t **buffer, uint32_t num_channels, uint32_t num_decode_samples, + uint32_t *decode_size) +{ + uint32_t ch, smpl; + const struct SRLAHeader *header; + const uint8_t *read_ptr; + + /* 内部関数なので不正な引数はアサートで落とす */ + SRLA_ASSERT(decoder != NULL); + SRLA_ASSERT(data != NULL); + SRLA_ASSERT(data_size > 0); + SRLA_ASSERT(buffer != NULL); + SRLA_ASSERT(buffer[0] != NULL); + SRLA_ASSERT(num_decode_samples > 0); + SRLA_ASSERT(decode_size != NULL); + + /* ヘッダ取得 */ + header = &(decoder->header); + + /* チャンネル数不足もアサートで落とす */ + SRLA_ASSERT(num_channels >= header->num_channels); + + /* データサイズチェック */ + if (data_size < (header->bits_per_sample * num_decode_samples * header->num_channels) / 8) { + return SRLA_APIRESULT_INSUFFICIENT_DATA; + } + + /* 生データをチャンネルインターリーブで取得 */ + read_ptr = data; + switch (header->bits_per_sample) { + case 8: + for (smpl = 0; smpl < num_decode_samples; smpl++) { + for (ch = 0; ch < header->num_channels; ch++) { + uint8_t buf; + ByteArray_GetUint8(read_ptr, &buf); + buffer[ch][smpl] = SRLAUTILITY_UINT32_TO_SINT32(buf); + SRLA_ASSERT((uint32_t)(read_ptr - data) <= data_size); + } + } + break; + case 16: + for (smpl = 0; smpl < num_decode_samples; smpl++) { + for (ch = 0; ch < header->num_channels; ch++) { + uint16_t buf; + ByteArray_GetUint16BE(read_ptr, &buf); + buffer[ch][smpl] = SRLAUTILITY_UINT32_TO_SINT32(buf); + SRLA_ASSERT((uint32_t)(read_ptr - data) <= data_size); + } + } + break; + case 24: + for (smpl = 0; smpl < num_decode_samples; smpl++) { + for (ch = 0; ch < header->num_channels; ch++) { + uint32_t buf; + ByteArray_GetUint24BE(read_ptr, &buf); + buffer[ch][smpl] = SRLAUTILITY_UINT32_TO_SINT32(buf); + SRLA_ASSERT((uint32_t)(read_ptr - data) <= data_size); + } + } + break; + default: SRLA_ASSERT(0); + } + + /* 読み取りサイズ取得 */ + (*decode_size) = (uint32_t)(read_ptr - data); + + return SRLA_APIRESULT_OK; +} + +/* 圧縮データブロックデコード */ +static SRLAApiResult SRLADecoder_DecodeCompressData( + struct SRLADecoder *decoder, + const uint8_t *data, uint32_t data_size, + int32_t **buffer, uint32_t num_channels, uint32_t num_decode_samples, + uint32_t *decode_size) +{ + uint32_t ch; + int32_t l; + struct BitStream reader; + const struct SRLAHeader *header; + SRLAChannelProcessMethod ch_process_method; + + /* 内部関数なので不正な引数はアサートで落とす */ + SRLA_ASSERT(decoder != NULL); + SRLA_ASSERT(data != NULL); + SRLA_ASSERT(data_size > 0); + SRLA_ASSERT(buffer != NULL); + SRLA_ASSERT(buffer[0] != NULL); + SRLA_ASSERT(num_decode_samples > 0); + SRLA_ASSERT(decode_size != NULL); + + /* ヘッダ取得 */ + header = &(decoder->header); + + /* チャンネル数不足もアサートで落とす */ + SRLA_ASSERT(num_channels >= header->num_channels); + + /* ビットリーダ作成 */ + BitReader_Open(&reader, (uint8_t *)data, data_size); + + /* マルチチャンネル処理法の取得 */ + BitReader_GetBits(&reader, (uint32_t *)&ch_process_method, 2); + + /* パラメータ復号 */ + /* プリエンファシス */ + for (ch = 0; ch < num_channels; ch++) { + uint32_t uval; + for (l = 0; l < SRLA_NUM_PREEMPHASIS_FILTERS; l++) { + BitReader_GetBits(&reader, &uval, header->bits_per_sample + 1); + decoder->de_emphasis[ch][l].prev = SRLAUTILITY_UINT32_TO_SINT32(uval); + /* プリエンファシス係数は正値に制限しているため1bitケチれる */ + BitReader_GetBits(&reader, &uval, SRLA_PREEMPHASIS_COEF_SHIFT - 1); + decoder->de_emphasis[ch][l].coef = (int32_t)uval; + } + } + /* LPC係数次数/LPC係数右シフト量/LPC係数 */ + for (ch = 0; ch < num_channels; ch++) { + uint32_t i, uval; + /* LPC係数次数 */ + BitReader_GetBits(&reader, &decoder->coef_order[ch], SRLA_LPC_COEFFICIENT_ORDER_BITWIDTH); + decoder->coef_order[ch] += 1; /* -1してエンコードしてあるので戻す */ + /* 各レイヤーでのLPC係数右シフト量 */ + BitReader_GetBits(&reader, &decoder->rshifts[ch], SRLA_RSHIFT_LPC_COEFFICIENT_BITWIDTH); + /* LPC係数 */ + for (i = 0; i < decoder->coef_order[ch]; i++) { + BitReader_GetBits(&reader, &uval, SRLA_LPC_COEFFICIENT_BITWIDTH); + decoder->params_int[ch][i] = SRLAUTILITY_UINT32_TO_SINT32(uval); + } + } + + /* 残差復号 */ + for (ch = 0; ch < header->num_channels; ch++) { + SRLACoder_Decode(&reader, buffer[ch], num_decode_samples); + } + + /* バイト境界に揃える */ + BitStream_Flush(&reader); + + /* 読み出しサイズの取得 */ + BitStream_Tell(&reader, (int32_t *)decode_size); + + /* ビットライタ破棄 */ + BitStream_Close(&reader); + + /* チャンネル毎に合成処理 */ + for (ch = 0; ch < header->num_channels; ch++) { + /* LPC合成 */ + SRLALPC_Synthesize(buffer[ch], + num_decode_samples, decoder->params_int[ch], decoder->coef_order[ch], decoder->rshifts[ch]); + /* デエンファシス */ + SRLAPreemphasisFilter_MultiStageDeemphasis( + decoder->de_emphasis[ch], SRLA_NUM_PREEMPHASIS_FILTERS, buffer[ch], num_decode_samples); + } + + /* マルチチャンネル処理 */ + switch (ch_process_method) { + case SRLA_CH_PROCESS_METHOD_NONE: + break; + case SRLA_CH_PROCESS_METHOD_MS: + SRLA_ASSERT(header->num_channels >= 2); + SRLAUtility_MStoLRConversion(buffer, num_decode_samples); + break; + case SRLA_CH_PROCESS_METHOD_LS: + SRLA_ASSERT(header->num_channels >= 2); + SRLAUtility_LStoLRConversion(buffer, num_decode_samples); + break; + case SRLA_CH_PROCESS_METHOD_RS: + SRLA_ASSERT(header->num_channels >= 2); + SRLAUtility_RStoLRConversion(buffer, num_decode_samples); + break; + default: + SRLA_ASSERT(0); + } + + /* 成功終了 */ + return SRLA_APIRESULT_OK; +} + +/* 無音データブロックデコード */ +static SRLAApiResult SRLADecoder_DecodeSilentData( + struct SRLADecoder *decoder, + const uint8_t *data, uint32_t data_size, + int32_t **buffer, uint32_t num_channels, uint32_t num_decode_samples, + uint32_t *decode_size) +{ + uint32_t ch; + const struct SRLAHeader *header; + + SRLAUTILITY_UNUSED_ARGUMENT(data_size); + + /* 内部関数なので不正な引数はアサートで落とす */ + SRLA_ASSERT(decoder != NULL); + SRLA_ASSERT(data != NULL); + SRLA_ASSERT(buffer != NULL); + SRLA_ASSERT(buffer[0] != NULL); + SRLA_ASSERT(num_decode_samples > 0); + SRLA_ASSERT(decode_size != NULL); + + /* ヘッダ取得 */ + header = &(decoder->header); + + /* チャンネル数不足もアサートで落とす */ + SRLA_ASSERT(num_channels >= header->num_channels); + + /* 全て無音で埋める */ + for (ch = 0; ch < header->num_channels; ch++) { + memset(buffer[ch], 0, sizeof(int32_t) * num_decode_samples); + } + + (*decode_size) = 0; + return SRLA_APIRESULT_OK; +} + +/* 単一データブロックデコード */ +SRLAApiResult SRLADecoder_DecodeBlock( + struct SRLADecoder *decoder, + const uint8_t *data, uint32_t data_size, + int32_t **buffer, uint32_t buffer_num_channels, uint32_t buffer_num_samples, + uint32_t *decode_size, uint32_t *num_decode_samples) +{ + uint8_t buf8; + uint16_t buf16; + uint32_t buf32; + uint16_t num_block_samples; + uint32_t block_header_size, block_data_size; + SRLAApiResult ret; + SRLABlockDataType block_type; + const struct SRLAHeader *header; + const uint8_t *read_ptr; + + /* 引数チェック */ + if ((decoder == NULL) || (data == NULL) + || (buffer == NULL) || (decode_size == NULL) + || (num_decode_samples == NULL)) { + return SRLA_APIRESULT_INVALID_ARGUMENT; + } + + /* ヘッダがまだセットされていない */ + if (!SRLADECODER_GET_STATUS_FLAG(decoder, SRLADECODER_STATUS_FLAG_SET_HEADER)) { + return SRLA_APIRESULT_PARAMETER_NOT_SET; + } + + /* ヘッダ取得 */ + header = &(decoder->header); + + /* バッファチャンネル数チェック */ + if (buffer_num_channels < header->num_channels) { + return SRLA_APIRESULT_INSUFFICIENT_BUFFER; + } + + /* ブロックヘッダデコード */ + read_ptr = data; + + /* 同期コード */ + ByteArray_GetUint16BE(read_ptr, &buf16); + /* 同期コード不一致 */ + if (buf16 != SRLA_BLOCK_SYNC_CODE) { + return SRLA_APIRESULT_INVALID_FORMAT; + } + /* ブロックサイズ */ + ByteArray_GetUint32BE(read_ptr, &buf32); + SRLA_ASSERT(buf32 > 0); + /* データサイズ不足 */ + if ((buf32 + 6) > data_size) { + return SRLA_APIRESULT_INSUFFICIENT_DATA; + } + /* ブロックチェックサム */ + ByteArray_GetUint16BE(read_ptr, &buf16); + /* チェックするならばチェックサム計算を行い取得値との一致を確認 */ + if (SRLADECODER_GET_STATUS_FLAG(decoder, SRLADECODER_STATUS_FLAG_CHECKSUM_CHECK)) { + /* チェックサム自体の領域は外すために-2 */ + uint16_t checksum = SRLAUtility_CalculateFletcher16CheckSum(read_ptr, buf32 - 2); + if (checksum != buf16) { + return SRLA_APIRESULT_DETECT_DATA_CORRUPTION; + } + } + /* ブロックデータタイプ */ + ByteArray_GetUint8(read_ptr, &buf8); + block_type = (SRLABlockDataType)buf8; + /* ブロックチャンネルあたりサンプル数 */ + ByteArray_GetUint16BE(read_ptr, &num_block_samples); + if (num_block_samples > buffer_num_samples) { + return SRLA_APIRESULT_INSUFFICIENT_BUFFER; + } + /* ブロックヘッダサイズ */ + block_header_size = (uint32_t)(read_ptr - data); + + /* データ部のデコード */ + switch (block_type) { + case SRLA_BLOCK_DATA_TYPE_RAWDATA: + ret = SRLADecoder_DecodeRawData(decoder, + read_ptr, data_size - block_header_size, buffer, header->num_channels, num_block_samples, &block_data_size); + break; + case SRLA_BLOCK_DATA_TYPE_COMPRESSDATA: + ret = SRLADecoder_DecodeCompressData(decoder, + read_ptr, data_size - block_header_size, buffer, header->num_channels, num_block_samples, &block_data_size); + break; + case SRLA_BLOCK_DATA_TYPE_SILENT: + ret = SRLADecoder_DecodeSilentData(decoder, + read_ptr, data_size - block_header_size, buffer, header->num_channels, num_block_samples, &block_data_size); + break; + default: + return SRLA_APIRESULT_INVALID_FORMAT; + } + + /* データデコードに失敗している */ + if (ret != SRLA_APIRESULT_OK) { + return ret; + } + + /* デコードサイズ */ + (*decode_size) = block_header_size + block_data_size; + + /* デコードサンプル数 */ + (*num_decode_samples) = num_block_samples; + + /* デコード成功 */ + return SRLA_APIRESULT_OK; +} + +/* ヘッダを含めて全ブロックデコード */ +SRLAApiResult SRLADecoder_DecodeWhole( + struct SRLADecoder *decoder, + const uint8_t *data, uint32_t data_size, + int32_t **buffer, uint32_t buffer_num_channels, uint32_t buffer_num_samples) +{ + SRLAApiResult ret; + uint32_t progress, ch, read_offset, read_block_size, num_decode_samples; + const uint8_t *read_pos; + int32_t *buffer_ptr[SRLA_MAX_NUM_CHANNELS]; + struct SRLAHeader tmp_header; + const struct SRLAHeader *header; + + /* 引数チェック */ + if ((decoder == NULL) || (data == NULL) || (buffer == NULL)) { + return SRLA_APIRESULT_INVALID_ARGUMENT; + } + + /* ヘッダデコードとデコーダへのセット */ + if ((ret = SRLADecoder_DecodeHeader(data, data_size, &tmp_header)) + != SRLA_APIRESULT_OK) { + return ret; + } + if ((ret = SRLADecoder_SetHeader(decoder, &tmp_header)) + != SRLA_APIRESULT_OK) { + return ret; + } + header = &(decoder->header); + + /* バッファサイズチェック */ + if ((buffer_num_channels < header->num_channels) + || (buffer_num_samples < header->num_samples)) { + return SRLA_APIRESULT_INSUFFICIENT_BUFFER; + } + + progress = 0; + read_offset = SRLA_HEADER_SIZE; + read_pos = data + SRLA_HEADER_SIZE; + while ((progress < header->num_samples) && (read_offset < data_size)) { + /* サンプル書き出し位置のセット */ + for (ch = 0; ch < header->num_channels; ch++) { + buffer_ptr[ch] = &buffer[ch][progress]; + } + /* ブロックデコード */ + if ((ret = SRLADecoder_DecodeBlock(decoder, + read_pos, data_size - read_offset, + buffer_ptr, buffer_num_channels, buffer_num_samples - progress, + &read_block_size, &num_decode_samples)) != SRLA_APIRESULT_OK) { + return ret; + } + /* 進捗更新 */ + read_pos += read_block_size; + read_offset += read_block_size; + progress += num_decode_samples; + SRLA_ASSERT(progress <= buffer_num_samples); + SRLA_ASSERT(read_offset <= data_size); + } + + /* 成功終了 */ + return SRLA_APIRESULT_OK; +} diff --git a/libs/srla_decoder/src/srla_lpc_synthesize.c b/libs/srla_decoder/src/srla_lpc_synthesize.c new file mode 100644 index 0000000..b27b95a --- /dev/null +++ b/libs/srla_decoder/src/srla_lpc_synthesize.c @@ -0,0 +1,128 @@ +#include "srla_lpc_synthesize.h" + +#include +#include "srla_internal.h" +#include "srla_utility.h" + +/* SSE4.1を使うか +#define USE_SSE41 +*/ + +/* LPC係数により合成(in-place) */ +#if !defined(USE_SSE41) +void SRLALPC_Synthesize( + int32_t *data, uint32_t num_samples, + const int32_t *coef, uint32_t coef_order, uint32_t coef_rshift) +{ + uint32_t smpl, ord; + const int32_t half = 1 << (coef_rshift - 1); /* 固定小数の0.5 */ + int32_t predict; + + /* 引数チェック */ + SRLA_ASSERT(data != NULL); + SRLA_ASSERT(coef != NULL); + + for (smpl = 0; smpl < num_samples - coef_order; smpl++) { + predict = half; + for (ord = 0; ord < coef_order; ord++) { + predict += (coef[ord] * data[smpl + ord]); + } + data[smpl + ord] -= (predict >> coef_rshift); + } +} +#else +#ifdef _MSC_VER +#include +#else +#include +#endif +void SRLALPC_Synthesize( + int32_t *data, uint32_t num_samples, + const int32_t *coef, uint32_t coef_order, uint32_t coef_rshift) +{ + int32_t smpl, ord; + const int32_t half = 1 << (coef_rshift - 1); /* 固定小数の0.5 */ + int32_t predict; + + /* 引数チェック */ + SRLA_ASSERT(data != NULL); + SRLA_ASSERT(coef != NULL); + + smpl = coef_order; + + if (coef_order >= 4) { + uint32_t i; + __m128i vcoef[SRLA_MAX_COEFFICIENT_ORDER]; + /* 係数をベクトル化 */ + for (i = 0; i < coef_order; i++) { + vcoef[i] = _mm_set1_epi32(coef[i]); + } + for (; smpl < num_samples - coef_order - 4; smpl += 4) { + /* 4サンプル並列に処理 + int32_t predict[4] = { half, half, half, half } + for (ord = 0; ord < coef_order - 3; ord++) { + predict[0] += (coef[ord] * data[smpl - coef_order + ord + 0]); + predict[1] += (coef[ord] * data[smpl - coef_order + ord + 1]); + predict[2] += (coef[ord] * data[smpl - coef_order + ord + 2]); + predict[3] += (coef[ord] * data[smpl - coef_order + ord + 3]); + } + */ + __declspec(align(16)) int32_t predict[4]; + __m128i vdata; + __m128i vpred = _mm_set1_epi32(half); + for (ord = 0; ord < (int32_t)coef_order - 3 - 4; ord += 4) { + const int32_t *dat = &data[smpl - coef_order + ord]; + vdata = _mm_loadu_epi32(&dat[0]); + vpred = _mm_add_epi32(vpred, _mm_mullo_epi32(vcoef[ord + 0], vdata)); + vdata = _mm_loadu_epi32(&dat[1]); + vpred = _mm_add_epi32(vpred, _mm_mullo_epi32(vcoef[ord + 1], vdata)); + vdata = _mm_loadu_epi32(&dat[2]); + vpred = _mm_add_epi32(vpred, _mm_mullo_epi32(vcoef[ord + 2], vdata)); + vdata = _mm_loadu_epi32(&dat[3]); + vpred = _mm_add_epi32(vpred, _mm_mullo_epi32(vcoef[ord + 3], vdata)); + } + for (; ord < coef_order - 3; ord++) { + vdata = _mm_loadu_epi32(&data[smpl - coef_order + ord]); + vpred = _mm_add_epi32(vpred, _mm_mullo_epi32(vcoef[ord], vdata)); + } + _mm_store_si128(&predict, vpred); + + /* ord = coef_order - 3 */ + /* data[smpl + 0] .. data[smpl + 2]に依存関係があるため処理 + * TODO: ここもSSEでやり切ってdataに結果を直接storeしたい + predict[0] += (coef[ord + 0] * data[smpl - 3 + 0]); + predict[0] += (coef[ord + 1] * data[smpl - 3 + 1]); + predict[0] += (coef[ord + 2] * data[smpl - 3 + 2]); + data[smpl + 0] -= (predict[0] >> coef_rshift); + predict[1] += (coef[ord + 0] * data[smpl - 3 + 1]); + predict[1] += (coef[ord + 1] * data[smpl - 3 + 2]); + predict[1] += (coef[ord + 2] * data[smpl - 3 + 3]); + data[smpl + 1] -= (predict[1] >> coef_rshift); + predict[2] += (coef[ord + 0] * data[smpl - 3 + 2]); + predict[2] += (coef[ord + 1] * data[smpl - 3 + 3]); + predict[2] += (coef[ord + 2] * data[smpl - 3 + 4]); + data[smpl + 2] -= (predict[2] >> coef_rshift); + predict[3] += (coef[ord + 0] * data[smpl - 3 + 3]); + predict[3] += (coef[ord + 1] * data[smpl - 3 + 4]); + predict[3] += (coef[ord + 2] * data[smpl - 3 + 5]); + data[smpl + 3] -= (predict[3] >> coef_rshift); + */ + for (i = 0; i < 4; i++) { + predict[i] += (coef[ord + 0] * data[smpl - 3 + i + 0]); + predict[i] += (coef[ord + 1] * data[smpl - 3 + i + 1]); + predict[i] += (coef[ord + 2] * data[smpl - 3 + i + 2]); + data[smpl + i] -= (predict[i] >> coef_rshift); + } + } + } + + /* 余ったサンプル分の処理 */ + for (; smpl < num_samples; smpl++) { + int32_t predict = half; + for (ord = 0; ord < coef_order; ord++) { + predict += (coef[ord] * data[smpl - coef_order + ord]); + } + data[smpl] -= (predict >> coef_rshift); + } +} +#endif diff --git a/libs/srla_decoder/src/srla_lpc_synthesize.h b/libs/srla_decoder/src/srla_lpc_synthesize.h new file mode 100644 index 0000000..832a872 --- /dev/null +++ b/libs/srla_decoder/src/srla_lpc_synthesize.h @@ -0,0 +1,18 @@ +#ifndef SRLA_LPCSYNTHESIZE_H_INCLUDED +#define SRLA_LPCSYNTHESIZE_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* LPC係数により合成(in-place) */ +void SRLALPC_Synthesize( + int32_t *data, uint32_t num_samples, const int32_t *coef, uint32_t coef_order, uint32_t coef_rshift); + +#ifdef __cplusplus +} +#endif + +#endif /* SRLA_LPCSYNTHESIZE_H_INCLUDED */ diff --git a/libs/srla_encoder/CMakeLists.txt b/libs/srla_encoder/CMakeLists.txt new file mode 100644 index 0000000..24db87f --- /dev/null +++ b/libs/srla_encoder/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# プロジェクト名 +project(SRLAEncoder C) + +# ライブラリ名 +set(LIB_NAME srla_encoder) + +# 静的ライブラリ指定 +add_library(${LIB_NAME} STATIC) + +# ソースディレクトリ +add_subdirectory(src) + +# インクルードパス +target_include_directories(${LIB_NAME} + PRIVATE + ${PROJECT_ROOT_PATH}/include + ${PROJECT_ROOT_PATH}/libs/byte_array/include + ${PROJECT_ROOT_PATH}/libs/bit_stream/include + ${PROJECT_ROOT_PATH}/libs/lpc/include + ${PROJECT_ROOT_PATH}/libs/srla_internal/include + ${PROJECT_ROOT_PATH}/libs/srla_coder/include + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + +# コンパイルオプション +if(MSVC) + target_compile_options(${LIB_NAME} PRIVATE /W4) +else() + target_compile_options(${LIB_NAME} PRIVATE -Wall -Wextra -Wpedantic -Wformat=2 -Wstrict-aliasing=2 -Wconversion -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition) + set(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -DDEBUG") + set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") +endif() +set_target_properties(${LIB_NAME} + PROPERTIES + C_STANDARD 90 C_EXTENSIONS OFF + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) diff --git a/libs/srla_encoder/src/CMakeLists.txt b/libs/srla_encoder/src/CMakeLists.txt new file mode 100644 index 0000000..86180ce --- /dev/null +++ b/libs/srla_encoder/src/CMakeLists.txt @@ -0,0 +1,6 @@ +target_sources(${LIB_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/srla_encoder.c + ${CMAKE_CURRENT_SOURCE_DIR}/srla_lpc_predict.c + ${CMAKE_CURRENT_SOURCE_DIR}/srla_lpc_predict.h + ) diff --git a/libs/srla_encoder/src/srla_encoder.c b/libs/srla_encoder/src/srla_encoder.c new file mode 100644 index 0000000..112cb26 --- /dev/null +++ b/libs/srla_encoder/src/srla_encoder.c @@ -0,0 +1,1025 @@ +#include "srla_encoder.h" + +#include +#include +#include +#include +#include "srla_lpc_predict.h" +#include "srla_internal.h" +#include "srla_utility.h" +#include "byte_array.h" +#include "bit_stream.h" +#include "lpc.h" +#include "srla_coder.h" + +/* エンコーダハンドル */ +struct SRLAEncoder { + struct SRLAHeader header; /* ヘッダ */ + struct SRLACoder *coder; /* 符号化ハンドル */ + uint32_t max_num_channels; /* バッファチャンネル数 */ + uint32_t max_num_samples_per_block; /* バッファサンプル数 */ + uint32_t max_num_parameters; /* 最大パラメータ数 */ + uint8_t set_parameter; /* パラメータセット済み? */ + struct LPCCalculator *lpcc; /* LPC計算ハンドル */ + struct SRLAPreemphasisFilter **pre_emphasis; /* プリエンファシスフィルタ */ + int32_t **pre_emphasis_prev; /* プリエンファシスフィルタの直前のサンプル */ + double **params_double; /* 各チャンネルのLPC係数(double) */ + int32_t **params_int; /* 各チャンネルのLPC係数(int) */ + uint32_t *rshifts; /* 各チャンネルのLPC係数右シフト量 */ + uint32_t *coef_order; /* 各チャンネルのLPC係数次数 */ + int32_t **buffer_int; /* 信号バッファ(int) */ + int32_t **residual; /* 残差信号 */ + double *buffer_double; /* 信号バッファ(double) */ + const struct SRLAParameterPreset *parameter_preset; /* パラメータプリセット */ + uint8_t alloced_by_own; /* 領域を自前確保しているか? */ + void *work; /* ワーク領域先頭ポインタ */ +}; + +/* エンコードパラメータをヘッダに変換 */ +static SRLAError SRLAEncoder_ConvertParameterToHeader( + const struct SRLAEncodeParameter *parameter, uint32_t num_samples, + struct SRLAHeader *header); +/* ブロックデータタイプの判定 */ +static SRLABlockDataType SRLAEncoder_DecideBlockDataType( + struct SRLAEncoder *encoder, const int32_t *const *input, uint32_t num_samples); + +/* ヘッダエンコード */ +SRLAApiResult SRLAEncoder_EncodeHeader( + const struct SRLAHeader *header, uint8_t *data, uint32_t data_size) +{ + uint8_t *data_pos; + + /* 引数チェック */ + if ((header == NULL) || (data == NULL)) { + return SRLA_APIRESULT_INVALID_ARGUMENT; + } + + /* 出力先バッファサイズ不足 */ + if (data_size < SRLA_HEADER_SIZE) { + return SRLA_APIRESULT_INSUFFICIENT_BUFFER; + } + + /* ヘッダ異常値のチェック */ + /* データに書き出す(副作用)前にできる限りのチェックを行う */ + /* チャンネル数 */ + if (header->num_channels == 0) { + return SRLA_APIRESULT_INVALID_FORMAT; + } + /* サンプル数 */ + if (header->num_samples == 0) { + return SRLA_APIRESULT_INVALID_FORMAT; + } + /* サンプリングレート */ + if (header->sampling_rate == 0) { + return SRLA_APIRESULT_INVALID_FORMAT; + } + /* ビット深度 */ + if (header->bits_per_sample == 0) { + return SRLA_APIRESULT_INVALID_FORMAT; + } + /* ブロックあたりサンプル数 */ + if (header->num_samples_per_block == 0) { + return SRLA_APIRESULT_INVALID_FORMAT; + } + /* パラメータプリセット */ + if (header->preset >= SRLA_NUM_PARAMETER_PRESETS) { + return SRLA_APIRESULT_INVALID_FORMAT; + } + + /* 書き出し用ポインタ設定 */ + data_pos = data; + + /* シグネチャ */ + ByteArray_PutUint8(data_pos, '1'); + ByteArray_PutUint8(data_pos, '2'); + ByteArray_PutUint8(data_pos, '4'); + ByteArray_PutUint8(data_pos, '9'); + /* フォーマットバージョン + * 補足)ヘッダの設定値は無視してマクロ値を書き込む */ + ByteArray_PutUint32BE(data_pos, SRLA_FORMAT_VERSION); + /* コーデックバージョン + * 補足)ヘッダの設定値は無視してマクロ値を書き込む */ + ByteArray_PutUint32BE(data_pos, SRLA_CODEC_VERSION); + /* チャンネル数 */ + ByteArray_PutUint16BE(data_pos, header->num_channels); + /* サンプル数 */ + ByteArray_PutUint32BE(data_pos, header->num_samples); + /* サンプリングレート */ + ByteArray_PutUint32BE(data_pos, header->sampling_rate); + /* サンプルあたりビット数 */ + ByteArray_PutUint16BE(data_pos, header->bits_per_sample); + /* ブロックあたりサンプル数 */ + ByteArray_PutUint32BE(data_pos, header->num_samples_per_block); + /* パラメータプリセット */ + ByteArray_PutUint8(data_pos, header->preset); + + /* ヘッダサイズチェック */ + SRLA_ASSERT((data_pos - data) == SRLA_HEADER_SIZE); + + /* 成功終了 */ + return SRLA_APIRESULT_OK; +} + +/* エンコードパラメータをヘッダに変換 */ +static SRLAError SRLAEncoder_ConvertParameterToHeader( + const struct SRLAEncodeParameter *parameter, uint32_t num_samples, + struct SRLAHeader *header) +{ + struct SRLAHeader tmp_header = { 0, }; + + /* 引数チェック */ + if ((parameter == NULL) || (header == NULL)) { + return SRLA_ERROR_INVALID_ARGUMENT; + } + + /* パラメータのチェック */ + if (parameter->num_channels == 0) { + return SRLA_ERROR_INVALID_FORMAT; + } + if (parameter->bits_per_sample == 0) { + return SRLA_ERROR_INVALID_FORMAT; + } + if (parameter->sampling_rate == 0) { + return SRLA_ERROR_INVALID_FORMAT; + } + if (parameter->preset >= SRLA_NUM_PARAMETER_PRESETS) { + return SRLA_ERROR_INVALID_FORMAT; + } + + /* 総サンプル数 */ + tmp_header.num_samples = num_samples; + + /* 対応するメンバをコピー */ + tmp_header.num_channels = parameter->num_channels; + tmp_header.sampling_rate = parameter->sampling_rate; + tmp_header.bits_per_sample = parameter->bits_per_sample; + tmp_header.preset = parameter->preset; + tmp_header.num_samples_per_block = parameter->num_samples_per_block; + + /* 成功終了 */ + (*header) = tmp_header; + return SRLA_ERROR_OK; +} + +/* エンコーダハンドル作成に必要なワークサイズ計算 */ +int32_t SRLAEncoder_CalculateWorkSize(const struct SRLAEncoderConfig *config) +{ + int32_t work_size, tmp_work_size; + + /* 引数チェック */ + if (config == NULL) { + return -1; + } + + /* コンフィグチェック */ + if ((config->max_num_samples_per_block == 0) + || (config->max_num_channels == 0) + || (config->max_num_parameters == 0)) { + return -1; + } + + /* ブロックサイズはパラメータ数より大きくなるべき */ + if (config->max_num_parameters > config->max_num_samples_per_block) { + return -1; + } + + /* ハンドル本体のサイズ */ + work_size = sizeof(struct SRLAEncoder) + SRLA_MEMORY_ALIGNMENT; + + /* LPC計算ハンドルのサイズ */ + { + struct LPCCalculatorConfig lpcc_config; + lpcc_config.max_num_samples = config->max_num_samples_per_block; + lpcc_config.max_order = config->max_num_parameters; + if ((tmp_work_size = LPCCalculator_CalculateWorkSize(&lpcc_config)) < 0) { + return -1; + } + work_size += tmp_work_size; + } + + /* 符号化ハンドルのサイズ */ + if ((tmp_work_size = SRLACoder_CalculateWorkSize()) < 0) { + return -1; + } + work_size += tmp_work_size; + + /* プリエンファシスフィルタのサイズ */ + work_size += SRLA_CALCULATE_2DIMARRAY_WORKSIZE(struct SRLAPreemphasisFilter, config->max_num_channels, SRLA_NUM_PREEMPHASIS_FILTERS); + work_size += SRLA_CALCULATE_2DIMARRAY_WORKSIZE(int32_t, config->max_num_channels, SRLA_NUM_PREEMPHASIS_FILTERS); + /* パラメータバッファ領域 */ + /* LPC係数(int) */ + work_size += SRLA_CALCULATE_2DIMARRAY_WORKSIZE(int32_t, config->max_num_channels, config->max_num_parameters); + /* LPC係数(double) */ + work_size += SRLA_CALCULATE_2DIMARRAY_WORKSIZE(double, config->max_num_channels, config->max_num_parameters); + /* 各チャンネルのLPC係数右シフト量 */ + work_size += SRLA_MEMORY_ALIGNMENT + sizeof(uint32_t) * config->max_num_channels; + /* 各チャンネルのLPC係数次数 */ + work_size += SRLA_MEMORY_ALIGNMENT + sizeof(uint32_t) * config->max_num_channels; + /* 信号処理バッファのサイズ */ + work_size += SRLA_CALCULATE_2DIMARRAY_WORKSIZE(int32_t, config->max_num_channels, config->max_num_samples_per_block); + work_size += config->max_num_samples_per_block * sizeof(double) + SRLA_MEMORY_ALIGNMENT; + /* 残差信号のサイズ */ + work_size += SRLA_CALCULATE_2DIMARRAY_WORKSIZE(int32_t, config->max_num_channels, config->max_num_samples_per_block); + + return work_size; +} + +/* エンコーダハンドル作成 */ +struct SRLAEncoder* SRLAEncoder_Create(const struct SRLAEncoderConfig* config, void* work, int32_t work_size) +{ + uint32_t ch, l; + struct SRLAEncoder* encoder; + uint8_t tmp_alloc_by_own = 0; + uint8_t* work_ptr; + + /* ワーク領域時前確保の場合 */ + if ((work == NULL) && (work_size == 0)) { + if ((work_size = SRLAEncoder_CalculateWorkSize(config)) < 0) { + return NULL; + } + work = malloc((uint32_t)work_size); + tmp_alloc_by_own = 1; + } + + /* 引数チェック */ + if ((config == NULL) || (work == NULL) + || (work_size < SRLAEncoder_CalculateWorkSize(config))) { + return NULL; + } + + /* コンフィグチェック */ + if ((config->max_num_channels == 0) + || (config->max_num_samples_per_block == 0) + || (config->max_num_parameters == 0)) { + return NULL; + } + + /* ブロックサイズはパラメータ数より大きくなるべき */ + if (config->max_num_parameters > config->max_num_samples_per_block) { + return NULL; + } + + /* ワーク領域先頭ポインタ取得 */ + work_ptr = (uint8_t*)work; + + /* エンコーダハンドル領域確保 */ + work_ptr = (uint8_t*)SRLAUTILITY_ROUNDUP((uintptr_t)work_ptr, SRLA_MEMORY_ALIGNMENT); + encoder = (struct SRLAEncoder*)work_ptr; + work_ptr += sizeof(struct SRLAEncoder); + + /* エンコーダメンバ設定 */ + encoder->set_parameter = 0; + encoder->alloced_by_own = tmp_alloc_by_own; + encoder->work = work; + encoder->max_num_channels = config->max_num_channels; + encoder->max_num_samples_per_block = config->max_num_samples_per_block; + encoder->max_num_parameters = config->max_num_parameters; + + /* LPC計算ハンドルの作成 */ + { + int32_t lpcc_size; + struct LPCCalculatorConfig lpcc_config; + lpcc_config.max_num_samples = config->max_num_samples_per_block; + lpcc_config.max_order = config->max_num_parameters; + lpcc_size = LPCCalculator_CalculateWorkSize(&lpcc_config); + if ((encoder->lpcc = LPCCalculator_Create(&lpcc_config, work_ptr, lpcc_size)) == NULL) { + return NULL; + } + work_ptr += lpcc_size; + } + + /* 符号化ハンドルの作成 */ + { + const int32_t coder_size = SRLACoder_CalculateWorkSize(); + if ((encoder->coder = SRLACoder_Create(work_ptr, coder_size)) == NULL) { + return NULL; + } + work_ptr += coder_size; + } + + /* プリエンファシスフィルタの作成 */ + SRLA_ALLOCATE_2DIMARRAY(encoder->pre_emphasis, + work_ptr, struct SRLAPreemphasisFilter, config->max_num_channels, SRLA_NUM_PREEMPHASIS_FILTERS); + /* プリエンファシスフィルタのバッファ領域 */ + SRLA_ALLOCATE_2DIMARRAY(encoder->pre_emphasis_prev, + work_ptr, int32_t, config->max_num_channels, SRLA_NUM_PREEMPHASIS_FILTERS); + + /* バッファ領域の確保 全てのポインタをアラインメント */ + /* LPC係数(int) */ + SRLA_ALLOCATE_2DIMARRAY(encoder->params_int, + work_ptr, int32_t, config->max_num_channels, config->max_num_parameters); + /* LPC係数(double) */ + SRLA_ALLOCATE_2DIMARRAY(encoder->params_double, + work_ptr, double, config->max_num_channels, config->max_num_parameters); + /* 各層のLPC係数右シフト量 */ + work_ptr = (uint8_t *)SRLAUTILITY_ROUNDUP((uintptr_t)work_ptr, SRLA_MEMORY_ALIGNMENT); + encoder->rshifts = (uint32_t *)work_ptr; + work_ptr += config->max_num_channels * sizeof(uint32_t); + /* 各層のLPC係数次数 */ + work_ptr = (uint8_t *)SRLAUTILITY_ROUNDUP((uintptr_t)work_ptr, SRLA_MEMORY_ALIGNMENT); + encoder->coef_order = (uint32_t *)work_ptr; + work_ptr += config->max_num_channels * sizeof(uint32_t); + + /* 信号処理用バッファ領域 */ + SRLA_ALLOCATE_2DIMARRAY(encoder->buffer_int, + work_ptr, int32_t, config->max_num_channels, config->max_num_samples_per_block); + SRLA_ALLOCATE_2DIMARRAY(encoder->residual, + work_ptr, int32_t, config->max_num_channels, config->max_num_samples_per_block); + + /* doubleバッファ */ + work_ptr = (uint8_t *)SRLAUTILITY_ROUNDUP((uintptr_t)work_ptr, SRLA_MEMORY_ALIGNMENT); + encoder->buffer_double = (double *)work_ptr; + work_ptr += config->max_num_samples_per_block * sizeof(double); + + /* バッファオーバーランチェック */ + /* 補足)既にメモリを破壊している可能性があるので、チェックに失敗したら落とす */ + SRLA_ASSERT((work_ptr - (uint8_t *)work) <= work_size); + + /* プリエンファシスフィルタ初期化 */ + for (ch = 0; ch < config->max_num_channels; ch++) { + for (l = 0; l < SRLA_NUM_PREEMPHASIS_FILTERS; l++) { + SRLAPreemphasisFilter_Initialize(&encoder->pre_emphasis[ch][l]); + } + } + + return encoder; +} + +/* エンコーダハンドルの破棄 */ +void SRLAEncoder_Destroy(struct SRLAEncoder *encoder) +{ + if (encoder != NULL) { + SRLACoder_Destroy(encoder->coder); + if (encoder->alloced_by_own == 1) { + free(encoder->work); + } + } +} + +/* エンコードパラメータの設定 */ +SRLAApiResult SRLAEncoder_SetEncodeParameter( + struct SRLAEncoder *encoder, const struct SRLAEncodeParameter *parameter) +{ + struct SRLAHeader tmp_header; + + /* 引数チェック */ + if ((encoder == NULL) || (parameter == NULL)) { + return SRLA_APIRESULT_INVALID_ARGUMENT; + } + + /* パラメータ設定がおかしくないか、ヘッダへの変換を通じて確認 */ + /* 総サンプル数はダミー値を入れる */ + if (SRLAEncoder_ConvertParameterToHeader(parameter, 0, &tmp_header) != SRLA_ERROR_OK) { + return SRLA_APIRESULT_INVALID_FORMAT; + } + + /* エンコーダの容量を越えてないかチェック */ + if ((encoder->max_num_samples_per_block < parameter->num_samples_per_block) + || (encoder->max_num_channels < parameter->num_channels)) { + return SRLA_APIRESULT_INSUFFICIENT_BUFFER; + } + /* ブロックあたりサンプル数のセット */ + tmp_header.num_samples_per_block = parameter->num_samples_per_block; + + /* ヘッダ設定 */ + encoder->header = tmp_header; + + /* エンコードプリセットを取得 */ + SRLA_ASSERT(parameter->preset < SRLA_NUM_PARAMETER_PRESETS); + encoder->parameter_preset = &g_srla_parameter_preset[parameter->preset]; + + /* パラメータ設定済みフラグを立てる */ + encoder->set_parameter = 1; + + return SRLA_APIRESULT_OK; +} + +/* ブロックデータタイプの判定 */ +static SRLABlockDataType SRLAEncoder_DecideBlockDataType( + struct SRLAEncoder *encoder, const int32_t *const *input, uint32_t num_samples) +{ + uint32_t ch, smpl; + double mean_length; + const struct SRLAHeader *header; + + SRLA_ASSERT(encoder != NULL); + SRLA_ASSERT(input != NULL); + SRLA_ASSERT(encoder->set_parameter == 1); + + header = &encoder->header; + + /* 平均符号長の計算 */ + mean_length = 0.0; + for (ch = 0; ch < header->num_channels; ch++) { + double len; + LPCApiResult ret; + /* 入力をdouble化 */ + for (smpl = 0; smpl < num_samples; smpl++) { + encoder->buffer_double[smpl] = input[ch][smpl] * pow(2.0, -(int32_t)(header->bits_per_sample - 1)); + } + /* 推定符号長計算 */ + ret = LPCCalculator_EstimateCodeLength(encoder->lpcc, + encoder->buffer_double, num_samples, + header->bits_per_sample, encoder->parameter_preset->max_num_parameters, &len, LPC_WINDOWTYPE_RECTANGULAR); + SRLA_ASSERT(ret == LPC_APIRESULT_OK); + mean_length += len; + } + mean_length /= header->num_channels; + + /* ビット幅に占める比に変換 */ + mean_length /= header->bits_per_sample; + + /* データタイプ判定 */ + + /* 圧縮が効きにくい: 生データ出力 */ + if (mean_length >= SRLA_ESTIMATED_CODELENGTH_THRESHOLD) { + return SRLA_BLOCK_DATA_TYPE_RAWDATA; + } + + /* 無音判定 */ + for (ch = 0; ch < header->num_channels; ch++) { + for (smpl = 0; smpl < num_samples; smpl++) { + if (input[ch][smpl] != 0) { + goto NOT_SILENCE; + } + } + } + return SRLA_BLOCK_DATA_TYPE_SILENT; + +NOT_SILENCE: + /* それ以外は圧縮データ */ + return SRLA_BLOCK_DATA_TYPE_COMPRESSDATA; +} + +/* 生データブロックエンコード */ +static SRLAApiResult SRLAEncoder_EncodeRawData( + struct SRLAEncoder *encoder, + const int32_t *const *input, uint32_t num_samples, + uint8_t *data, uint32_t data_size, uint32_t *output_size) +{ + uint32_t ch, smpl; + const struct SRLAHeader *header; + uint8_t *data_ptr; + + /* 内部関数なので不正な引数はアサートで落とす */ + SRLA_ASSERT(encoder != NULL); + SRLA_ASSERT(input != NULL); + SRLA_ASSERT(num_samples > 0); + SRLA_ASSERT(data != NULL); + SRLA_ASSERT(data_size > 0); + SRLA_ASSERT(output_size != NULL); + + header = &(encoder->header); + + /* 書き込み先のバッファサイズチェック */ + if (data_size < (header->bits_per_sample * num_samples * header->num_channels) / 8) { + return SRLA_APIRESULT_INSUFFICIENT_BUFFER; + } + + /* 生データをチャンネルインターリーブして出力 */ + data_ptr = data; + switch (header->bits_per_sample) { + case 8: + for (smpl = 0; smpl < num_samples; smpl++) { + for (ch = 0; ch < header->num_channels; ch++) { + ByteArray_PutUint8(data_ptr, SRLAUTILITY_SINT32_TO_UINT32(input[ch][smpl])); + SRLA_ASSERT((uint32_t)(data_ptr - data) < data_size); + } + } + break; + case 16: + for (smpl = 0; smpl < num_samples; smpl++) { + for (ch = 0; ch < header->num_channels; ch++) { + ByteArray_PutUint16BE(data_ptr, SRLAUTILITY_SINT32_TO_UINT32(input[ch][smpl])); + SRLA_ASSERT((uint32_t)(data_ptr - data) < data_size); + } + } + break; + case 24: + for (smpl = 0; smpl < num_samples; smpl++) { + for (ch = 0; ch < header->num_channels; ch++) { + ByteArray_PutUint24BE(data_ptr, SRLAUTILITY_SINT32_TO_UINT32(input[ch][smpl])); + SRLA_ASSERT((uint32_t)(data_ptr - data) < data_size); + } + } + break; + default: + SRLA_ASSERT(0); + } + + /* 書き込みサイズ取得 */ + (*output_size) = (uint32_t)(data_ptr - data); + + return SRLA_APIRESULT_OK; +} + +/* Recursive Golomb-Rice符号の平均符号長 */ +static double SRLAEncoder_CalculateRGRMeanCodeLength(double mean_abs_error, uint32_t bps) +{ + const double intmean = mean_abs_error * (1 << bps); /* 整数量子化した時の平均値 */ + const double rho = 1.0 / (1.0 + intmean); + const uint32_t k2 = (uint32_t)SRLAUTILITY_MAX(0, SRLAUtility_Log2(log(0.5127629514) / log(1.0 - rho))); + const uint32_t k1 = k2 + 1; + const double k1factor = pow(1.0 - rho, (double)(1 << k1)); + const double k2factor = pow(1.0 - rho, (double)(1 << k2)); + return (1.0 + k1) * (1.0 - k1factor) + (1.0 + k2 + (1.0 / (1.0 - k2factor))) * k1factor; +} + +/* 最適なLPC次数の選択 */ +static SRLAError SRLAEncoder_SelectBestLPCOrder(struct SRLAEncoder *encoder, + const double *input, uint32_t num_samples, SRLAChannelLPCOrderDecisionTactics tactics, + uint32_t max_coef_order, uint32_t *best_coef_order) +{ + SRLA_ASSERT(encoder != NULL); + SRLA_ASSERT(input != NULL); + SRLA_ASSERT(input == encoder->buffer_double); /* 現状エンコーダハンドルの領域の使用を想定 */ + SRLA_ASSERT(best_coef_order != NULL); + + switch (tactics) { + case SRLA_LPC_ORDER_DECISION_TACTICS_MAX_FIXED: + /* 最大次数を常に選択 */ + (*best_coef_order) = max_coef_order; + return SRLA_ERROR_OK; + case SRLA_LPC_ORDER_DECISION_TACTICS_BRUTEFORCE_SEARCH: + /* 網羅探索 */ + { + LPCApiResult ret; + double minlen, len, mabse; + uint32_t i, order, smpl, tmp_best_order = 0; + double coefs[SRLA_MAX_COEFFICIENT_ORDER][SRLA_MAX_COEFFICIENT_ORDER]; + double *pcoefs[SRLA_MAX_COEFFICIENT_ORDER]; + for (i = 0; i < SRLA_MAX_COEFFICIENT_ORDER; i++) { + pcoefs[i] = &coefs[i][0]; + } + /* 次数選択のため係数計算 */ + ret = LPCCalculator_CalculateMultipleLPCCoefficients(encoder->lpcc, + input, num_samples, pcoefs, max_coef_order, LPC_WINDOWTYPE_WELCH, 1e-6); + SRLA_ASSERT(ret == LPC_APIRESULT_OK); + + minlen = FLT_MAX; + for (order = 1; order <= max_coef_order; order++) { + const double *coef = pcoefs[order - 1]; + mabse = 0.0; + for (smpl = order; smpl < num_samples; smpl++) { + double residual = input[smpl]; + for (i = 0; i < order; i++) { + residual += coef[i] * input[smpl - i - 1]; + } + mabse += SRLAUTILITY_ABS(residual); + } + /* 残差符号のサイズ */ + len = SRLAEncoder_CalculateRGRMeanCodeLength(mabse / num_samples, encoder->header.bits_per_sample) * num_samples; + /* 係数のサイズ */ + len += SRLA_LPC_COEFFICIENT_BITWIDTH * order; + if (minlen > len) { + minlen = len; + tmp_best_order = order; + } + } + /* 結果を設定 */ + SRLA_ASSERT(tmp_best_order != 0); + (*best_coef_order) = tmp_best_order; + return SRLA_ERROR_OK; + } + case SRLA_LPC_ORDER_DECISION_TACTICS_BRUTEFORCE_ESTIMATION: + /* 残差分散の推測による網羅探索 */ + { + LPCApiResult ret; + double minlen, len, mabse; + uint32_t order, tmp_best_order = 0; + double error_vars[SRLA_MAX_COEFFICIENT_ORDER + 1]; + + /* 残差分散の計算 */ + ret = LPCCalculator_CalculateErrorVariances(encoder->lpcc, + input, num_samples, error_vars, max_coef_order, LPC_WINDOWTYPE_WELCH, 1e-6); + SRLA_ASSERT(ret == LPC_APIRESULT_OK); + + minlen = FLT_MAX; + for (order = 1; order <= max_coef_order; order++) { + /* Laplace分布の仮定で残差分散から平均絶対値を推定 */ + mabse = sqrt(error_vars[order] / 2.0); + /* 残差符号のサイズ */ + len = SRLAEncoder_CalculateRGRMeanCodeLength(mabse, encoder->header.bits_per_sample) * num_samples; + /* 係数のサイズ */ + len += SRLA_LPC_COEFFICIENT_BITWIDTH * order; + if (minlen > len) { + minlen = len; + tmp_best_order = order; + } + } + /* 結果を設定 */ + SRLA_ASSERT(tmp_best_order != 0); + (*best_coef_order) = tmp_best_order; + return SRLA_ERROR_OK; + } + default: + SRLA_ASSERT(0); + } + + return SRLA_ERROR_NG; +} + +/* 圧縮データブロックエンコード */ +static SRLAApiResult SRLAEncoder_EncodeCompressData( + struct SRLAEncoder *encoder, + const int32_t *const *input, uint32_t num_samples, + uint8_t *data, uint32_t data_size, uint32_t *output_size) +{ + uint32_t ch; + struct BitStream writer; + const struct SRLAHeader *header; + SRLAChannelProcessMethod ch_process_method = SRLA_CH_PROCESS_METHOD_INVALID; + + /* 内部関数なので不正な引数はアサートで落とす */ + SRLA_ASSERT(encoder != NULL); + SRLA_ASSERT(input != NULL); + SRLA_ASSERT(num_samples > 0); + SRLA_ASSERT(data != NULL); + SRLA_ASSERT(data_size > 0); + SRLA_ASSERT(output_size != NULL); + + /* ヘッダ取得 */ + header = &(encoder->header); + + /* マルチチャンネル処理法の決定 */ + if (header->num_channels == 1) { + ch_process_method = SRLA_CH_PROCESS_METHOD_NONE; + } else { + switch (encoder->parameter_preset->ch_process_method_tactics) { + case SRLA_CH_PROCESS_METHOD_TACTICS_NONE: + ch_process_method = SRLA_CH_PROCESS_METHOD_NONE; + break; + case SRLA_CH_PROCESS_METHOD_TACTICS_MS_FIXED: + ch_process_method = SRLA_CH_PROCESS_METHOD_MS; + break; + case SRLA_CH_PROCESS_METHOD_TACTICS_ADAPTIVE: + if (header->num_channels >= 2) { + uint32_t smpl; + double est_len[4]; + /* 入力をバッファにコピー */ + for (ch = 0; ch < 2; ch++) { + memcpy(encoder->buffer_int[ch], input[ch], sizeof(int32_t) * num_samples); + } + /* MS信号の生成 */ + SRLAUtility_LRtoMSConversion(encoder->buffer_int, num_samples); + + /* 各チャンネルの推定符号長を計算 */ + for (ch = 0; ch < 2; ch++) { + /* L,R */ + for (smpl = 0; smpl < num_samples; smpl++) { + encoder->buffer_double[smpl] = input[ch][smpl] * pow(2.0, -(int32_t)(header->bits_per_sample - 1)); + } + LPCCalculator_EstimateCodeLength(encoder->lpcc, + encoder->buffer_double, num_samples, header->bits_per_sample, encoder->parameter_preset->max_num_parameters, + &est_len[ch], LPC_WINDOWTYPE_WELCH); + /* M,S */ + for (smpl = 0; smpl < num_samples; smpl++) { + encoder->buffer_double[smpl] = encoder->buffer_int[ch][smpl] * pow(2.0, -(int32_t)(header->bits_per_sample - 1)); + } + LPCCalculator_EstimateCodeLength(encoder->lpcc, + encoder->buffer_double, num_samples, header->bits_per_sample, encoder->parameter_preset->max_num_parameters, + &est_len[2 + ch], LPC_WINDOWTYPE_WELCH); + } + /* 最小の符号長を選択 */ + { + uint32_t i; + SRLAChannelProcessMethod argmin; + double len[4], min; + SRLA_STATIC_ASSERT((SRLA_CH_PROCESS_METHOD_NONE == 0) && (SRLA_CH_PROCESS_METHOD_MS == 1) + && (SRLA_CH_PROCESS_METHOD_LS == 2) && (SRLA_CH_PROCESS_METHOD_RS == 3)); + len[SRLA_CH_PROCESS_METHOD_NONE] = est_len[0] + est_len[1]; + len[SRLA_CH_PROCESS_METHOD_MS] = est_len[2] + est_len[3]; + len[SRLA_CH_PROCESS_METHOD_LS] = est_len[0] + est_len[3]; + len[SRLA_CH_PROCESS_METHOD_RS] = est_len[1] + est_len[3]; + min = len[SRLA_CH_PROCESS_METHOD_NONE]; argmin = SRLA_CH_PROCESS_METHOD_NONE; + for (i = 1; i < 4; i++) { + if (min > len[i]) { + min = len[i]; + argmin = (SRLAChannelProcessMethod)i; + } + } + ch_process_method = argmin; + } + } + break; + default: + SRLA_ASSERT(0); + } + } + + /* 入力をバッファにコピー */ + for (ch = 0; ch < header->num_channels; ch++) { + memcpy(encoder->buffer_int[ch], input[ch], sizeof(int32_t) * num_samples); + /* バッファサイズより小さい入力のときは、末尾を0埋め */ + if (num_samples < encoder->max_num_samples_per_block) { + const uint32_t remain = encoder->max_num_samples_per_block - num_samples; + memset(&encoder->buffer_int[ch][num_samples], 0, sizeof(int32_t) * remain); + } + } + + /* マルチチャンネル処理 */ + switch (ch_process_method) { + case SRLA_CH_PROCESS_METHOD_NONE: + break; + case SRLA_CH_PROCESS_METHOD_MS: + SRLA_ASSERT(header->num_channels >= 2); + SRLAUtility_LRtoMSConversion(encoder->buffer_int, num_samples); + break; + case SRLA_CH_PROCESS_METHOD_LS: + SRLA_ASSERT(header->num_channels >= 2); + SRLAUtility_LRtoLSConversion(encoder->buffer_int, num_samples); + break; + case SRLA_CH_PROCESS_METHOD_RS: + SRLA_ASSERT(header->num_channels >= 2); + SRLAUtility_LRtoRSConversion(encoder->buffer_int, num_samples); + break; + default: + SRLA_ASSERT(0); + } + + /* プリエンファシス */ + for (ch = 0; ch < header->num_channels; ch++) { + uint32_t p; + for (p = 0; p < SRLA_NUM_PREEMPHASIS_FILTERS; p++) { + /* 直前値には先頭の同一値が続くと考える */ + encoder->pre_emphasis[ch][p].prev = encoder->pre_emphasis_prev[ch][p] = encoder->buffer_int[ch][0]; + SRLAPreemphasisFilter_CalculateCoefficient(&encoder->pre_emphasis[ch][p], encoder->buffer_int[ch], num_samples); + SRLAPreemphasisFilter_Preemphasis(&encoder->pre_emphasis[ch][p], encoder->buffer_int[ch], num_samples); + } + } + + /* チャンネル毎にパラメータ計算 */ + for (ch = 0; ch < header->num_channels; ch++) { + uint32_t smpl, p; + LPCApiResult ret; + /* double精度の信号に変換([-1,1]の範囲に正規化) */ + for (smpl = 0; smpl < num_samples; smpl++) { + encoder->buffer_double[smpl] = encoder->buffer_int[ch][smpl] * pow(2.0, -(int32_t)(header->bits_per_sample - 1)); + } + /* 次数選択 */ + SRLAEncoder_SelectBestLPCOrder(encoder, + encoder->buffer_double, num_samples, encoder->parameter_preset->lpc_order_tactics, + encoder->parameter_preset->max_num_parameters, &encoder->coef_order[ch]); + /* LPC係数計算 */ + ret = LPCCalculator_CalculateLPCCoefficientsSVR(encoder->lpcc, + encoder->buffer_double, num_samples, + encoder->params_double[ch], encoder->coef_order[ch], encoder->parameter_preset->svr_max_num_iterations, + LPC_WINDOWTYPE_WELCH, 1e-6, encoder->parameter_preset->margin_list, encoder->parameter_preset->margin_list_size); + SRLA_ASSERT(ret == LPC_APIRESULT_OK); + /* 畳み込み演算でインデックスが増える方向にしたい都合上パラメータ順序を変転 */ + for (p = 0; p < encoder->coef_order[ch] / 2; p++) { + double tmp = encoder->params_double[ch][p]; + encoder->params_double[ch][p] = encoder->params_double[ch][encoder->coef_order[ch] - p - 1]; + encoder->params_double[ch][encoder->coef_order[ch] - p - 1] = tmp; + } + ret = LPC_QuantizeCoefficients(encoder->params_double[ch], encoder->coef_order[ch], + SRLA_LPC_COEFFICIENT_BITWIDTH, (1 << SRLA_RSHIFT_LPC_COEFFICIENT_BITWIDTH), + encoder->params_int[ch], &encoder->rshifts[ch]); + SRLA_ASSERT(ret == LPC_APIRESULT_OK); + } + + /* チャンネル毎にLPC予測 */ + for (ch = 0; ch < header->num_channels; ch++) { + /* LPC予測 */ + SRLALPC_Predict(encoder->buffer_int[ch], + num_samples, encoder->params_int[ch], encoder->coef_order[ch], encoder->residual[ch], encoder->rshifts[ch]); + } + + /* ビットライタ作成 */ + BitWriter_Open(&writer, data, data_size); + + /* マルチチャンネル処理法の書き込み */ + SRLA_ASSERT(ch_process_method != SRLA_CH_PROCESS_METHOD_INVALID); + SRLA_ASSERT(ch_process_method < 4); + BitWriter_PutBits(&writer, ch_process_method, 2); + + /* パラメータ符号化 */ + /* プリエンファシス */ + for (ch = 0; ch < header->num_channels; ch++) { + uint32_t p, uval; + for (p = 0; p < SRLA_NUM_PREEMPHASIS_FILTERS; p++) { + /* プリエンファシスフィルタのバッファ */ + uval = SRLAUTILITY_SINT32_TO_UINT32(encoder->pre_emphasis_prev[ch][p]); + SRLA_ASSERT(uval < (1 << (header->bits_per_sample + 1))); + BitWriter_PutBits(&writer, uval, header->bits_per_sample + 1); + /* プリエンファシス係数は正値に制限しているため1bitケチれる */ + SRLA_ASSERT(encoder->pre_emphasis[ch][p].coef >= 0); + uval = (uint32_t)encoder->pre_emphasis[ch][p].coef; + SRLA_ASSERT(uval < (1 << (SRLA_PREEMPHASIS_COEF_SHIFT - 1))); + BitWriter_PutBits(&writer, uval, SRLA_PREEMPHASIS_COEF_SHIFT - 1); + } + } + /* LPC係数次数/LPC係数右シフト量/LPC係数 */ + for (ch = 0; ch < header->num_channels; ch++) { + uint32_t i, uval; + /* LPC係数次数 */ + SRLA_ASSERT(encoder->coef_order[ch] > 0); + SRLA_ASSERT(encoder->coef_order[ch] <= (1 << SRLA_LPC_COEFFICIENT_ORDER_BITWIDTH)); + BitWriter_PutBits(&writer, encoder->coef_order[ch] - 1, SRLA_LPC_COEFFICIENT_ORDER_BITWIDTH); + /* LPC係数右シフト量 */ + SRLA_ASSERT(encoder->rshifts[ch] < (1 << SRLA_RSHIFT_LPC_COEFFICIENT_BITWIDTH)); + BitWriter_PutBits(&writer, encoder->rshifts[ch], SRLA_RSHIFT_LPC_COEFFICIENT_BITWIDTH); + /* LPC係数 */ + for (i = 0; i < encoder->coef_order[ch]; i++) { + uval = SRLAUTILITY_SINT32_TO_UINT32(encoder->params_int[ch][i]); + SRLA_ASSERT(uval < (1 << SRLA_LPC_COEFFICIENT_BITWIDTH)); + BitWriter_PutBits(&writer, uval, SRLA_LPC_COEFFICIENT_BITWIDTH); + } + } + + /* 残差符号化 */ + for (ch = 0; ch < header->num_channels; ch++) { + SRLACoder_Encode(encoder->coder, &writer, encoder->residual[ch], num_samples); + } + + /* バイト境界に揃える */ + BitStream_Flush(&writer); + + /* 書き込みサイズの取得 */ + BitStream_Tell(&writer, (int32_t *)output_size); + + /* ビットライタ破棄 */ + BitStream_Close(&writer); + + return SRLA_APIRESULT_OK; +} + +/* 無音データブロックエンコード */ +static SRLAApiResult SRLAEncoder_EncodeSilentData( + struct SRLAEncoder *encoder, + const int32_t *const *input, uint32_t num_samples, + uint8_t *data, uint32_t data_size, uint32_t *output_size) +{ + /* 内部関数なので不正な引数はアサートで落とす */ + SRLA_ASSERT(encoder != NULL); + SRLA_ASSERT(input != NULL); + SRLA_ASSERT(num_samples > 0); + SRLA_ASSERT(data != NULL); + SRLA_ASSERT(data_size > 0); + SRLA_ASSERT(output_size != NULL); + + /* データサイズなし */ + (*output_size) = 0; + return SRLA_APIRESULT_OK; +} + +/* 単一データブロックエンコード */ +SRLAApiResult SRLAEncoder_EncodeBlock( + struct SRLAEncoder *encoder, + const int32_t *const *input, uint32_t num_samples, + uint8_t *data, uint32_t data_size, uint32_t *output_size) +{ + uint8_t *data_ptr; + const struct SRLAHeader *header; + SRLABlockDataType block_type; + SRLAApiResult ret; + uint32_t block_header_size, block_data_size; + + /* 引数チェック */ + if ((encoder == NULL) || (input == NULL) || (num_samples == 0) + || (data == NULL) || (data_size == 0) || (output_size == NULL)) { + return SRLA_APIRESULT_INVALID_ARGUMENT; + } + header = &(encoder->header); + + /* パラメータがセットされてない */ + if (encoder->set_parameter != 1) { + return SRLA_APIRESULT_PARAMETER_NOT_SET; + } + + /* エンコードサンプル数チェック */ + if (num_samples > header->num_samples_per_block) { + return SRLA_APIRESULT_INSUFFICIENT_BUFFER; + } + + /* 圧縮手法の判定 */ + block_type = SRLAEncoder_DecideBlockDataType(encoder, input, num_samples); + SRLA_ASSERT(block_type != SRLA_BLOCK_DATA_TYPE_INVALID); + + /* ブロックヘッダをエンコード */ + data_ptr = data; + /* ブロック先頭の同期コード */ + ByteArray_PutUint16BE(data_ptr, SRLA_BLOCK_SYNC_CODE); + /* ブロックサイズ: 仮値で埋めておく */ + ByteArray_PutUint32BE(data_ptr, 0); + /* ブロックチェックサム: 仮値で埋めておく */ + ByteArray_PutUint16BE(data_ptr, 0); + /* ブロックデータタイプ */ + ByteArray_PutUint8(data_ptr, block_type); + /* ブロックチャンネルあたりサンプル数 */ + ByteArray_PutUint16BE(data_ptr, num_samples); + /* ブロックヘッダサイズ */ + block_header_size = (uint32_t)(data_ptr - data); + + /* データ部のエンコード */ + /* 手法によりエンコードする関数を呼び分け */ + switch (block_type) { + case SRLA_BLOCK_DATA_TYPE_RAWDATA: + ret = SRLAEncoder_EncodeRawData(encoder, input, num_samples, + data_ptr, data_size - block_header_size, &block_data_size); + break; + case SRLA_BLOCK_DATA_TYPE_COMPRESSDATA: + ret = SRLAEncoder_EncodeCompressData(encoder, input, num_samples, + data_ptr, data_size - block_header_size, &block_data_size); + break; + case SRLA_BLOCK_DATA_TYPE_SILENT: + ret = SRLAEncoder_EncodeSilentData(encoder, input, num_samples, + data_ptr, data_size - block_header_size, &block_data_size); + break; + default: + ret = SRLA_APIRESULT_INVALID_FORMAT; + break; + } + + /* エンコードに失敗している */ + if (ret != SRLA_APIRESULT_OK) { + return ret; + } + + /* ブロックサイズ書き込み: + * チェックサム(2byte) + ブロックチャンネルあたりサンプル数(2byte) + ブロックデータタイプ(1byte) */ + ByteArray_WriteUint32BE(&data[2], block_data_size + 5); + + /* チェックサムの領域以降のチェックサムを計算し書き込み */ + { + /* ブロックチャンネルあたりサンプル数(2byte) + ブロックデータタイプ(1byte) を加算 */ + const uint16_t checksum = SRLAUtility_CalculateFletcher16CheckSum(&data[8], block_data_size + 3); + ByteArray_WriteUint16BE(&data[6], checksum); + } + + /* 出力サイズ */ + (*output_size) = block_header_size + block_data_size; + + /* エンコード成功 */ + return SRLA_APIRESULT_OK; +} + +/* ヘッダ含めファイル全体をエンコード */ +SRLAApiResult SRLAEncoder_EncodeWhole( + struct SRLAEncoder *encoder, + const int32_t *const *input, uint32_t num_samples, + uint8_t *data, uint32_t data_size, uint32_t *output_size) +{ + SRLAApiResult ret; + uint32_t progress, ch, write_size, write_offset, num_encode_samples; + uint8_t *data_pos; + const int32_t *input_ptr[SRLA_MAX_NUM_CHANNELS]; + const struct SRLAHeader *header; + + /* 引数チェック */ + if ((encoder == NULL) || (input == NULL) + || (data == NULL) || (output_size == NULL)) { + return SRLA_APIRESULT_INVALID_ARGUMENT; + } + + /* パラメータがセットされてない */ + if (encoder->set_parameter != 1) { + return SRLA_APIRESULT_PARAMETER_NOT_SET; + } + + /* 書き出し位置を取得 */ + data_pos = data; + + /* ヘッダエンコード */ + encoder->header.num_samples = num_samples; + if ((ret = SRLAEncoder_EncodeHeader(&(encoder->header), data_pos, data_size)) + != SRLA_APIRESULT_OK) { + return ret; + } + header = &(encoder->header); + + /* 進捗状況初期化 */ + progress = 0; + write_offset = SRLA_HEADER_SIZE; + data_pos = data + SRLA_HEADER_SIZE; + + /* ブロックを時系列順にエンコード */ + while (progress < num_samples) { + + /* エンコードサンプル数の確定 */ + num_encode_samples + = SRLAUTILITY_MIN(header->num_samples_per_block, num_samples - progress); + + /* サンプル参照位置のセット */ + for (ch = 0; ch < header->num_channels; ch++) { + input_ptr[ch] = &input[ch][progress]; + } + + /* ブロックエンコード */ + if ((ret = SRLAEncoder_EncodeBlock(encoder, + input_ptr, num_encode_samples, + data_pos, data_size - write_offset, &write_size)) != SRLA_APIRESULT_OK) { + return ret; + } + + /* 進捗更新 */ + data_pos += write_size; + write_offset += write_size; + progress += num_encode_samples; + SRLA_ASSERT(write_offset <= data_size); + } + + /* 成功終了 */ + (*output_size) = write_offset; + return SRLA_APIRESULT_OK; +} diff --git a/libs/srla_encoder/src/srla_lpc_predict.c b/libs/srla_encoder/src/srla_lpc_predict.c new file mode 100644 index 0000000..5c59392 --- /dev/null +++ b/libs/srla_encoder/src/srla_lpc_predict.c @@ -0,0 +1,30 @@ +#include "srla_lpc_predict.h" + +#include +#include "srla_internal.h" + +/* LPC係数により予測/誤差出力 */ +void SRLALPC_Predict( + const int32_t *data, uint32_t num_samples, + const int32_t *coef, uint32_t coef_order, int32_t *residual, uint32_t coef_rshift) +{ + uint32_t smpl, ord; + int32_t predict; + const int32_t half = 1 << (coef_rshift - 1); /* 固定小数の0.5 */ + + /* 引数チェック */ + SRLA_ASSERT(data != NULL); + SRLA_ASSERT(coef != NULL); + SRLA_ASSERT(residual != NULL); + + memcpy(residual, data, sizeof(int32_t) * num_samples); + + /* 予測 */ + for (smpl = 0; smpl < num_samples - coef_order; smpl++) { + predict = half; + for (ord = 0; ord < coef_order; ord++) { + predict += (coef[ord] * data[smpl + ord]); + } + residual[smpl + ord] += (predict >> coef_rshift); + } +} diff --git a/libs/srla_encoder/src/srla_lpc_predict.h b/libs/srla_encoder/src/srla_lpc_predict.h new file mode 100644 index 0000000..e5c125a --- /dev/null +++ b/libs/srla_encoder/src/srla_lpc_predict.h @@ -0,0 +1,19 @@ +#ifndef SRLA_LPCPREDICTOR_H_INCLUDED +#define SRLA_LPCPREDICTOR_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* LPC係数により予測/誤差出力 */ +void SRLALPC_Predict( + const int32_t *data, uint32_t num_samples, + const int32_t *coef, uint32_t coef_order, int32_t *residual, uint32_t coef_rshift); + +#ifdef __cplusplus +} +#endif + +#endif /* SRLA_LPCPREDICTOR_H_INCLUDED */ diff --git a/libs/srla_internal/CMakeLists.txt b/libs/srla_internal/CMakeLists.txt new file mode 100644 index 0000000..7093cc9 --- /dev/null +++ b/libs/srla_internal/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# プロジェクト名 +project(SRLAInternal C) + +# ライブラリ名 +set(LIB_NAME srla_internal) + +# 静的ライブラリ指定 +add_library(${LIB_NAME} STATIC) + +# ソースディレクトリ +add_subdirectory(src) + +# インクルードパス +target_include_directories(${LIB_NAME} + PRIVATE + ${PROJECT_ROOT_PATH}/include + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + +# コンパイルオプション +if(MSVC) + target_compile_options(${LIB_NAME} PRIVATE /W4) +else() + target_compile_options(${LIB_NAME} PRIVATE -Wall -Wextra -Wpedantic -Wformat=2 -Wstrict-aliasing=2 -Wconversion -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition) + set(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -DDEBUG") + set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") +endif() +set_target_properties(${LIB_NAME} + PROPERTIES + C_STANDARD 90 C_EXTENSIONS OFF + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) diff --git a/libs/srla_internal/include/srla_internal.h b/libs/srla_internal/include/srla_internal.h new file mode 100644 index 0000000..ab31821 --- /dev/null +++ b/libs/srla_internal/include/srla_internal.h @@ -0,0 +1,102 @@ +#ifndef SRLA_INTERNAL_H_INCLUDED +#define SRLA_INTERNAL_H_INCLUDED + +#include "srla.h" +#include "srla_stdint.h" + +/* 本ライブラリのメモリアラインメント */ +#define SRLA_MEMORY_ALIGNMENT 16 +/* ブロック先頭の同期コード */ +#define SRLA_BLOCK_SYNC_CODE 0xFFFF + +/* 内部エンコードパラメータ */ +/* プリエンファシスの係数シフト量 */ +#define SRLA_PREEMPHASIS_COEF_SHIFT 5 +/* プリエンファシスフィルタの適用回数 */ +#define SRLA_NUM_PREEMPHASIS_FILTERS 2 +/* LPC係数のビット幅 */ +#define SRLA_LPC_COEFFICIENT_BITWIDTH 8 +/* LPC係数右シフト量のビット幅 */ +#define SRLA_RSHIFT_LPC_COEFFICIENT_BITWIDTH 4 +/* (LPC係数次数-1)のビット幅 */ +#define SRLA_LPC_COEFFICIENT_ORDER_BITWIDTH 5 +/* 圧縮をやめて生データを出力するときの閾値(サンプルあたりビット数に占める比率) */ +#define SRLA_ESTIMATED_CODELENGTH_THRESHOLD 0.95f + +/* アサートマクロ */ +#ifdef NDEBUG +/* 未使用変数警告を明示的に回避 */ +#define SRLA_ASSERT(condition) ((void)(condition)) +#else +#include +#define SRLA_ASSERT(condition) assert(condition) +#endif + +/* 静的アサートマクロ */ +#define SRLA_STATIC_ASSERT(expr) extern void assertion_failed(char dummy[(expr) ? 1 : -1]) + +/* ブロックデータタイプ */ +typedef enum SRLABlockDataTypeTag { + SRLA_BLOCK_DATA_TYPE_COMPRESSDATA = 0, /* 圧縮済みデータ */ + SRLA_BLOCK_DATA_TYPE_SILENT = 1, /* 無音データ */ + SRLA_BLOCK_DATA_TYPE_RAWDATA = 2, /* 生データ */ + SRLA_BLOCK_DATA_TYPE_INVALID = 3 /* 無効 */ +} SRLABlockDataType; + +/* マルチチャンネル処理の決定方法 */ +typedef enum SRLAChannelProcessMethodTacticsTag { + SRLA_CH_PROCESS_METHOD_TACTICS_NONE = 0, /* 何もしない */ + SRLA_CH_PROCESS_METHOD_TACTICS_MS_FIXED, /* ステレオMS処理を常に選択 */ + SRLA_CH_PROCESS_METHOD_TACTICS_ADAPTIVE, /* 適応的にLR,LS,RS,MSを選択 */ + SRLA_CH_PROCESS_METHOD_TACTICS_INVALID /* 無効値 */ +} SRLAChannelProcessMethodTactics; + +/* マルチチャンネル処理法 */ +typedef enum SRLAChannelProcessMethodTag { + SRLA_CH_PROCESS_METHOD_NONE = 0, /* 何もしない */ + SRLA_CH_PROCESS_METHOD_MS = 1, /* ステレオMS処理 */ + SRLA_CH_PROCESS_METHOD_LS = 2, /* ステレオLS処理 */ + SRLA_CH_PROCESS_METHOD_RS = 3, /* ステレオRS処理 */ + SRLA_CH_PROCESS_METHOD_INVALID /* 無効値 */ +} SRLAChannelProcessMethod; + +/* LPCの次数決定方法 */ +typedef enum SRLAChannelLPCOrderDecisionTacticsTag { + SRLA_LPC_ORDER_DECISION_TACTICS_MAX_FIXED = 0, /* 最大次数を常に選択 */ + SRLA_LPC_ORDER_DECISION_TACTICS_BRUTEFORCE_SEARCH, /* 素朴な網羅探索 */ + SRLA_LPC_ORDER_DECISION_TACTICS_BRUTEFORCE_ESTIMATION, /* 残差分散の推定による網羅探索 */ + SRLA_LPC_ORDER_DECISION_TACTICS_INVALID /* 無効値 */ +} SRLAChannelLPCOrderDecisionTactics; + +/* 内部エラー型 */ +typedef enum SRLAErrorTag { + SRLA_ERROR_OK = 0, /* OK */ + SRLA_ERROR_NG, /* 分類不能な失敗 */ + SRLA_ERROR_INVALID_ARGUMENT, /* 不正な引数 */ + SRLA_ERROR_INVALID_FORMAT, /* 不正なフォーマット */ + SRLA_ERROR_INSUFFICIENT_BUFFER, /* バッファサイズが足りない */ + SRLA_ERROR_INSUFFICIENT_DATA /* データサイズが足りない */ +} SRLAError; + +/* パラメータプリセット */ +struct SRLAParameterPreset { + uint32_t max_num_parameters; /* 最大パラメータ数 */ + SRLAChannelProcessMethodTactics ch_process_method_tactics; /* マルチチャンネル処理の決定法 */ + SRLAChannelLPCOrderDecisionTactics lpc_order_tactics; /* LPCの次数決定法 */ + uint32_t svr_max_num_iterations; /* SVRの最大繰り返し回数 */ + const double *margin_list; /* マージンリスト */ + uint32_t margin_list_size; /* マージンリストサイズ */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* パラメータプリセット配列 */ +extern const struct SRLAParameterPreset g_srla_parameter_preset[]; + +#ifdef __cplusplus +} +#endif + +#endif /* SRLA_INTERNAL_H_INCLUDED */ diff --git a/libs/srla_internal/include/srla_utility.h b/libs/srla_internal/include/srla_utility.h new file mode 100644 index 0000000..cb60db6 --- /dev/null +++ b/libs/srla_internal/include/srla_utility.h @@ -0,0 +1,148 @@ +#ifndef SRLAUTILITY_H_INCLUDED +#define SRLAUTILITY_H_INCLUDED + +#include "srla_stdint.h" +#include + +/* 未使用引数警告回避 */ +#define SRLAUTILITY_UNUSED_ARGUMENT(arg) ((void)(arg)) +/* 算術右シフト */ +#if ((((int32_t)-1) >> 1) == ((int32_t)-1)) +/* 算術右シフトが有効な環境では、そのまま右シフト */ +#define SRLAUTILITY_SHIFT_RIGHT_ARITHMETIC(sint32, rshift) ((sint32) >> (rshift)) +#else +/* 算術右シフトが無効な環境では、自分で定義する ハッカーのたのしみのより引用 */ +/* 注意)有効範囲:0 <= rshift <= 32 */ +#define SRLAUTILITY_SHIFT_RIGHT_ARITHMETIC(sint32, rshift) ((((uint64_t)(sint32) + 0x80000000UL) >> (rshift)) - (0x80000000UL >> (rshift))) +#endif +/* 符号関数 ハッカーのたのしみより引用 補足)val==0の時は0を返す */ +#define SRLAUTILITY_SIGN(val) (((val) > 0) - ((val) < 0)) +/* nの倍数への切り上げ */ +#define SRLAUTILITY_ROUNDUP(val, n) ((((val) + ((n) - 1)) / (n)) * (n)) +/* 最大値の取得 */ +#define SRLAUTILITY_MAX(a,b) (((a) > (b)) ? (a) : (b)) +/* 最小値の取得 */ +#define SRLAUTILITY_MIN(a,b) (((a) < (b)) ? (a) : (b)) +/* 最小値以上最小値以下に制限 */ +#define SRLAUTILITY_INNER_VALUE(val, min, max) (SRLAUTILITY_MIN((max), SRLAUTILITY_MAX((min), (val)))) +/* 2の冪乗か? */ +#define SRLAUTILITY_IS_POWERED_OF_2(val) (!((val) & ((val) - 1))) +/* 符号付き32bit数値を符号なし32bit数値に一意変換 */ +#define SRLAUTILITY_SINT32_TO_UINT32(sint) (((int32_t)(sint) < 0) ? ((uint32_t)((-((sint) << 1)) - 1)) : ((uint32_t)(((sint) << 1)))) +/* 符号なし32bit数値を符号付き32bit数値に一意変換 */ +#define SRLAUTILITY_UINT32_TO_SINT32(uint) ((int32_t)((uint) >> 1) ^ -(int32_t)((uint) & 1)) +/* 絶対値の取得 */ +#define SRLAUTILITY_ABS(val) (((val) > 0) ? (val) : -(val)) + +/* NLZ(最上位ビットから1に当たるまでのビット数)の計算 */ +#if defined(__GNUC__) +/* ビルトイン関数を使用 */ +#define SRLAUTILITY_NLZ(x) (((x) > 0) ? (uint32_t)__builtin_clz(x) : 32U) +#elif defined(_MSC_VER) +/* ビルトイン関数を使用 */ +__inline uint32_t SRLAUTILITY_NLZ(uint32_t x) +{ + unsigned long result; + return (_BitScanReverse(&result, x) != 0) ? (31U - result) : 32U; +} +#else +/* ソフトウェア実装を使用 */ +#define SRLAUTILITY_NLZ(x) SRLAUtility_NLZSoft(x) +#endif + +/* ceil(log2(val))の計算 */ +#define SRLAUTILITY_LOG2CEIL(x) (32U - SRLAUTILITY_NLZ((uint32_t)((x) - 1U))) +/* floor(log2(val))の計算 */ +#define SRLAUTILITY_LOG2FLOOR(x) (31U - SRLAUTILITY_NLZ(x)) + +/* 2の冪乗数(1,2,4,8,16,...)への切り上げ */ +#if defined(__GNUC__) || defined(_MSC_VER) +/* ビルトイン関数を使用 */ +#define SRLAUTILITY_ROUNDUP2POWERED(x) (1U << SRLAUTILITY_LOG2CEIL(x)) +#else +/* ソフトウェア実装を使用 */ +#define SRLAUTILITY_ROUNDUP2POWERED(x) SRLAUtility_RoundUp2PoweredSoft(x) +#endif + +/* 2次元配列の領域ワークサイズ計算 */ +#define SRLA_CALCULATE_2DIMARRAY_WORKSIZE(type, size1, size2)\ + ((size1) * ((int32_t)sizeof(type *) + SRLA_MEMORY_ALIGNMENT\ + + (size2) * (int32_t)sizeof(type) + SRLA_MEMORY_ALIGNMENT)) + +/* 2次元配列の領域割当て */ +#define SRLA_ALLOCATE_2DIMARRAY(ptr, work_ptr, type, size1, size2)\ + do {\ + uint32_t i;\ + (work_ptr) = (uint8_t *)SRLAUTILITY_ROUNDUP((uintptr_t)work_ptr, SRLA_MEMORY_ALIGNMENT);\ + (ptr) = (type **)work_ptr;\ + (work_ptr) += sizeof(type *) * (size1);\ + for (i = 0; i < (size1); i++) {\ + (work_ptr) = (uint8_t *)SRLAUTILITY_ROUNDUP((uintptr_t)work_ptr, SRLA_MEMORY_ALIGNMENT);\ + (ptr)[i] = (type *)work_ptr;\ + (work_ptr) += sizeof(type) * (size2);\ + }\ + } while (0) + +/* プリエンファシス/デエンファシスフィルタ */ +struct SRLAPreemphasisFilter { + int32_t prev; + int32_t coef; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* round関数(C89で用意されていない) */ +double SRLAUtility_Round(double d); + +/* log2関数(C89で定義されていない) */ +double SRLAUtility_Log2(double d); + +/* フレッチャーのチェックサム計算 */ +uint16_t SRLAUtility_CalculateFletcher16CheckSum(const uint8_t *data, size_t data_size); + +/* NLZ(最上位ビットから1に当たるまでのビット数)の計算 */ +uint32_t SRLAUtility_NLZSoft(uint32_t val); + +/* 2の冪乗に切り上げる */ +uint32_t SRLAUtility_RoundUp2PoweredSoft(uint32_t val); + +/* LR -> MS (in-place) */ +void SRLAUtility_LRtoMSConversion(int32_t **buffer, uint32_t num_samples); + +/* MS -> LR (in-place) */ +void SRLAUtility_MStoLRConversion(int32_t **buffer, uint32_t num_samples); + +/* LR -> LS (in-place) */ +void SRLAUtility_LRtoLSConversion(int32_t **buffer, uint32_t num_samples); + +/* LS -> LR (in-place) */ +void SRLAUtility_LStoLRConversion(int32_t **buffer, uint32_t num_samples); + +/* LR -> RS (in-place) */ +void SRLAUtility_LRtoRSConversion(int32_t **buffer, uint32_t num_samples); + +/* RS -> LR (in-place) */ +void SRLAUtility_RStoLRConversion(int32_t **buffer, uint32_t num_samples); + +/* プリエンファシスフィルタ初期化 */ +void SRLAPreemphasisFilter_Initialize(struct SRLAPreemphasisFilter *preem); + +/* プリエンファシスフィルタ係数計算 */ +void SRLAPreemphasisFilter_CalculateCoefficient( + struct SRLAPreemphasisFilter *preem, const int32_t *buffer, uint32_t num_samples); + +/* プリエンファシス */ +void SRLAPreemphasisFilter_Preemphasis( + struct SRLAPreemphasisFilter *preem, int32_t *buffer, uint32_t num_samples); + +/* デエンファシスを複数回適用 */ +void SRLAPreemphasisFilter_MultiStageDeemphasis( + struct SRLAPreemphasisFilter *preem, uint32_t num_preem, int32_t *buffer, uint32_t num_samples); + +#ifdef __cplusplus +} +#endif + +#endif /* SRLAUTILITY_H_INCLUDED */ diff --git a/libs/srla_internal/src/CMakeLists.txt b/libs/srla_internal/src/CMakeLists.txt new file mode 100644 index 0000000..879b98a --- /dev/null +++ b/libs/srla_internal/src/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${LIB_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/srla_internal.c + ${CMAKE_CURRENT_SOURCE_DIR}/srla_utility.c + ) diff --git a/libs/srla_internal/src/srla_internal.c b/libs/srla_internal/src/srla_internal.c new file mode 100644 index 0000000..4d69441 --- /dev/null +++ b/libs/srla_internal/src/srla_internal.c @@ -0,0 +1,21 @@ +#include "srla_internal.h" + +/* 配列の要素数を取得 */ +#define SRLA_NUM_ARRAY_ELEMENTS(array) ((sizeof(array)) / (sizeof(array[0]))) +/* プリセットの要素定義 */ +#define SRLA_DEFINE_ARRAY_AND_NUM_ELEMTNS_TUPLE(array) array, SRLA_NUM_ARRAY_ELEMENTS(array) + +/* マージンリスト候補配列 */ +static const double margin_list[] = { 0.0, 1.0 / 4096, 1.0 / 1024, 1.0 / 256, 1.0 / 64, 1.0 / 16 }; + +/* パラメータプリセット配列 */ +const struct SRLAParameterPreset g_srla_parameter_preset[] = { + { 32, SRLA_CH_PROCESS_METHOD_TACTICS_ADAPTIVE, SRLA_LPC_ORDER_DECISION_TACTICS_MAX_FIXED, 0, SRLA_DEFINE_ARRAY_AND_NUM_ELEMTNS_TUPLE(margin_list) }, + { 32, SRLA_CH_PROCESS_METHOD_TACTICS_ADAPTIVE, SRLA_LPC_ORDER_DECISION_TACTICS_MAX_FIXED, 10, SRLA_DEFINE_ARRAY_AND_NUM_ELEMTNS_TUPLE(margin_list) }, + { 32, SRLA_CH_PROCESS_METHOD_TACTICS_ADAPTIVE, SRLA_LPC_ORDER_DECISION_TACTICS_BRUTEFORCE_ESTIMATION, 0, SRLA_DEFINE_ARRAY_AND_NUM_ELEMTNS_TUPLE(margin_list) }, + { 32, SRLA_CH_PROCESS_METHOD_TACTICS_ADAPTIVE, SRLA_LPC_ORDER_DECISION_TACTICS_BRUTEFORCE_ESTIMATION, 10, SRLA_DEFINE_ARRAY_AND_NUM_ELEMTNS_TUPLE(margin_list) }, + { 32, SRLA_CH_PROCESS_METHOD_TACTICS_ADAPTIVE, SRLA_LPC_ORDER_DECISION_TACTICS_BRUTEFORCE_SEARCH, 0, SRLA_DEFINE_ARRAY_AND_NUM_ELEMTNS_TUPLE(margin_list) }, + { 32, SRLA_CH_PROCESS_METHOD_TACTICS_ADAPTIVE, SRLA_LPC_ORDER_DECISION_TACTICS_BRUTEFORCE_SEARCH, 10, SRLA_DEFINE_ARRAY_AND_NUM_ELEMTNS_TUPLE(margin_list) } +}; + +SRLA_STATIC_ASSERT(SRLA_NUM_ARRAY_ELEMENTS(g_srla_parameter_preset) == SRLA_NUM_PARAMETER_PRESETS); diff --git a/libs/srla_internal/src/srla_utility.c b/libs/srla_internal/src/srla_utility.c new file mode 100644 index 0000000..ae50c82 --- /dev/null +++ b/libs/srla_internal/src/srla_utility.c @@ -0,0 +1,268 @@ +#include "srla_utility.h" + +#include +#include +#include "srla_internal.h" + +/* NLZ計算のためのテーブル */ +#define UNUSED 99 +static const uint32_t st_nlz10_table[64] = { + 32, 20, 19, UNUSED, UNUSED, 18, UNUSED, 7, + 10, 17, UNUSED, UNUSED, 14, UNUSED, 6, UNUSED, + UNUSED, 9, UNUSED, 16, UNUSED, UNUSED, 1, 26, + UNUSED, 13, UNUSED, UNUSED, 24, 5, UNUSED, UNUSED, + UNUSED, 21, UNUSED, 8, 11, UNUSED, 15, UNUSED, + UNUSED, UNUSED, UNUSED, 2, 27, 0, 25, UNUSED, + 22, UNUSED, 12, UNUSED, UNUSED, 3, 28, UNUSED, + 23, UNUSED, 4, 29, UNUSED, UNUSED, 30, 31 +}; +#undef UNUSED + +/* round関数(C89で用意されていない) */ +double SRLAUtility_Round(double d) +{ + return (d >= 0.0) ? floor(d + 0.5) : -floor(-d + 0.5); +} + +/* log2関数(C89で定義されていない) */ +double SRLAUtility_Log2(double d) +{ +#define INV_LOGE2 (1.4426950408889634) /* 1 / log(2) */ + return log(d) * INV_LOGE2; +#undef INV_LOGE2 +} + +/* フレッチャーのチェックサム計算 */ +uint16_t SRLAUtility_CalculateFletcher16CheckSum(const uint8_t *data, size_t data_size) +{ +#define MAX_BLOCK_SIZE 5802 /* c1のmodが変化しないブロックサイズ */ +#define MOD255(x) (((x) + ((x) / 255)) & 0xFF) /* 255の剰余計算 */ + uint32_t c0, c1; + + /* 引数チェック */ + SRLA_ASSERT(data != NULL); + + c0 = c1 = 0; + while (data_size > 0) { + size_t block_size = SRLAUTILITY_MIN(MAX_BLOCK_SIZE, data_size); + data_size -= block_size; + while (block_size--) { + c0 += *data++; + c1 += c0; + } + c0 = MOD255(c0); + c1 = MOD255(c1); + } + + return (uint16_t)((c1 << 8) | c0); +#undef MOD255 +#undef MAX_BLOCK_SIZE +} + +/* NLZ(最上位ビットから1に当たるまでのビット数)の計算 */ +uint32_t SRLAUtility_NLZSoft(uint32_t x) +{ + /* ハッカーのたのしみ参照 */ + x = x | (x >> 1); + x = x | (x >> 2); + x = x | (x >> 4); + x = x | (x >> 8); + x = x & ~(x >> 16); + x = (x << 9) - x; + x = (x << 11) - x; + x = (x << 14) - x; + return st_nlz10_table[x >> 26]; +} + +/* 2の冪乗数に切り上げる */ +uint32_t SRLAUtility_RoundUp2PoweredSoft(uint32_t val) +{ + /* ハッカーのたのしみ参照 */ + val--; + val |= val >> 1; + val |= val >> 2; + val |= val >> 4; + val |= val >> 8; + val |= val >> 16; + return val + 1; +} + +/* LR -> MS (in-place) */ +void SRLAUtility_LRtoMSConversion(int32_t **buffer, uint32_t num_samples) +{ + uint32_t smpl; + + SRLA_ASSERT(buffer != NULL); + SRLA_ASSERT(buffer[0] != NULL); + SRLA_ASSERT(buffer[1] != NULL); + + for (smpl = 0; smpl < num_samples; smpl++) { + buffer[1][smpl] -= buffer[0][smpl]; + buffer[0][smpl] += (buffer[1][smpl] >> 1); + } +} + +/* MS -> LR (in-place) */ +void SRLAUtility_MStoLRConversion(int32_t **buffer, uint32_t num_samples) +{ + uint32_t smpl; + + SRLA_ASSERT(buffer != NULL); + SRLA_ASSERT(buffer[0] != NULL); + SRLA_ASSERT(buffer[1] != NULL); + + for (smpl = 0; smpl < num_samples; smpl++) { + buffer[0][smpl] -= (buffer[1][smpl] >> 1); + buffer[1][smpl] += buffer[0][smpl]; + } +} + +/* LR -> LS (in-place) */ +void SRLAUtility_LRtoLSConversion(int32_t **buffer, uint32_t num_samples) +{ + uint32_t smpl; + + SRLA_ASSERT(buffer != NULL); + SRLA_ASSERT(buffer[0] != NULL); + SRLA_ASSERT(buffer[1] != NULL); + + for (smpl = 0; smpl < num_samples; smpl++) { + buffer[1][smpl] -= buffer[0][smpl]; + } +} + +/* LS -> LR (in-place) */ +void SRLAUtility_LStoLRConversion(int32_t **buffer, uint32_t num_samples) +{ + uint32_t smpl; + + SRLA_ASSERT(buffer != NULL); + SRLA_ASSERT(buffer[0] != NULL); + SRLA_ASSERT(buffer[1] != NULL); + + for (smpl = 0; smpl < num_samples; smpl++) { + buffer[1][smpl] += buffer[0][smpl]; + } +} + +/* LR -> RS (in-place) */ +void SRLAUtility_LRtoRSConversion(int32_t **buffer, uint32_t num_samples) +{ + uint32_t smpl; + + SRLA_ASSERT(buffer != NULL); + SRLA_ASSERT(buffer[0] != NULL); + SRLA_ASSERT(buffer[1] != NULL); + + for (smpl = 0; smpl < num_samples; smpl++) { + buffer[0][smpl] = buffer[1][smpl] - buffer[0][smpl]; + } +} + +/* RS -> LR (in-place) */ +void SRLAUtility_RStoLRConversion(int32_t **buffer, uint32_t num_samples) +{ + uint32_t smpl; + + SRLA_ASSERT(buffer != NULL); + SRLA_ASSERT(buffer[0] != NULL); + SRLA_ASSERT(buffer[1] != NULL); + + for (smpl = 0; smpl < num_samples; smpl++) { + buffer[0][smpl] = buffer[1][smpl] - buffer[0][smpl]; + } +} + +/* プリエンファシスフィルタ初期化 */ +void SRLAPreemphasisFilter_Initialize(struct SRLAPreemphasisFilter *preem) +{ + SRLA_ASSERT(preem != NULL); + preem->prev = 0; + preem->coef = 0; +} + +/* プリエンファシスフィルタ係数計算 */ +void SRLAPreemphasisFilter_CalculateCoefficient( + struct SRLAPreemphasisFilter *preem, const int32_t *buffer, uint32_t num_samples) +{ + uint32_t smpl; + int32_t coef; + double corr[2] = { 0.0, 0.0 }; + double curr; + + SRLA_ASSERT(preem != NULL); + SRLA_ASSERT(buffer != NULL); + + /* 相関の計算 */ + curr = buffer[0]; + for (smpl = 0; smpl < num_samples - 1; smpl++) { + const double succ = buffer[smpl + 1]; + corr[0] += curr * curr; + corr[1] += curr * succ; + curr = succ; + } + /* 分散(=0次相関)で正規化 */ + corr[1] /= corr[0]; + + /* 固定小数化 */ + if ((corr[0] < 1e-6) || (corr[1] < 0.0)) { + /* 1次相関が負の場合は振動しているためプリエンファシスの効果は薄い */ + coef = 0; + } else { + coef = (int32_t)SRLAUtility_Round(corr[1] * pow(2.0f, SRLA_PREEMPHASIS_COEF_SHIFT)); + /* 丸め込み */ + if (coef >= (1 << (SRLA_PREEMPHASIS_COEF_SHIFT - 1))) { + coef = (1 << (SRLA_PREEMPHASIS_COEF_SHIFT - 1)) - 1; + } + } + + preem->coef = coef; +} + +/* プリエンファシス */ +void SRLAPreemphasisFilter_Preemphasis( + struct SRLAPreemphasisFilter *preem, int32_t *buffer, uint32_t num_samples) +{ + uint32_t smpl; + int32_t prev, tmp; + + SRLA_ASSERT(buffer != NULL); + SRLA_ASSERT(preem != NULL); + + prev = preem->prev; + for (smpl = 0; smpl < num_samples; smpl++) { + tmp = buffer[smpl]; + buffer[smpl] -= (prev * preem->coef) >> SRLA_PREEMPHASIS_COEF_SHIFT; + prev = tmp; + } + preem->prev = prev; +} + +/* デエンファシスを複数回適用 */ +void SRLAPreemphasisFilter_MultiStageDeemphasis( + struct SRLAPreemphasisFilter *preem, uint32_t num_preem, int32_t *buffer, uint32_t num_samples) +{ + uint32_t smpl; + const int32_t c0 = preem[0].coef; + const int32_t c1 = preem[1].coef; + + /* 注意)現段階では2回を前提 */ + SRLA_STATIC_ASSERT(SRLA_NUM_PREEMPHASIS_FILTERS == 2); + SRLA_ASSERT(num_preem == 2); + + SRLA_ASSERT(buffer != NULL); + SRLA_ASSERT(preem != NULL); + + buffer[0] += (preem[1].prev * c1) >> SRLA_PREEMPHASIS_COEF_SHIFT; + buffer[1] += (buffer[0] * c1) >> SRLA_PREEMPHASIS_COEF_SHIFT; + buffer[0] += (preem[0].prev * c0) >> SRLA_PREEMPHASIS_COEF_SHIFT; + + for (smpl = 2; smpl < num_samples; smpl++) { + buffer[smpl] += (buffer[smpl - 1] * c1) >> SRLA_PREEMPHASIS_COEF_SHIFT; + buffer[smpl - 1] += (buffer[smpl - 2] * c0) >> SRLA_PREEMPHASIS_COEF_SHIFT; + } + + preem[0].prev = buffer[num_samples - 1]; + buffer[num_samples - 1] += (buffer[num_samples - 2] * c0) >> SRLA_PREEMPHASIS_COEF_SHIFT; + preem[1].prev = buffer[num_samples - 1]; +} diff --git a/libs/wav/CMakeLists.txt b/libs/wav/CMakeLists.txt new file mode 100644 index 0000000..8905d6a --- /dev/null +++ b/libs/wav/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.15) + +# プロジェクト名 +project(Wav C) + +# ライブラリ名 +set(LIB_NAME wav) + +# 静的ライブラリ指定 +add_library(${LIB_NAME} STATIC) + +# ソースディレクトリ +add_subdirectory(src) + +# インクルードパス +target_include_directories(${LIB_NAME} + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + +# コンパイルオプション +if(MSVC) + target_compile_options(${LIB_NAME} PRIVATE /W4) +else() + target_compile_options(${LIB_NAME} PRIVATE -Wall -Wextra -Wpedantic -Wformat=2 -Wstrict-aliasing=2 -Wconversion -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition) + set(CMAKE_C_FLAGS_DEBUG "-O0 -g3 -DDEBUG") + set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") +endif() +set_target_properties(${LIB_NAME} + PROPERTIES + C_STANDARD 90 C_EXTENSIONS OFF + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) diff --git a/libs/wav/include/wav.h b/libs/wav/include/wav.h new file mode 100644 index 0000000..06e922a --- /dev/null +++ b/libs/wav/include/wav.h @@ -0,0 +1,66 @@ +#ifndef WAV_INCLUDED +#define WAV_INCLUDED + +#include + +/* PCM型 - ファイルのビット深度如何によらず、メモリ上では全て符号付き32bitで取り扱う */ +typedef int32_t WAVPcmData; + +/* WAVデータのフォーマット */ +typedef enum WAVDataFormatTag { + WAV_DATA_FORMAT_PCM /* PCMのみ対応 */ +} WAVDataFormat; + +/* API結果型 */ +typedef enum WAVApiResultTag { + WAV_APIRESULT_OK = 0, + WAV_APIRESULT_NG, + WAV_APIRESULT_INVALID_FORMAT, /* フォーマットが不正 */ + WAV_APIRESULT_IOERROR, /* ファイル入出力エラー */ + WAV_APIRESULT_INVALID_PARAMETER /* 引数が不正 */ +} WAVApiResult; + +/* WAVファイルフォーマット */ +struct WAVFileFormat { + WAVDataFormat data_format; /* データフォーマット */ + uint32_t num_channels; /* チャンネル数 */ + uint32_t sampling_rate; /* サンプリングレート */ + uint32_t bits_per_sample; /* 量子化ビット数 */ + uint32_t num_samples; /* サンプル数 */ +}; + +/* WAVファイルハンドル */ +struct WAVFile { + struct WAVFileFormat format; /* フォーマット */ + WAVPcmData** data; /* 実データ */ +}; + +/* アクセサ */ +#define WAVFile_PCM(wavfile, samp, ch) (wavfile->data[(ch)][(samp)]) + +#ifdef __cplusplus +extern "C" { +#endif + +/* ファイルからWAVファイルハンドルを作成 */ +struct WAVFile* WAV_CreateFromFile(const char* filename); + +/* フォーマットを指定して新規にWAVファイルハンドルを作成 */ +struct WAVFile* WAV_Create(const struct WAVFileFormat* format); + +/* WAVファイルハンドルを破棄 */ +void WAV_Destroy(struct WAVFile* wavfile); + +/* ファイル書き出し */ +WAVApiResult WAV_WriteToFile( + const char* filename, const struct WAVFile* wavfile); + +/* ファイルからWAVファイルフォーマットだけ読み取り */ +WAVApiResult WAV_GetWAVFormatFromFile( + const char* filename, struct WAVFileFormat* format); + +#ifdef __cplusplus +} +#endif + +#endif /* WAV_INCLUDED */ diff --git a/libs/wav/src/CMakeLists.txt b/libs/wav/src/CMakeLists.txt new file mode 100644 index 0000000..4b6ac15 --- /dev/null +++ b/libs/wav/src/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/wav.c + ) diff --git a/libs/wav/src/wav.c b/libs/wav/src/wav.c new file mode 100644 index 0000000..da7ba8f --- /dev/null +++ b/libs/wav/src/wav.c @@ -0,0 +1,990 @@ +#include "wav.h" + +#include +#include +#include +#include + +/* パーサの読み込みバッファサイズ */ +#define WAVBITBUFFER_BUFFER_SIZE (10 * 1024) + +/* 下位n_bitsを取得 */ +/* 補足)((1 << n_bits) - 1)は下位の数値だけ取り出すマスクになる */ +#define WAV_GetLowerBits(n_bits, val) ((val) & (uint32_t)((1 << (n_bits)) - 1)) + +/* a,bの内の小さい値を取得 */ +#define WAV_Min(a, b) (((a) < (b)) ? (a) : (b)) + +/* 内部エラー型 */ +typedef enum WAVErrorTag { + WAV_ERROR_OK = 0, /* OK */ + WAV_ERROR_NG, /* 分類不能な失敗 */ + WAV_ERROR_IO, /* 入出力エラー */ + WAV_ERROR_INVALID_PARAMETER, /* 不正な引数 */ + WAV_ERROR_INVALID_FORMAT /* 不正なフォーマット */ +} WAVError; + +/* ビットバッファ */ +struct WAVBitBuffer { + uint8_t bytes[WAVBITBUFFER_BUFFER_SIZE]; /* ビットバッファ */ + uint32_t bit_count; /* ビット入力カウント */ + int32_t byte_pos; /* バイト列読み込み位置 */ +}; + +/* パーサ */ +struct WAVParser { + FILE* fp; /* 読み込みファイルポインタ */ + struct WAVBitBuffer buffer; /* ビットバッファ */ +}; + +/* ライタ */ +struct WAVWriter { + FILE* fp; /* 書き込みファイルポインタ */ + uint32_t bit_buffer; /* 出力途中のビット */ + uint32_t bit_count; /* 出力カウント */ + struct WAVBitBuffer buffer; /* ビットバッファ */ +}; + +/* パーサの初期化 */ +static void WAVParser_Initialize(struct WAVParser* parser, FILE* fp); +/* パーサの使用終了 */ +static void WAVParser_Finalize(struct WAVParser* parser); +/* n_bit 取得し、結果を右詰めする */ +static WAVError WAVParser_GetBits(struct WAVParser* parser, uint32_t n_bits, uint64_t* bitsbuf); +/* シーク(fseek準拠) */ +static WAVError WAVParser_Seek(struct WAVParser* parser, int32_t offset, int32_t wherefrom); +/* ライタの初期化 */ +static void WAVWriter_Initialize(struct WAVWriter* writer, FILE* fp); +/* ライタの終了 */ +static void WAVWriter_Finalize(struct WAVWriter* writer); +/* valの下位n_bitを書き込む */ +static WAVError WAVWriter_PutBits(struct WAVWriter* writer, uint64_t val, uint32_t n_bits); +/* バッファにたまったビットをクリア */ +static WAVError WAVWriter_Flush(struct WAVWriter* writer); +/* リトルエンディアンでビットパターンを出力 */ +static WAVError WAVWriter_PutLittleEndianBytes( + struct WAVWriter* writer, uint32_t nbytes, uint64_t data); + +/* ライタを使用してファイルフォーマットに従ったヘッダ部を出力 */ +static WAVError WAVWriter_PutWAVHeader( + struct WAVWriter* writer, const struct WAVFileFormat* format); +/* ライタを使用してPCMデータ出力 */ +static WAVError WAVWriter_PutWAVPcmData( + struct WAVWriter* writer, const struct WAVFile* wavfile); + +/* リトルエンディアンでビットパターンを取得 */ +static WAVError WAVParser_GetLittleEndianBytes( + struct WAVParser* parser, uint32_t nbytes, uint64_t* bitsbuf); +/* パーサを使用して文字列取得 */ +static WAVError WAVParser_GetString( + struct WAVParser* parser, char* string_buffer, uint32_t string_length); +/* パーサを使用して文字列取得/一致チェック */ +static WAVError WAVParser_CheckSignatureString( + struct WAVParser* parser, const char* signature, uint32_t signature_length); +/* パーサを使用してファイルフォーマットを読み取り */ +static WAVError WAVParser_GetWAVFormat( + struct WAVParser* parser, struct WAVFileFormat* format); +/* パーサを使用してPCMデータを読み取り */ +static WAVError WAVParser_GetWAVPcmData( + struct WAVParser* parser, struct WAVFile* wavfile); + +/* 8bitPCM形式を32bit形式に変換 */ +static int32_t WAV_Convert8bitPCMto32bitPCM(int32_t in_8bitpcm); +/* 16bitPCM形式を32bit形式に変換 */ +static int32_t WAV_Convert16bitPCMto32bitPCM(int32_t in_16bitpcm); +/* 24bitPCM形式を32bit形式に変換 */ +static int32_t WAV_Convert24bitPCMto32bitPCM(int32_t in_24bitpcm); +/* 32bitPCM形式を32bit形式に変換 */ +static int32_t WAV_Convert32bitPCMto32bitPCM(int32_t in_32bitpcm); + +/* 32bitPCM形式を32bit形式に変換 */ +static int32_t WAV_Convert32bitPCMto32bitPCM(int32_t in_32bitpcm); + +/* パーサを使用してファイルフォーマットを読み取り */ +static WAVError WAVParser_GetWAVFormat( + struct WAVParser* parser, struct WAVFileFormat* format) +{ + uint64_t bitsbuf; + int32_t fmt_chunk_size; + struct WAVFileFormat tmp_format; + + /* 引数チェック */ + if (parser == NULL || format == NULL) { + return WAV_ERROR_INVALID_PARAMETER; + } + + /* ヘッダ 'R', 'I', 'F', 'F' をチェック */ + if (WAVParser_CheckSignatureString(parser, "RIFF", 4) != WAV_ERROR_OK) { + return WAV_ERROR_INVALID_FORMAT; + } + + /* ファイルサイズ-8(読み飛ばし) */ + if (WAVParser_GetLittleEndianBytes(parser, 4, &bitsbuf) != WAV_ERROR_OK) { return WAV_ERROR_IO; } + + /* ヘッダ 'W', 'A', 'V', 'E' をチェック */ + if (WAVParser_CheckSignatureString(parser, "WAVE", 4) != WAV_ERROR_OK) { + return WAV_ERROR_INVALID_FORMAT; + } + + /* fmtチャンクのヘッダ 'f', 'm', 't', ' ' をチェック */ + if (WAVParser_CheckSignatureString(parser, "fmt ", 4) != WAV_ERROR_OK) { + return WAV_ERROR_INVALID_FORMAT; + } + + /* fmtチャンクのバイト数を取得 + * 補足/注意)16より大きいサイズのfmtチャンクの内容(拡張)は読み飛ばす */ + if (WAVParser_GetLittleEndianBytes(parser, 4, &bitsbuf) != WAV_ERROR_OK) { return WAV_ERROR_IO; } + fmt_chunk_size = (int32_t)bitsbuf; + + /* フォーマットIDをチェック + * 補足)1(リニアPCM)以外対応していない */ + if (WAVParser_GetLittleEndianBytes(parser, 2, &bitsbuf) != WAV_ERROR_OK) { return WAV_ERROR_IO; } + if (bitsbuf != 1) { + /* fprintf(stderr, "Unsupported format: fmt chunk format ID \n"); */ + return WAV_ERROR_INVALID_FORMAT; + } + tmp_format.data_format = WAV_DATA_FORMAT_PCM; + + /* チャンネル数 */ + if (WAVParser_GetLittleEndianBytes(parser, 2, &bitsbuf) != WAV_ERROR_OK) { return WAV_ERROR_IO; } + tmp_format.num_channels = (uint32_t)bitsbuf; + + /* サンプリングレート */ + if (WAVParser_GetLittleEndianBytes(parser, 4, &bitsbuf) != WAV_ERROR_OK) { return WAV_ERROR_IO; } + tmp_format.sampling_rate =(uint32_t) bitsbuf; + + /* データ速度(byte/sec)は読み飛ばし */ + if (WAVParser_GetLittleEndianBytes(parser, 4, &bitsbuf) != WAV_ERROR_OK) { return WAV_ERROR_IO; } + + /* ブロックあたりサイズ数は読み飛ばし */ + if (WAVParser_GetLittleEndianBytes(parser, 2, &bitsbuf) != WAV_ERROR_OK) { return WAV_ERROR_IO; } + + /* 量子化ビット数(サンプルあたりのビット数) */ + if (WAVParser_GetLittleEndianBytes(parser, 2, &bitsbuf) != WAV_ERROR_OK) { return WAV_ERROR_IO; } + tmp_format.bits_per_sample = (uint32_t)bitsbuf; + + /* 拡張部分の読み取りには未対応: 読み飛ばしを行う */ + if (fmt_chunk_size > 16) { + fprintf(stderr, "Warning: skip fmt chunk extention (unsupported). \n"); + if (WAVParser_Seek(parser, fmt_chunk_size - 16, SEEK_CUR) != WAV_ERROR_OK) { return WAV_ERROR_IO; } + } + + /* チャンク読み取り */ + while (1) { + char string_buf[4]; + /* チャンク文字列取得 */ + if (WAVParser_GetString(parser, string_buf, 4) != WAV_ERROR_OK) { + return WAV_ERROR_IO; + } + if (strncmp(string_buf, "data", 4) == 0) { + /* データチャンクを見つけたら終わり */ + break; + } else { + /* 他のチャンクはサイズだけ取得してシークにより読み飛ばす */ + if (WAVParser_GetLittleEndianBytes(parser, 4, &bitsbuf) != WAV_ERROR_OK) { + return WAV_ERROR_IO; + } + /* printf("chunk:%s size:%d \n", string_buf, (int32_t)bitsbuf); */ + WAVParser_Seek(parser, (int32_t)bitsbuf, SEEK_CUR); + } + } + + /* サンプル数: 波形データバイト数から算出 */ + if (WAVParser_GetLittleEndianBytes(parser, 4, &bitsbuf) != WAV_ERROR_OK) { return WAV_ERROR_IO; } + tmp_format.num_samples = (uint32_t)bitsbuf; + assert(tmp_format.num_samples % ((tmp_format.bits_per_sample / 8) * tmp_format.num_channels) == 0); + tmp_format.num_samples /= ((tmp_format.bits_per_sample / 8) * tmp_format.num_channels); + + /* 構造体コピー */ + *format = tmp_format; + + return WAV_ERROR_OK; +} + +/* パーサを使用してPCMデータを読み取り */ +static WAVError WAVParser_GetWAVPcmData( + struct WAVParser* parser, struct WAVFile* wavfile) +{ + uint32_t ch, sample, bytes_per_sample; + uint64_t bitsbuf; + int32_t (*convert_to_sint32_func)(int32_t); + + /* 引数チェック */ + if (parser == NULL || wavfile == NULL) { + return WAV_ERROR_INVALID_PARAMETER; + } + + /* ビット深度に合わせてPCMデータの変換関数を決定 */ + switch (wavfile->format.bits_per_sample) { + case 8: + convert_to_sint32_func = WAV_Convert8bitPCMto32bitPCM; + break; + case 16: + convert_to_sint32_func = WAV_Convert16bitPCMto32bitPCM; + break; + case 24: + convert_to_sint32_func = WAV_Convert24bitPCMto32bitPCM; + break; + case 32: + convert_to_sint32_func = WAV_Convert32bitPCMto32bitPCM; + break; + default: + /* fprintf(stderr, "Unsupported bits per sample format(=%d). \n", wavfile->format.bits_per_sample); */ + return WAV_ERROR_INVALID_FORMAT; + } + + /* データ読み取り */ + bytes_per_sample = wavfile->format.bits_per_sample / 8; + for (sample = 0; sample < wavfile->format.num_samples; sample++) { + for (ch = 0; ch < wavfile->format.num_channels; ch++) { + if (WAVParser_GetLittleEndianBytes(parser, bytes_per_sample, &bitsbuf) != WAV_ERROR_OK) { + return WAV_ERROR_IO; + } + /* 32bit整数形式に変形してデータにセット */ + wavfile->data[ch][sample] = convert_to_sint32_func((int32_t)(bitsbuf)); + } + } + + return WAV_ERROR_OK; +} + +/* ファイルからWAVファイルフォーマットだけ読み取り */ +WAVApiResult WAV_GetWAVFormatFromFile( + const char* filename, struct WAVFileFormat* format) +{ + struct WAVParser parser; + FILE* fp; + + /* 引数チェック */ + if (filename == NULL || format == NULL) { + return WAV_APIRESULT_NG; + } + + /* wavファイルを開く */ + fp = fopen(filename, "rb"); + if (fp == NULL) { + /* fprintf(stderr, "Failed to open %s. \n", filename); */ + return WAV_APIRESULT_NG; + } + + /* パーサ初期化 */ + WAVParser_Initialize(&parser, fp); + + /* ヘッダ読み取り */ + if (WAVParser_GetWAVFormat(&parser, format) != WAV_ERROR_OK) { + return WAV_APIRESULT_NG; + } + + /* パーサ使用終了 */ + WAVParser_Finalize(&parser); + + /* ファイルを閉じる */ + fclose(fp); + + return WAV_APIRESULT_OK; +} + +/* ファイルからWAVファイルハンドルを作成 */ +struct WAVFile* WAV_CreateFromFile(const char* filename) +{ + struct WAVParser parser; + FILE* fp; + struct WAVFile* wavfile; + struct WAVFileFormat format; + + /* 引数チェック */ + if (filename == NULL) { + return NULL; + } + + /* wavファイルを開く */ + fp = fopen(filename, "rb"); + if (fp == NULL) { + /* fprintf(stderr, "Failed to open %s. \n", filename); */ + return NULL; + } + + /* パーサ初期化 */ + WAVParser_Initialize(&parser, fp); + + /* ヘッダ読み取り */ + if (WAVParser_GetWAVFormat(&parser, &format) != WAV_ERROR_OK) { + return NULL; + } + + /* ハンドル作成 */ + wavfile = WAV_Create(&format); + if (wavfile == NULL) { + return NULL; + } + + /* PCMデータ読み取り */ + if (WAVParser_GetWAVPcmData(&parser, wavfile) != WAV_ERROR_OK) { + goto EXIT_FAILURE_WITH_DATA_RELEASE; + } + + /* パーサ終了 */ + WAVParser_Finalize(&parser); + + /* ファイルを閉じる */ + fclose(fp); + + /* 正常終了 */ + return wavfile; + + /* ハンドルが確保したデータを全て解放して終了 */ +EXIT_FAILURE_WITH_DATA_RELEASE: + WAV_Destroy(wavfile); + WAVParser_Finalize(&parser); + fclose(fp); + return NULL; +} + +/* フォーマットを指定して新規にWAVファイルハンドルを作成 */ +struct WAVFile* WAV_Create(const struct WAVFileFormat* format) +{ + uint32_t ch; + struct WAVFile* wavfile; + + /* 引数チェック */ + if (format == NULL) { + return NULL; + } + + /* 現在はPCMフォーマット以外対応していない */ + if (format->data_format != WAV_DATA_FORMAT_PCM) { + /* fprintf(stderr, "Unsupported wav data format. \n"); */ + return NULL; + } + + /* ハンドル作成 */ + wavfile = (struct WAVFile *)malloc(sizeof(struct WAVFile)); + if (wavfile == NULL) { + goto EXIT_FAILURE_WITH_DATA_RELEASE; + } + + /* 構造体コピーによりフォーマット情報取得 */ + wavfile->format = (*format); + + /* データ領域の割り当て */ + wavfile->data = (WAVPcmData **)malloc(sizeof(WAVPcmData *) * format->num_channels); + if (wavfile->data == NULL) { + goto EXIT_FAILURE_WITH_DATA_RELEASE; + } + for (ch = 0; ch < format->num_channels; ch++) { + wavfile->data[ch] = (WAVPcmData *)calloc(format->num_samples, sizeof(WAVPcmData)); + if (wavfile->data[ch] == NULL) { + goto EXIT_FAILURE_WITH_DATA_RELEASE; + } + } + + return wavfile; + +EXIT_FAILURE_WITH_DATA_RELEASE: + WAV_Destroy(wavfile); + return NULL; +} + +/* 8bitPCM形式を32bit形式に変換 */ +static int32_t WAV_Convert8bitPCMto32bitPCM(int32_t in_8bitpcm) +{ + /* 無音に相当する128を引いてから32bit整数に切り上げる */ + return (in_8bitpcm - 128) << 24; +} + +/* 16bitPCM形式を32bit形式に変換 */ +static int32_t WAV_Convert16bitPCMto32bitPCM(int32_t in_16bitpcm) +{ + /* そのまま16bit左シフト */ + return in_16bitpcm << 16; +} + +/* 24bitPCM形式を32bit形式に変換 */ +static int32_t WAV_Convert24bitPCMto32bitPCM(int32_t in_24bitpcm) +{ + /* そのまま8bit左シフト */ + return in_24bitpcm << 8; +} + +/* 32bitPCM形式を32bit形式に変換 */ +static int32_t WAV_Convert32bitPCMto32bitPCM(int32_t in_32bitpcm) +{ + /* 何もしない */ + return in_32bitpcm; +} + +/* パーサの初期化 */ +static void WAVParser_Initialize(struct WAVParser* parser, FILE* fp) +{ + parser->fp = fp; + memset(&parser->buffer, 0, sizeof(struct WAVBitBuffer)); + parser->buffer.byte_pos = -1; +} + +/* パーサの使用終了 */ +static void WAVParser_Finalize(struct WAVParser* parser) +{ + parser->fp = NULL; + memset(&parser->buffer, 0, sizeof(struct WAVBitBuffer)); + parser->buffer.byte_pos = -1; +} + +/* n_bit 取得し、結果を右詰めする */ +static WAVError WAVParser_GetBits(struct WAVParser* parser, uint32_t n_bits, uint64_t* bitsbuf) +{ + uint64_t tmp; + struct WAVBitBuffer *buf = &(parser->buffer); + + /* 引数チェック */ + if (parser == NULL || bitsbuf == NULL || n_bits > 64) { + return WAV_ERROR_INVALID_PARAMETER; + } + + /* 初回読み込み */ + if (buf->byte_pos == -1) { + if (fread(buf->bytes, sizeof(uint8_t), WAVBITBUFFER_BUFFER_SIZE, parser->fp) == 0) { + return WAV_ERROR_IO; + } + buf->byte_pos = 0; + buf->bit_count = 8; + } + + /* 最上位ビットからデータを埋めていく + * 初回ループではtmpの上位ビットにセット + * 2回目以降は8bit単位で入力しtmpにセット */ + tmp = 0; + while (n_bits > buf->bit_count) { + /* 上位bitから埋めていく */ + n_bits -= buf->bit_count; + tmp |= (uint64_t)WAV_GetLowerBits(buf->bit_count, buf->bytes[buf->byte_pos]) << n_bits; + + /* 1バイト読み進める */ + buf->byte_pos++; + buf->bit_count = 8; + + /* バッファが一杯ならば、再度読み込み */ + if (buf->byte_pos == WAVBITBUFFER_BUFFER_SIZE) { + if (fread(buf->bytes, sizeof(uint8_t), WAVBITBUFFER_BUFFER_SIZE, parser->fp) == 0) { + return WAV_ERROR_IO; + } + buf->byte_pos = 0; + } + } + + /* 端数ビットの処理 + * 残ったビット分をtmpの最上位ビットにセット */ + buf->bit_count -= n_bits; + tmp |= (uint64_t)WAV_GetLowerBits(n_bits, (uint32_t)(buf->bytes[buf->byte_pos] >> buf->bit_count)); + + *bitsbuf = tmp; + return WAV_ERROR_OK; +} + +/* シーク(fseek準拠) */ +static WAVError WAVParser_Seek(struct WAVParser* parser, int32_t offset, int32_t wherefrom) +{ + if (parser->buffer.byte_pos != -1) { + /* バッファに取り込んだ分先読みしているので戻す */ + offset -= (WAVBITBUFFER_BUFFER_SIZE - (parser->buffer.byte_pos + 1)); + } + /* 移動 */ + fseek(parser->fp, offset, wherefrom); + /* バッファをクリア */ + parser->buffer.byte_pos = -1; + + return WAV_ERROR_OK; +} + +/* WAVファイルハンドルを破棄 */ +void WAV_Destroy(struct WAVFile* wavfile) +{ + uint32_t ch; + + /* NULLチェックして解放 */ +#define NULLCHECK_AND_FREE(ptr) { \ + if ((ptr) != NULL) { \ + free(ptr); \ + ptr = NULL; \ + } \ +} + + if (wavfile != NULL) { + for (ch = 0; ch < wavfile->format.num_channels; ch++) { + NULLCHECK_AND_FREE(wavfile->data[ch]); + } + NULLCHECK_AND_FREE(wavfile->data); + free(wavfile); + } + +#undef NULLCHECK_AND_FREE +} + +/* ライタを使用してファイルフォーマットに従ったヘッダ部を出力 */ +static WAVError WAVWriter_PutWAVHeader( + struct WAVWriter* writer, const struct WAVFileFormat* format) +{ + uint32_t filesize, pcm_data_size; + + /* 引数チェック */ + if (writer == NULL || format == NULL) { + return WAV_ERROR_INVALID_PARAMETER; + } + + /* フォーマットチェック */ + /* PCM以外は対応していない */ + if (format->data_format != WAV_DATA_FORMAT_PCM) { + return WAV_ERROR_INVALID_FORMAT; + } + + /* PCM データサイズ */ + pcm_data_size + = format->num_samples * (format->bits_per_sample / 8) * format->num_channels; + + /* ファイルサイズ */ + /* 44は"RIFF" から ("data"のサイズ) までのフィールドのバイト数(拡張部分を一切含まない) */ + filesize = pcm_data_size + 44; + + /* ヘッダ 'R', 'I', 'F', 'F' を出力 */ + if (WAVWriter_PutBits(writer, 'R', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + if (WAVWriter_PutBits(writer, 'I', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + if (WAVWriter_PutBits(writer, 'F', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + if (WAVWriter_PutBits(writer, 'F', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + + /* ファイルサイズ-8(この要素以降のサイズ) */ + if (WAVWriter_PutLittleEndianBytes(writer, 4, filesize - 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; } + + /* ヘッダ 'W', 'A', 'V', 'E' を出力 */ + if (WAVWriter_PutBits(writer, 'W', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + if (WAVWriter_PutBits(writer, 'A', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + if (WAVWriter_PutBits(writer, 'V', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + if (WAVWriter_PutBits(writer, 'E', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + + /* fmtチャンクのヘッダ 'f', 'm', 't', ' ' を出力 */ + if (WAVWriter_PutBits(writer, 'f', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + if (WAVWriter_PutBits(writer, 'm', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + if (WAVWriter_PutBits(writer, 't', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + if (WAVWriter_PutBits(writer, ' ', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + + /* fmtチャンクのバイト数を出力 (補足)現在は16byte決め打ち */ + if (WAVWriter_PutLittleEndianBytes(writer, 4, 16) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + + /* フォーマットIDを出力 (補足)現在は1(リニアPCM)決め打ち */ + if (WAVWriter_PutLittleEndianBytes(writer, 2, 1) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + + /* チャンネル数 */ + if (WAVWriter_PutLittleEndianBytes(writer, 2, format->num_channels) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + + /* サンプリングレート */ + if (WAVWriter_PutLittleEndianBytes(writer, 4, format->sampling_rate) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + + /* データ速度(byte/sec) */ + if (WAVWriter_PutLittleEndianBytes(writer, 4, + format->sampling_rate * (format->bits_per_sample / 8) * format->num_channels) + != WAV_ERROR_OK) { return WAV_ERROR_IO; } + + /* ブロックあたりサイズ数 */ + if (WAVWriter_PutLittleEndianBytes(writer, 2, + (format->bits_per_sample / 8) * format->num_channels) + != WAV_ERROR_OK) { return WAV_ERROR_IO; } + + /* 量子化ビット数(サンプルあたりのビット数) */ + if (WAVWriter_PutLittleEndianBytes(writer, 2, format->bits_per_sample) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + + /* "data" チャンクのヘッダ出力 */ + if (WAVWriter_PutBits(writer, 'd', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + if (WAVWriter_PutBits(writer, 'a', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + if (WAVWriter_PutBits(writer, 't', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + if (WAVWriter_PutBits(writer, 'a', 8) != WAV_ERROR_OK) { return WAV_ERROR_IO; }; + + /* 波形データバイト数 */ + if (WAVWriter_PutLittleEndianBytes(writer, 4, pcm_data_size) != WAV_ERROR_OK) { return WAV_ERROR_IO; } + + return WAV_ERROR_OK; +} + +/* リトルエンディアンで書き出し +* 注意)dataはスワップされる可能性がある */ +static size_t WAVWrite_FWriteLittleEndian( + void *data, size_t size, size_t ndata, FILE *fp) +{ + int x = 1; + uint8_t *buffer; + uint32_t i; + + /* リトルエンディアン環境ではそのままfwrite */ + if ((size == 1) || (*((char *)&x) == 1)) { + return fwrite(data, size, ndata, fp); + } + + /* ビッグエンディアン環境では並び替えてから書き込む */ + buffer = (uint8_t *)data; + + switch (size) { + case 2: + for (i = 0; i < ndata; i++) { + uint8_t a = buffer[2 * i]; + buffer[2 * i + 0] = buffer[2 * i + 1]; + buffer[2 * i + 1] = a; + } + break; + case 3: + for (i = 0; i < ndata; i++) { + uint8_t a = buffer[3 * i]; + buffer[3 * i + 0] = buffer[3 * i + 2]; + buffer[3 * i + 2] = a; + } + break; + case 4: + for (i = 0; i < ndata; i++) { + uint8_t a = buffer[4 * i]; + uint8_t b = buffer[4 * i + 1]; + buffer[4 * i + 0] = buffer[4 * i + 3]; + buffer[4 * i + 1] = buffer[4 * i + 2]; + buffer[4 * i + 2] = b; + buffer[4 * i + 3] = a; + } + break; + default: + return 0; + } + + return fwrite(data, size, ndata, fp); +} + +/* ライタを使用してPCMデータ出力 */ +static WAVError WAVWriter_PutWAVPcmData( + struct WAVWriter* writer, const struct WAVFile* wavfile) +{ + uint32_t ch, smpl, progress; + + /* バッファは空に */ + WAVWriter_Flush(writer); + + /* チャンネルインターリーブしながら書き出し */ + switch (wavfile->format.bits_per_sample) { + case 8: + { + uint8_t *buffer; + const uint32_t num_output_smpls_per_buffer = WAVBITBUFFER_BUFFER_SIZE / (sizeof(uint8_t) * wavfile->format.num_channels); + progress = 0; + while (progress < wavfile->format.num_samples) { + const uint32_t num_process_smpls = WAV_Min(num_output_smpls_per_buffer, wavfile->format.num_samples - progress); + const uint32_t num_output_smpls = num_process_smpls * wavfile->format.num_channels; + buffer = (uint8_t *)writer->buffer.bytes; + for (smpl = 0; smpl < num_process_smpls; smpl++) { + for (ch = 0; ch < wavfile->format.num_channels; ch++) { + (*buffer++) = (uint8_t)(((WAVFile_PCM(wavfile, progress + smpl, ch) >> 24) + 128) & 0xFF); + } + } + if (WAVWrite_FWriteLittleEndian(writer->buffer.bytes, + sizeof(uint8_t), num_output_smpls, writer->fp) < num_output_smpls) { + return WAV_ERROR_IO; + } + progress += num_process_smpls; + } + } + break; + case 16: + { + int16_t *buffer; + const uint32_t num_output_smpls_per_buffer = WAVBITBUFFER_BUFFER_SIZE / (sizeof(int16_t) * wavfile->format.num_channels); + progress = 0; + while (progress < wavfile->format.num_samples) { + const uint32_t num_process_smpls = WAV_Min(num_output_smpls_per_buffer, wavfile->format.num_samples - progress); + const uint32_t num_output_smpls = num_process_smpls * wavfile->format.num_channels; + buffer = (int16_t *)writer->buffer.bytes; + for (smpl = 0; smpl < num_process_smpls; smpl++) { + for (ch = 0; ch < wavfile->format.num_channels; ch++) { + (*buffer++) = (int16_t)((WAVFile_PCM(wavfile, progress + smpl, ch) >> 16) & 0xFFFF); + } + } + if (WAVWrite_FWriteLittleEndian(writer->buffer.bytes, + sizeof(int16_t), num_output_smpls, writer->fp) < num_output_smpls) { + return WAV_ERROR_IO; + } + progress += num_process_smpls; + } + } + break; + case 24: + { + uint8_t *buffer; + const size_t int24_size = 3 * sizeof(uint8_t); + const uint32_t num_output_smpls_per_buffer = WAVBITBUFFER_BUFFER_SIZE / (int24_size * wavfile->format.num_channels); + progress = 0; + while (progress < wavfile->format.num_samples) { + const uint32_t num_process_smpls = WAV_Min(num_output_smpls_per_buffer, wavfile->format.num_samples - progress); + const uint32_t num_output_smpls = num_process_smpls * wavfile->format.num_channels; + const size_t output_size = num_output_smpls * int24_size; + buffer = (uint8_t *)writer->buffer.bytes; + for (smpl = 0; smpl < num_process_smpls; smpl++) { + for (ch = 0; ch < wavfile->format.num_channels; ch++) { + int32_t pcm = WAVFile_PCM(wavfile, progress + smpl, ch); + (*buffer++) = (uint8_t)((pcm >> 8) & 0xFF); + (*buffer++) = (uint8_t)((pcm >> 16) & 0xFF); + (*buffer++) = (uint8_t)((pcm >> 24) & 0xFF); + } + } + if (WAVWrite_FWriteLittleEndian(writer->buffer.bytes, + sizeof(uint8_t), output_size, writer->fp) < output_size) { + return WAV_ERROR_IO; + } + progress += num_process_smpls; + } + } + break; + case 32: + { + int32_t *buffer; + const uint32_t num_output_smpls_per_buffer = WAVBITBUFFER_BUFFER_SIZE / (sizeof(int32_t) * wavfile->format.num_channels); + progress = 0; + while (progress < wavfile->format.num_samples) { + const uint32_t num_process_smpls = WAV_Min(num_output_smpls_per_buffer, wavfile->format.num_samples - progress); + const uint32_t num_output_smpls = num_process_smpls * wavfile->format.num_channels; + buffer = (int32_t *)writer->buffer.bytes; + for (smpl = 0; smpl < num_process_smpls; smpl++) { + for (ch = 0; ch < wavfile->format.num_channels; ch++) { + (*buffer++) = WAVFile_PCM(wavfile, progress + smpl, ch); + } + } + if (WAVWrite_FWriteLittleEndian(writer->buffer.bytes, + sizeof(int32_t), num_output_smpls, writer->fp) < num_output_smpls) { + return WAV_ERROR_IO; + } + progress += num_process_smpls; + } + } + break; + default: + /* fprintf(stderr, "Unsupported bits per smpl format(=%d). \n", wavfile->format.bits_per_smpl); */ + return WAV_ERROR_INVALID_FORMAT; + } + + + return WAV_ERROR_OK; +} + +/* ファイル書き出し */ +WAVApiResult WAV_WriteToFile( + const char* filename, const struct WAVFile* wavfile) +{ + struct WAVWriter writer; + FILE* fp; + + /* 引数チェック */ + if (filename == NULL || wavfile == NULL) { + return WAV_APIRESULT_INVALID_PARAMETER; + } + + /* wavファイルを開く */ + fp = fopen(filename, "wb"); + if (fp == NULL) { + /* fprintf(stderr, "Failed to open %s. \n", filename); */ + return WAV_APIRESULT_NG; + } + + /* ライタ初期化 */ + WAVWriter_Initialize(&writer, fp); + + /* ヘッダ書き出し */ + if (WAVWriter_PutWAVHeader(&writer, &wavfile->format) != WAV_ERROR_OK) { + return WAV_APIRESULT_NG; + } + + /* データ書き出し */ + if (WAVWriter_PutWAVPcmData(&writer, wavfile) != WAV_ERROR_OK) { + return WAV_APIRESULT_NG; + } + + /* ライタ終了 */ + WAVWriter_Finalize(&writer); + + /* ファイルを閉じる */ + fclose(fp); + + /* 正常終了 */ + return WAV_APIRESULT_OK; +} + +/* ライタの初期化 */ +static void WAVWriter_Initialize(struct WAVWriter* writer, FILE* fp) +{ + writer->fp = fp; + writer->bit_count = 8; + writer->bit_buffer = 0; + memset(&writer->buffer, 0, sizeof(struct WAVBitBuffer)); + writer->buffer.byte_pos = 0; +} + +/* ライタの終了 */ +static void WAVWriter_Finalize(struct WAVWriter* writer) +{ + /* バッファに余っているデータを書き出し */ + WAVWriter_Flush(writer); + + /* メンバをクリア */ + writer->fp = NULL; + writer->bit_count = 8; + writer->bit_buffer = 0; + memset(&writer->buffer, 0, sizeof(struct WAVBitBuffer)); + writer->buffer.byte_pos = 0; +} + +/* valの下位n_bitを書き込む(ビッグエンディアンで) */ +static WAVError WAVWriter_PutBits(struct WAVWriter* writer, uint64_t val, uint32_t n_bits) +{ + /* 無効な引数 */ + if (writer == NULL) { + return WAV_ERROR_INVALID_PARAMETER; + } + + /* valの上位ビットから順次出力 + * 初回ループでは端数(出力に必要なビット数)分を埋め出力 + * 2回目以降は8bit単位で出力 */ + while (n_bits >= writer->bit_count) { + n_bits -= writer->bit_count; + writer->bit_buffer |= (uint8_t)WAV_GetLowerBits(writer->bit_count, val >> n_bits); + + /* バッファに追記 */ + writer->buffer.bytes[writer->buffer.byte_pos++] = (uint8_t)(writer->bit_buffer & 0xFF); + + /* バッファが一杯になったら書き出し */ + if (writer->buffer.byte_pos == WAVBITBUFFER_BUFFER_SIZE) { + if (fwrite(writer->buffer.bytes, + sizeof(uint8_t), WAVBITBUFFER_BUFFER_SIZE, + writer->fp) < WAVBITBUFFER_BUFFER_SIZE) { + return WAV_ERROR_IO; + } + /* 書き込み位置をリセット */ + writer->buffer.byte_pos = 0; + } + + writer->bit_buffer = 0; + writer->bit_count = 8; + } + + /* 端数ビットの処理: + * 残った分をバッファの上位ビットにセット */ + writer->bit_count -= n_bits; + writer->bit_buffer |= (uint8_t)(WAV_GetLowerBits(n_bits, (uint32_t)val) << writer->bit_count); + + return WAV_ERROR_OK; +} + +/* リトルエンディアンでビットパターンを出力 */ +static WAVError WAVWriter_PutLittleEndianBytes( + struct WAVWriter* writer, uint32_t nbytes, uint64_t data) +{ + uint64_t out; + uint32_t i_byte; + + /* リトルエンディアンに並び替え */ + out = 0; + for (i_byte = 0; i_byte < nbytes; i_byte++) { + out |= ((data >> (8 * (nbytes - i_byte - 1))) & 0xFFUL) << (8 * i_byte); + } + + /* 出力 */ + if (WAVWriter_PutBits(writer, out, (uint8_t)(nbytes * 8)) != WAV_ERROR_OK) { + return WAV_ERROR_IO; + } + + return WAV_ERROR_OK; +} + +/* バッファにたまったビットをクリア */ +static WAVError WAVWriter_Flush(struct WAVWriter* writer) +{ + /* 引数チェック */ + if (writer == NULL) { + return WAV_ERROR_INVALID_PARAMETER; + } + + /* 余ったビットを強制出力 */ + if (writer->bit_count != 8) { + if (WAVWriter_PutBits(writer, 0, (uint8_t)writer->bit_count) != WAV_ERROR_OK) { + return WAV_ERROR_IO; + } + writer->bit_buffer = 0; + writer->bit_count = 8; + } + + /* バッファに残っているデータをフラッシュ */ + if (fwrite(writer->buffer.bytes, + sizeof(uint8_t), (uint32_t)writer->buffer.byte_pos, + writer->fp) < (size_t)writer->buffer.byte_pos) { + return WAV_ERROR_IO; + } + /* バッファ残量は0に */ + writer->buffer.byte_pos = 0; + + return WAV_ERROR_OK; +} + +/* リトルエンディアンでビットパターンを取得 */ +static WAVError WAVParser_GetLittleEndianBytes( + struct WAVParser* parser, uint32_t nbytes, uint64_t* bitsbuf) +{ + uint64_t tmp, ret; + uint32_t i_byte; + + /* ビッグエンディアンで取得 */ + if (WAVParser_GetBits(parser, nbytes * 8, &tmp) != WAV_ERROR_OK) { + return WAV_ERROR_IO; + } + + /* リトルエンディアンに並び替え */ + ret = 0; + for (i_byte = 0; i_byte < nbytes; i_byte++) { + ret |= ((tmp >> (8 * (nbytes - i_byte - 1))) & 0xFFUL) << (8 * i_byte); + } + *bitsbuf = ret; + + return WAV_ERROR_OK; +} + +/* パーサを使用して文字列取得 */ +static WAVError WAVParser_GetString( + struct WAVParser* parser, char* string_buffer, uint32_t string_length) +{ + uint32_t i_byte; + uint64_t bitsbuf; + + assert(parser != NULL && string_buffer != NULL); + + /* 文字列取得 */ + for (i_byte = 0; i_byte < string_length; i_byte++) { + /* 1文字取得 */ + if (WAVParser_GetBits(parser, 8, &bitsbuf) != WAV_ERROR_OK) { + return WAV_ERROR_IO; + } + string_buffer[i_byte] = (char)bitsbuf; + } + + return WAV_ERROR_OK; +} + +/* パーサを使用して文字列取得/一致チェック */ +static WAVError WAVParser_CheckSignatureString( + struct WAVParser* parser, const char* signature, uint32_t signature_length) +{ + uint32_t i_byte; + uint64_t bitsbuf; + + assert(parser != NULL && signature != NULL); + + /* 文字列取得/検査 */ + for (i_byte = 0; i_byte < signature_length; i_byte++) { + /* 1文字取得 */ + if (WAVParser_GetBits(parser, 8, &bitsbuf) != WAV_ERROR_OK) { + return WAV_ERROR_IO; + } + /* シグネチャ検査 */ + if (signature[i_byte] != (char)bitsbuf) { + /* fprintf(stderr, "Failed to check %s header signature. \n", signature); */ + return WAV_ERROR_INVALID_FORMAT; + } + } + + return WAV_ERROR_OK; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..0e985ad --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.15) + +add_subdirectory(bit_stream) +add_subdirectory(byte_array) +add_subdirectory(command_line_parser) +add_subdirectory(srla_internal) +add_subdirectory(srla_coder) +add_subdirectory(srla_encoder) +add_subdirectory(srla_decoder) +add_subdirectory(srla_encode_decode) +add_subdirectory(lpc) +add_subdirectory(wav) diff --git a/test/bit_stream/CMakeLists.txt b/test/bit_stream/CMakeLists.txt new file mode 100644 index 0000000..eff9884 --- /dev/null +++ b/test/bit_stream/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# テスト名 +set(TEST_NAME bit_stream_test) + +# 実行形式ファイル +add_executable(${TEST_NAME} main.cpp bit_stream_macro_test.cpp bit_stream_function_test.cpp) + +# インクルードディレクトリ +include_directories(${PROJECT_ROOT_PATH}/libs/bit_stream/include) + +# リンクするライブラリ +target_link_libraries(${TEST_NAME} gtest gtest_main) +if (NOT MSVC) +target_link_libraries(${TEST_NAME} pthread) +endif() + +# コンパイルオプション +set_target_properties(${TEST_NAME} + PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) + +add_test( + NAME bit_stream + COMMAND $ + ) + +# run with: ctest -L lib +set_property( + TEST bit_stream + PROPERTY LABELS lib bit_stream + ) diff --git a/test/bit_stream/bit_stream_common_test.cpp b/test/bit_stream/bit_stream_common_test.cpp new file mode 100644 index 0000000..a698627 --- /dev/null +++ b/test/bit_stream/bit_stream_common_test.cpp @@ -0,0 +1,228 @@ +#include +#include + +#include + +/* インスタンス作成破棄テスト */ +TEST(BitStreamTest, CreateDestroyTest) +{ + /* インスタンス作成・破棄 */ + { + struct BitStream strm; + uint8_t test_memory[] = {'A', 'I', 'K', 'A', 'T', 'S', 'U'}; + const uint32_t test_memory_size = sizeof(test_memory) / sizeof(test_memory[0]); + + /* 書きモードでインスタンス作成 */ + BitWriter_Open(&strm, test_memory, test_memory_size); + EXPECT_TRUE(strm.memory_image == test_memory); + EXPECT_EQ(test_memory_size, strm.memory_size); + EXPECT_TRUE(strm.memory_p == test_memory); + EXPECT_EQ(0, strm.bit_buffer); + EXPECT_EQ(32, strm.bit_count); + EXPECT_TRUE(!(strm.flags & BITSTREAM_FLAGS_MODE_READ)); + BitStream_Close(&strm); + + /* 読みモードでインスタンス作成 */ + BitReader_Open(&strm, test_memory, test_memory_size); + EXPECT_TRUE(strm.memory_image == test_memory); + EXPECT_EQ(test_memory_size, strm.memory_size); + EXPECT_TRUE(strm.memory_p == test_memory); + EXPECT_EQ(0, strm.bit_buffer); + EXPECT_EQ(0, strm.bit_count); + EXPECT_TRUE(strm.flags & BITSTREAM_FLAGS_MODE_READ); + BitStream_Close(&strm); + } +} + +/* PutBit関数テスト */ +TEST(BitStreamTest, PutGetTest) +{ + { + struct BitStream strm; + uint8_t bit_pattern[] = { 1, 1, 1, 1, 0, 0, 0, 0 }; + uint8_t memory_image[256]; + uint32_t bit_pattern_length = sizeof(bit_pattern) / sizeof(bit_pattern[0]); + uint32_t i, is_ok; + + /* 書き込んでみる */ + BitWriter_Open(&strm, memory_image, sizeof(memory_image)); + for (i = 0; i < bit_pattern_length; i++) { + BitWriter_PutBits(&strm, bit_pattern[i], 1); + } + BitStream_Close(&strm); + + /* 正しく書き込めているか? */ + BitReader_Open(&strm, memory_image, sizeof(memory_image)); + is_ok = 1; + for (i = 0; i < bit_pattern_length; i++) { + uint32_t buf; + BitReader_GetBits(&strm, &buf, 1); + if ((uint8_t)buf != bit_pattern[i]) { + is_ok = 0; + break; + } + } + EXPECT_EQ(1, is_ok); + BitStream_Close(&strm); + } + + /* PutBit関数テスト2 8bitパターンチェック */ + { + struct BitStream strm; + uint8_t memory_image[256]; + uint32_t i, is_ok, nbits; + + for (nbits = 1; nbits <= 8; nbits++) { + /* 書き込んでみる */ + BitWriter_Open(&strm, memory_image, sizeof(memory_image)); + for (i = 0; i < (1 << nbits); i++) { + BitWriter_PutBits(&strm, i, nbits); + } + BitStream_Close(&strm); + + /* 正しく書き込めているか? */ + BitReader_Open(&strm, memory_image, sizeof(memory_image)); + is_ok = 1; + for (i = 0; i < (1 << nbits); i++) { + uint32_t buf; + BitReader_GetBits(&strm, &buf, nbits); + if (buf != i) { + is_ok = 0; + break; + } + } + EXPECT_EQ(1, is_ok); + BitStream_Close(&strm); + } + + } + + /* Flushテスト */ + { + struct BitStream strm; + uint8_t memory_image[256] = { 0, }; + uint32_t bits; + + BitWriter_Open(&strm, memory_image, sizeof(memory_image)); + BitWriter_PutBits(&strm, 1, 1); + BitWriter_PutBits(&strm, 1, 1); + /* 2bitしか書いていないがフラッシュ */ + BitStream_Flush(&strm); + EXPECT_EQ(0, strm.bit_buffer); + EXPECT_EQ(32, strm.bit_count); + BitStream_Close(&strm); + + /* 1バイトで先頭2bitだけが立っているはず */ + BitReader_Open(&strm, memory_image, sizeof(memory_image)); + BitReader_GetBits(&strm, &bits, 8); + EXPECT_EQ(0xC0, bits); + EXPECT_EQ(24, strm.bit_count); + EXPECT_EQ(0xC0000000, strm.bit_buffer); + EXPECT_EQ(&memory_image[4], strm.memory_p); + BitStream_Flush(&strm); + EXPECT_EQ(0, strm.bit_count); + EXPECT_EQ(0, strm.bit_buffer); + EXPECT_EQ(&memory_image[1], strm.memory_p); + BitStream_Close(&strm); + } + +} + +/* seek, tellなどのストリーム操作系APIテスト */ +TEST(BitStreamTest, StreamOperationTest) +{ + /* Seek/Tellテスト */ + { + struct BitStream strm; + int32_t tell_result; + uint8_t test_memory[8]; + + /* テスト用に適当にデータ作成 */ + BitWriter_Open(&strm, test_memory, sizeof(test_memory)); + BitWriter_PutBits(&strm, 0xDEADBEAF, 32); + BitWriter_PutBits(&strm, 0xABADCAFE, 32); + BitStream_Tell(&strm, &tell_result); + EXPECT_EQ(8, tell_result); + BitStream_Close(&strm); + + /* ビットリーダを使ったseek & tellテスト */ + BitReader_Open(&strm, test_memory, sizeof(test_memory)); + BitStream_Seek(&strm, 0, BITSTREAM_SEEK_SET); + BitStream_Tell(&strm, &tell_result); + EXPECT_EQ(0, tell_result); + BitStream_Seek(&strm, 1, BITSTREAM_SEEK_CUR); + BitStream_Tell(&strm, &tell_result); + EXPECT_EQ(1, tell_result); + BitStream_Seek(&strm, 2, BITSTREAM_SEEK_CUR); + BitStream_Tell(&strm, &tell_result); + EXPECT_EQ(3, tell_result); + BitStream_Seek(&strm, 0, BITSTREAM_SEEK_END); + BitStream_Tell(&strm, &tell_result); + EXPECT_EQ(7, tell_result); + BitStream_Close(&strm); + + /* ビットライタを使ったseek & tellテスト */ + BitWriter_Open(&strm, test_memory, sizeof(test_memory)); + BitStream_Seek(&strm, 0, BITSTREAM_SEEK_SET); + BitStream_Tell(&strm, &tell_result); + EXPECT_EQ(0, tell_result); + BitStream_Seek(&strm, 1, BITSTREAM_SEEK_CUR); + BitStream_Tell(&strm, &tell_result); + EXPECT_EQ(1, tell_result); + BitStream_Seek(&strm, 2, BITSTREAM_SEEK_CUR); + BitStream_Tell(&strm, &tell_result); + EXPECT_EQ(3, tell_result); + BitStream_Seek(&strm, 0, BITSTREAM_SEEK_END); + BitStream_Tell(&strm, &tell_result); + EXPECT_EQ(7, tell_result); + BitStream_Close(&strm); + } +} + +/* ランレングス取得テスト */ +TEST(BitStreamTest, GetZeroRunLengthTest) +{ + { + struct BitStream strm; + uint8_t data[256] = { 0, }; + uint32_t test_length, run; + + for (test_length = 0; test_length <= 65; test_length++) { + /* ラン長だけ0を書き込み、1で止める */ + BitWriter_Open(&strm, data, sizeof(data)); + for (run = 0; run < test_length; run++) { + BitWriter_PutBits(&strm, 0, 1); + } + BitWriter_PutBits(&strm, 1, 1); + BitStream_Close(&strm); + + BitReader_Open(&strm, data, sizeof(data)); + BitReader_GetZeroRunLength(&strm, &run); + EXPECT_EQ(test_length, run); + } + + /* ラン長出力APIを使用 */ + for (test_length = 0; test_length <= 65; test_length++) { + BitWriter_Open(&strm, data, sizeof(data)); + BitWriter_PutZeroRun(&strm, test_length); + BitStream_Close(&strm); + + BitReader_Open(&strm, data, sizeof(data)); + BitReader_GetZeroRunLength(&strm, &run); + EXPECT_EQ(test_length, run); + } + + /* 連続したラン */ + BitWriter_Open(&strm, data, sizeof(data)); + for (test_length = 0; test_length <= 32; test_length++) { + BitWriter_PutZeroRun(&strm, test_length); + } + BitStream_Close(&strm); + BitReader_Open(&strm, data, sizeof(data)); + for (test_length = 0; test_length <= 32; test_length++) { + BitReader_GetZeroRunLength(&strm, &run); + EXPECT_EQ(test_length, run); + } + BitStream_Close(&strm); + } +} diff --git a/test/bit_stream/bit_stream_function_test.cpp b/test/bit_stream/bit_stream_function_test.cpp new file mode 100644 index 0000000..9bfd9a8 --- /dev/null +++ b/test/bit_stream/bit_stream_function_test.cpp @@ -0,0 +1,44 @@ +#include "bit_stream.h" + +/* マクロ定義を削除 */ +#undef BitReader_Open +#undef BitWriter_Open +#undef BitStream_Close +#undef BitStream_Seek +#undef BitStream_Tell +#undef BitWriter_PutBits +#undef BitWriter_PutZeroRun +#undef BitReader_GetBits +#undef BitReader_GetZeroRunLength +#undef BitStream_Flush + +/* マクロの代わりに関数宣言 */ +extern "C" { +void BitReader_Open(struct BitStream *stream, const uint8_t *memory, size_t size); +void BitWriter_Open(struct BitStream *stream, const uint8_t *memory, size_t size); +void BitStream_Close(struct BitStream *stream); +void BitStream_Seek(struct BitStream *stream, int32_t offset, int32_t origin); +void BitStream_Tell(struct BitStream *stream, int32_t *result); +void BitWriter_PutBits(struct BitStream *stream, uint32_t val, uint32_t nbits); +void BitWriter_PutZeroRun(struct BitStream *stream, uint32_t runlength); +void BitReader_GetBits(struct BitStream *stream, uint32_t *val, uint32_t nbits); +void BitReader_GetZeroRunLength(struct BitStream *stream, uint32_t *runlength); +void BitStream_Flush(struct BitStream *stream); +} + +/* 多重定義防止 */ +#define BitStream_NLZSoft BitStream_NLZSoftTestDummy +#define g_bitstream_lower_bits_mask g_bitstream_lower_bits_mask_test_dummy +#define g_bitstream_zerobit_runlength_table g_bitstream_zerobit_runlength_table_test_dummy + +/* テスト対象のモジュール */ +extern "C" { +/* 関数定義を使用 */ +#undef BITSTREAM_USE_MACROS +#include "../../libs/bit_stream/src/bit_stream.c" +} + +/* マクロと同じテストソースを使用 */ +#define BitStreamTest BitStreamFunctionTest +#include "bit_stream_common_test.cpp" +#undef BitStreamTest diff --git a/test/bit_stream/bit_stream_macro_test.cpp b/test/bit_stream/bit_stream_macro_test.cpp new file mode 100644 index 0000000..d38ce46 --- /dev/null +++ b/test/bit_stream/bit_stream_macro_test.cpp @@ -0,0 +1,6 @@ +/* テスト対象のモジュール */ +extern "C" { +#include "../../libs/bit_stream/src/bit_stream.c" +} + +#include "bit_stream_common_test.cpp" diff --git a/test/bit_stream/main.cpp b/test/bit_stream/main.cpp new file mode 100644 index 0000000..96d7200 --- /dev/null +++ b/test/bit_stream/main.cpp @@ -0,0 +1,7 @@ +#include + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/byte_array/CMakeLists.txt b/test/byte_array/CMakeLists.txt new file mode 100644 index 0000000..8029e86 --- /dev/null +++ b/test/byte_array/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# テスト名 +set(TEST_NAME byte_array_test) + +# 実行形式ファイル +add_executable(${TEST_NAME} main.cpp) + +# インクルードディレクトリ +include_directories(${PROJECT_ROOT_PATH}/libs/byte_array/include) + +# リンクするライブラリ +target_link_libraries(${TEST_NAME} gtest gtest_main) +if (NOT MSVC) +target_link_libraries(${TEST_NAME} pthread) +endif() + +# コンパイルオプション +set_target_properties(${TEST_NAME} + PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) + +add_test( + NAME byte_array + COMMAND $ + ) + +# run with: ctest -L lib +set_property( + TEST byte_array + PROPERTY LABELS lib byte_array + ) diff --git a/test/byte_array/main.cpp b/test/byte_array/main.cpp new file mode 100644 index 0000000..0207c5e --- /dev/null +++ b/test/byte_array/main.cpp @@ -0,0 +1,360 @@ +#include +#include + +#include + +/* テスト対象のモジュール */ +extern "C" { +#include "byte_array.h" +} + +/* 読み書きテスト */ +TEST(ByteArrayTest, ReadWriteTest) +{ +#define TEST_SIZE (16 * 1024) + + /* 1バイト読み/書き */ + { + uint8_t *pos; + uint8_t array[TEST_SIZE], answer[TEST_SIZE]; + uint32_t i; + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE; i++) { + answer[i] = (uint8_t)i; + ByteArray_WriteUint8(pos, (uint8_t)i); + pos += 1; + } + + /* リファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(array, answer, sizeof(uint8_t) * TEST_SIZE)); + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE; i++) { + array[i] = ByteArray_ReadUint8(pos); + pos += 1; + } + + /* リファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(array, answer, sizeof(uint8_t) * TEST_SIZE)); + } + /* 同じことをGet/Putでやる */ + { + uint8_t *pos; + uint8_t array[TEST_SIZE], answer[TEST_SIZE]; + uint32_t i; + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE; i++) { + answer[i] = (uint8_t)i; + ByteArray_PutUint8(pos, (uint8_t)i); + } + + /* リファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(array, answer, sizeof(uint8_t) * TEST_SIZE)); + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE; i++) { + ByteArray_GetUint8(pos, &array[i]); + } + + /* リファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(array, answer, sizeof(uint8_t) * TEST_SIZE)); + } + + /* 2バイト読み/書き */ + { +#define TEST_SIZE_UINT16 (TEST_SIZE / sizeof(uint16_t)) + uint8_t *pos; + uint8_t array[TEST_SIZE]; + uint16_t test[TEST_SIZE_UINT16], answer[TEST_SIZE_UINT16]; + uint32_t i; + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT16; i++) { + answer[i] = (uint16_t)i; + ByteArray_WriteUint16LE(pos, (uint16_t)i); + pos += 2; + } + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT16; i++) { + test[i] = ByteArray_ReadUint16LE(pos); + pos += 2; + } + + /* 読み出した結果がリファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(test, answer, sizeof(uint8_t) * TEST_SIZE)); + + /* ビッグエンディアンでも */ + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT16; i++) { + answer[i] = (uint16_t)i; + ByteArray_WriteUint16BE(pos, (uint16_t)i); + pos += 2; + } + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT16; i++) { + test[i] = ByteArray_ReadUint16BE(pos); + pos += 2; + } + + /* 読み出した結果がリファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(test, answer, sizeof(uint8_t) * TEST_SIZE)); + +#undef TEST_SIZE_UINT16 + } + /* 同じことをGet/Putでやる */ + { +#define TEST_SIZE_UINT16 (TEST_SIZE / sizeof(uint16_t)) + uint8_t *pos; + uint8_t array[TEST_SIZE]; + uint16_t test[TEST_SIZE_UINT16], answer[TEST_SIZE_UINT16]; + uint32_t i; + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT16; i++) { + answer[i] = (uint16_t)i; + ByteArray_PutUint16LE(pos, (uint16_t)i); + } + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT16; i++) { + ByteArray_GetUint16LE(pos, &test[i]); + } + + /* 読み出した結果がリファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(test, answer, sizeof(uint8_t) * TEST_SIZE)); + + /* ビッグエンディアンでも */ + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT16; i++) { + answer[i] = (uint16_t)i; + ByteArray_PutUint16BE(pos, (uint16_t)i); + } + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT16; i++) { + ByteArray_GetUint16BE(pos, &test[i]); + } + + /* 読み出した結果がリファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(test, answer, sizeof(uint8_t) * TEST_SIZE)); + +#undef TEST_SIZE_UINT16 + } + + /* 3バイト読み/書き */ + { +#define TEST_SIZE_FOR24 1021 +#define TEST_SIZE_UINT24 ((TEST_SIZE_FOR24 * 4) / (sizeof(uint32_t) * 3)) + uint8_t *pos; + uint8_t array[TEST_SIZE_FOR24]; + uint32_t test[TEST_SIZE_UINT24], answer[TEST_SIZE_UINT24]; + uint32_t i; + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT24; i++) { + answer[i] = (uint32_t)i; + ByteArray_WriteUint24LE(pos, (uint32_t)i); + pos += 3; + } + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT24; i++) { + test[i] = ByteArray_ReadUint24LE(pos); + pos += 3; + } + + /* 読み出した結果がリファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(test, answer, sizeof(uint8_t) * TEST_SIZE_FOR24)); + + /* ビッグエンディアンでも */ + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT24; i++) { + answer[i] = (uint32_t)i; + ByteArray_WriteUint24BE(pos, (uint32_t)i); + pos += 3; + } + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT24; i++) { + test[i] = ByteArray_ReadUint24BE(pos); + pos += 3; + } + + /* 読み出した結果がリファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(test, answer, sizeof(uint8_t) * TEST_SIZE_FOR24)); + +#undef TEST_SIZE_UINT24 +#undef TEST_SIZE_FOR24 + } + /* 同じことをGet/Putでやる */ + { +#define TEST_SIZE_FOR24 1021 +#define TEST_SIZE_UINT24 ((TEST_SIZE_FOR24 * 4) / (sizeof(uint32_t) * 3)) + uint8_t *pos; + uint8_t array[TEST_SIZE]; + uint32_t test[TEST_SIZE_UINT24], answer[TEST_SIZE_UINT24]; + uint32_t i; + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT24; i++) { + answer[i] = (uint32_t)i; + ByteArray_PutUint24LE(pos, (uint32_t)i); + } + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT24; i++) { + ByteArray_GetUint24LE(pos, &test[i]); + } + + /* 読み出した結果がリファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(test, answer, sizeof(uint8_t) * TEST_SIZE_FOR24)); + + /* ビッグエンディアンでも */ + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT24; i++) { + answer[i] = (uint32_t)i; + ByteArray_PutUint24BE(pos, (uint32_t)i); + } + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT24; i++) { + ByteArray_GetUint24BE(pos, &test[i]); + } + + /* 読み出した結果がリファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(test, answer, sizeof(uint8_t) * TEST_SIZE_FOR24)); + +#undef TEST_SIZE_UINT24 +#undef TEST_SIZE_FOR24 + } + + /* 4バイト読み/書き */ + { +#define TEST_SIZE_UINT32 (TEST_SIZE / sizeof(uint32_t)) + uint8_t *pos; + uint8_t array[TEST_SIZE]; + uint32_t test[TEST_SIZE_UINT32], answer[TEST_SIZE_UINT32]; + uint32_t i; + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT32; i++) { + answer[i] = (uint32_t)i; + ByteArray_WriteUint32LE(pos, (uint32_t)i); + pos += 4; + } + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT32; i++) { + test[i] = ByteArray_ReadUint32LE(pos); + pos += 4; + } + + /* 読み出した結果がリファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(test, answer, sizeof(uint8_t) * TEST_SIZE)); + + /* ビッグエンディアンでも */ + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT32; i++) { + answer[i] = (uint32_t)i; + ByteArray_WriteUint32BE(pos, (uint32_t)i); + pos += 4; + } + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT32; i++) { + test[i] = ByteArray_ReadUint32BE(pos); + pos += 4; + } + + /* 読み出した結果がリファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(test, answer, sizeof(uint8_t) * TEST_SIZE)); + +#undef TEST_SIZE_UINT32 + } + + /* 同じことをGet/Putでやる */ + { +#define TEST_SIZE_UINT32 (TEST_SIZE / sizeof(uint32_t)) + uint8_t *pos; + uint8_t array[TEST_SIZE]; + uint32_t test[TEST_SIZE_UINT32], answer[TEST_SIZE_UINT32]; + uint32_t i; + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT32; i++) { + answer[i] = (uint32_t)i; + ByteArray_PutUint32LE(pos, (uint32_t)i); + } + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT32; i++) { + ByteArray_GetUint32LE(pos, &test[i]); + } + + /* 読み出した結果がリファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(test, answer, sizeof(uint8_t) * TEST_SIZE)); + + /* ビッグエンディアンでもやる */ + + /* 書き出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT32; i++) { + answer[i] = (uint32_t)i; + ByteArray_PutUint32BE(pos, (uint32_t)i); + } + + /* 読み出し */ + pos = array; + for (i = 0; i < TEST_SIZE_UINT32; i++) { + ByteArray_GetUint32BE(pos, &test[i]); + } + + /* 読み出した結果がリファレンスと一致するか? */ + EXPECT_EQ(0, memcmp(test, answer, sizeof(uint8_t) * TEST_SIZE)); + +#undef TEST_SIZE_UINT16 + } + +#undef TEST_SIZE +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/command_line_parser/CMakeLists.txt b/test/command_line_parser/CMakeLists.txt new file mode 100644 index 0000000..2fac1c6 --- /dev/null +++ b/test/command_line_parser/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# テスト名 +set(TEST_NAME command_line_parser_test) + +# 実行形式ファイル +add_executable(${TEST_NAME} main.cpp) + +# インクルードディレクトリ +include_directories(${PROJECT_ROOT_PATH}/libs/command_line_parser/include) + +# リンクするライブラリ +target_link_libraries(${TEST_NAME} gtest gtest_main) +if (NOT MSVC) +target_link_libraries(${TEST_NAME} pthread) +endif() + +# コンパイルオプション +set_target_properties(${TEST_NAME} + PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) + +add_test( + NAME command_line_parser + COMMAND $ + ) + +# run with: ctest -L lib +set_property( + TEST command_line_parser + PROPERTY LABELS lib command_line_parser + ) diff --git a/test/command_line_parser/main.cpp b/test/command_line_parser/main.cpp new file mode 100644 index 0000000..43a4c8f --- /dev/null +++ b/test/command_line_parser/main.cpp @@ -0,0 +1,587 @@ +#include +#include + +#include + +/* テスト対象のモジュール */ +extern "C" { +#include "../../libs/command_line_parser/src/command_line_parser.c" +} + +/* ショートオプションの取得テスト */ +TEST(CommandLineParserTest, GetShortOptionTest) +{ + + /* 簡単な成功例 */ + { +#define INPUT_FILE_NAME "inputfile" + static const struct CommandLineParserSpecification specs[] = { + { 'i', NULL, "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'p', NULL, "output file", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + struct CommandLineParserSpecification get_specs[sizeof(specs) / sizeof(specs[0])]; + const char* test_argv1[] = { "progname", "-i", INPUT_FILE_NAME, "-p" }; + const char* test_argv2[] = { "progname", "-p", "-i", INPUT_FILE_NAME }; + const char* test_argv3[] = { "progname", "-pi", INPUT_FILE_NAME }; + + /* パースしてみる */ + memcpy(get_specs, specs, sizeof(get_specs)); + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_OK, + CommandLineParser_ParseArguments( + get_specs, + sizeof(test_argv1) / sizeof(test_argv1[0]), test_argv1, + NULL, 0)); + + /* 正しく取得できたかチェック */ + EXPECT_EQ(COMMAND_LINE_PARSER_TRUE, get_specs[0].acquired); + EXPECT_TRUE(get_specs[0].argument_string != NULL); + if (get_specs[0].argument_string != NULL) { + EXPECT_EQ(strcmp(INPUT_FILE_NAME, get_specs[0].argument_string), 0); + } + EXPECT_EQ(COMMAND_LINE_PARSER_TRUE, get_specs[1].acquired); + + /* 引数順番を変えたものをパースしてみる */ + memcpy(get_specs, specs, sizeof(get_specs)); + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_OK, + CommandLineParser_ParseArguments( + get_specs, + sizeof(test_argv2) / sizeof(test_argv2[0]), test_argv2, + NULL, 0)); + + /* 正しく取得できたかチェック */ + EXPECT_EQ(COMMAND_LINE_PARSER_TRUE, get_specs[0].acquired); + EXPECT_TRUE(get_specs[0].argument_string != NULL); + if (get_specs[0].argument_string != NULL) { + EXPECT_EQ(0, strcmp(get_specs[0].argument_string, INPUT_FILE_NAME)); + } + EXPECT_EQ(COMMAND_LINE_PARSER_TRUE, get_specs[1].acquired); + + /* ショートオプションの連なりを含むものをパースしてみる */ + memcpy(get_specs, specs, sizeof(get_specs)); + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_OK, + CommandLineParser_ParseArguments( + get_specs, + sizeof(test_argv3) / sizeof(test_argv3[0]), test_argv3, + NULL, 0)); + + /* 正しく取得できたかチェック */ + EXPECT_EQ(COMMAND_LINE_PARSER_TRUE, get_specs[0].acquired); + EXPECT_TRUE(get_specs[0].argument_string != NULL); + if (get_specs[0].argument_string != NULL) { + EXPECT_EQ(0, strcmp(get_specs[0].argument_string, INPUT_FILE_NAME)); + } + EXPECT_EQ(COMMAND_LINE_PARSER_TRUE, get_specs[1].acquired); +#undef INPUT_FILE_NAME + } + + /* 失敗系 */ + + /* 引数が指定されずに末尾に達した */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', NULL, "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "-i" }; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_NOT_SPECIFY_ARGUMENT_TO_OPTION, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0)); + } + + /* 引数に他のオプションが指定されている */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', NULL, "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv1[] = { "progname", "-i", "-p" }; + const char* test_argv2[] = { "progname", "-i", "--pripara" }; + + EXPECT_EQ( + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv1) / sizeof(test_argv1[0]), test_argv1, + NULL, 0), + COMMAND_LINE_PARSER_RESULT_NOT_SPECIFY_ARGUMENT_TO_OPTION); + + EXPECT_EQ( + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv2) / sizeof(test_argv2[0]), test_argv2, + NULL, 0), + COMMAND_LINE_PARSER_RESULT_NOT_SPECIFY_ARGUMENT_TO_OPTION); + } + + /* 仕様にないオプションが指定された */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', NULL, "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'p', NULL, "output file", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "-i", "kiriya aoi", "-p", "-s" }; + + EXPECT_EQ( + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0), + COMMAND_LINE_PARSER_RESULT_UNKNOWN_OPTION); + } + + /* 同じオプションが複数回指定されている ケース1 */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', NULL, "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "-i", "kiriya aoi", "-i", "shibuki ran" }; + + EXPECT_EQ( + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0), + COMMAND_LINE_PARSER_RESULT_OPTION_MULTIPLY_SPECIFIED); + } + + /* 同じオプションが複数回指定されている ケース2 */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', NULL, "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'p', NULL, "aikatsu", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "-p", "-i", "kiriya aoi", "-p" }; + + EXPECT_EQ( + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0), + COMMAND_LINE_PARSER_RESULT_OPTION_MULTIPLY_SPECIFIED); + } + + /* ショートオプションの使い方が正しくない パート1 */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', NULL, "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'p', NULL, "aikatsu", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "-ip", "filename" }; + + EXPECT_EQ( + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0), + COMMAND_LINE_PARSER_RESULT_INVAILD_SHORT_OPTION_ARGUMENT); + } + + /* ショートオプションの使い方が正しくない パート2 */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', NULL, "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'p', NULL, "RL", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "-ip", "filename" }; + + EXPECT_EQ( + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0), + COMMAND_LINE_PARSER_RESULT_INVAILD_SHORT_OPTION_ARGUMENT); + } + +} + +/* ロングオプションの取得テスト */ +TEST(CommandLineParserTest, GetLongOptionTest) +{ + + /* 簡単な成功例 */ + { +#define INPUT_FILE_NAME "inputfile" + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'a', "aikatsu", "aikatsu dakega boku no shinri datta...", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "--input", INPUT_FILE_NAME, "--aikatsu" }; + + /* パースしてみる */ + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_OK, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0)); + + /* 正しく取得できたかチェック */ + EXPECT_EQ(COMMAND_LINE_PARSER_TRUE, specs[0].acquired); + EXPECT_TRUE(specs[0].argument_string != NULL); + if (specs[0].argument_string != NULL) { + EXPECT_EQ(0, strcmp(specs[0].argument_string, INPUT_FILE_NAME)); + } + EXPECT_EQ(COMMAND_LINE_PARSER_TRUE, specs[1].acquired); + +#undef INPUT_FILE_NAME + } + + /* 簡単な成功例 パート2 */ + { +#define INPUT_FILE_NAME "inputfile" + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'a', "aikatsu", "aikatsu dakega boku no shinri datta...", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "--input=" INPUT_FILE_NAME, "--aikatsu" }; + + /* パースしてみる */ + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_OK, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0)); + + /* 正しく取得できたかチェック */ + EXPECT_EQ(COMMAND_LINE_PARSER_TRUE, specs[0].acquired); + EXPECT_TRUE(specs[0].argument_string != NULL); + if (specs[0].argument_string != NULL) { + EXPECT_EQ(0, strcmp(specs[0].argument_string, INPUT_FILE_NAME)); + } + EXPECT_EQ(COMMAND_LINE_PARSER_TRUE, specs[1].acquired); + +#undef INPUT_FILE_NAME + } + + /* 失敗系 */ + + /* 引数が指定されずに末尾に達した */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "--input" }; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_NOT_SPECIFY_ARGUMENT_TO_OPTION, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0)); + } + + /* 引数に他のオプションが指定されている */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv1[] = { "progname", "--input", "-a" }; + const char* test_argv2[] = { "progname", "--input", "--aikatsu" }; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_NOT_SPECIFY_ARGUMENT_TO_OPTION, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv1) / sizeof(test_argv1[0]), test_argv1, + NULL, 0)); + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_NOT_SPECIFY_ARGUMENT_TO_OPTION, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv2) / sizeof(test_argv2[0]), test_argv2, + NULL, 0)); + } + + /* 仕様にないオプションが指定された */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'p', "aikatsu", "aikatsu mode", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "--input", "kiriya aoi", "--aikatsu", "--unknown" }; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_UNKNOWN_OPTION, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0)); + } + + /* 同じオプションが複数回指定されている ケース1 */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "--input", "kiriya aoi", "--input", "shibuki ran" }; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_OPTION_MULTIPLY_SPECIFIED, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0)); + } + + /* 同じオプションが複数回指定されている ケース2 */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "--input=kiriya aoi", "--input=shibuki ran" }; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_OPTION_MULTIPLY_SPECIFIED, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0)); + } + + /* 同じオプションが複数回指定されている ケース3 */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "--input=kiriya aoi", "--input", "shibuki ran" }; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_OPTION_MULTIPLY_SPECIFIED, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0)); + } +} + +/* 他文字列オプションの取得テスト */ +TEST(CommandLineParserTest, GetOtherStringTest) +{ + + /* 簡単な成功例 */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "Ichgo Hoshimiya", "Aoi Kiriya", "Ran Shibuki" }; + const char* other_string_array[3]; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_OK, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + other_string_array, sizeof(other_string_array) / sizeof(other_string_array[0]))); + + /* 順番含め取れたか確認 */ + EXPECT_EQ(0, strcmp(other_string_array[0], test_argv[1])); + EXPECT_EQ(0, strcmp(other_string_array[1], test_argv[2])); + EXPECT_EQ(0, strcmp(other_string_array[2], test_argv[3])); + } + + /* オプションを混ぜてみる */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "Ichgo Hoshimiya", "-i", "inputfile", "Aoi Kiriya", "Ran Shibuki" }; + const char* other_string_array[3]; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_OK, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + other_string_array, sizeof(other_string_array) / sizeof(other_string_array[0]))); + + /* 順番含め取れたか確認 */ + EXPECT_EQ(0, strcmp(other_string_array[0], test_argv[1])); + EXPECT_EQ(0, strcmp(other_string_array[1], test_argv[4])); + EXPECT_EQ(0, strcmp(other_string_array[2], test_argv[5])); + EXPECT_EQ(0, strcmp(specs[0].argument_string, "inputfile")); + } + + /* 失敗系 */ + + /* バッファサイズが足らない */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "Ichgo Hoshimiya", "Aoi Kiriya", "Ran Shibuki" }; + const char* other_string_array[2]; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_INSUFFICIENT_OTHER_STRING_ARRAY_SIZE, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + other_string_array, sizeof(other_string_array) / sizeof(other_string_array[0]))); + } +} + +/* 様々な文字列設定に対するテスト */ +TEST(CommandLineParserTest, ParseVariousStringTest) +{ + + /* 失敗系 */ + + /* パーサ仕様が不正 ケース1(ショートオプション重複) */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'a', "aikatsu", "aikatsu dakega boku no shinri datta...", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'i', NULL, "aikatsu dakega boku no shinri datta...", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "--input", "inputfile", "--aikatsu" }; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_INVALID_SPECIFICATION, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0)); + } + + /* パーサ仕様が不正 ケース2(ロングオプション重複) */ + { + struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'a', "aikatsu", "aikatsu dakega boku no shinri datta...", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'p', "input", "aikatsu dakega boku no shinri datta...", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + const char* test_argv[] = { "progname", "--input", "inputfile", "--aikatsu" }; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_INVALID_SPECIFICATION, + CommandLineParser_ParseArguments( + specs, + sizeof(test_argv) / sizeof(test_argv[0]), test_argv, + NULL, 0)); + } +} + +/* インデックス取得テスト */ +TEST(CommandLineParserTest, GetSpecificationIndexTest) +{ + /* 簡単な成功例 */ + { + uint32_t get_index, spec_no; + const struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'a', "aikatsu", "aikatsu dakega boku no shinri datta...", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'p', "RL", "aikatsu dakega boku no shinri datta...", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, } + }; + uint32_t num_specs = CommandLineParser_GetNumSpecifications(specs); + + for (spec_no = 0; spec_no < num_specs; spec_no++) { + char short_option_str[2]; + /* ショートオプションに対してテスト */ + short_option_str[0] = specs[spec_no].short_option; + short_option_str[1] = '\0'; + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_OK, + CommandLineParser_GetSpecificationIndex( + specs, short_option_str, &get_index)); + EXPECT_EQ(spec_no, get_index); + /* ロングオプションに対してテスト */ + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_OK, + CommandLineParser_GetSpecificationIndex( + specs, specs[spec_no].long_option, &get_index)); + EXPECT_EQ(spec_no, get_index); + } + } + + /* 失敗系 */ + + /* 引数が不正 */ + { + uint32_t get_index; + const struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'a', "aikatsu", "aikatsu dakega boku no shinri datta...", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'p', "RL", "aikatsu dakega boku no shinri datta...", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, NULL, } + }; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_INVALID_ARGUMENT, + CommandLineParser_GetSpecificationIndex( + NULL, "aikatsu", &get_index)); + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_INVALID_ARGUMENT, + CommandLineParser_GetSpecificationIndex( + specs, NULL, &get_index)); + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_INVALID_ARGUMENT, + CommandLineParser_GetSpecificationIndex( + specs, "aikatsu", NULL)); + } + + /* 存在しないオプションのインデックスを問い合わせる */ + { + uint32_t get_index; + const struct CommandLineParserSpecification specs[] = { + { 'i', "input", "input file", COMMAND_LINE_PARSER_TRUE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'a', "aikatsu", "aikatsu dakega boku no shinri datta...", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 'p', "RL", "aikatsu dakega boku no shinri datta...", COMMAND_LINE_PARSER_FALSE, NULL, COMMAND_LINE_PARSER_FALSE }, + { 0, } + }; + + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_UNKNOWN_OPTION, + CommandLineParser_GetSpecificationIndex( + specs, "aikats", &get_index)); + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_UNKNOWN_OPTION, + CommandLineParser_GetSpecificationIndex( + specs, "naru ayase", &get_index)); + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_UNKNOWN_OPTION, + CommandLineParser_GetSpecificationIndex( + specs, "rinne ibara", &get_index)); + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_UNKNOWN_OPTION, + CommandLineParser_GetSpecificationIndex( + specs, "s", &get_index)); + EXPECT_EQ( + COMMAND_LINE_PARSER_RESULT_UNKNOWN_OPTION, + CommandLineParser_GetSpecificationIndex( + specs, "b", &get_index)); + } +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/lpc/CMakeLists.txt b/test/lpc/CMakeLists.txt new file mode 100644 index 0000000..587b7a8 --- /dev/null +++ b/test/lpc/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# テスト名 +set(TEST_NAME lpc_test) + +# 実行形式ファイル +add_executable(${TEST_NAME} main.cpp) + +# インクルードディレクトリ +include_directories(${PROJECT_ROOT_PATH}/libs/lpc/include) + +# リンクするライブラリ +target_link_libraries(${TEST_NAME} gtest gtest_main) +if (NOT MSVC) +target_link_libraries(${TEST_NAME} pthread) +endif() + +# コンパイルオプション +set_target_properties(${TEST_NAME} + PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) + +add_test( + NAME lpc + COMMAND $ + ) + +# run with: ctest -L lib +set_property( + TEST lpc + PROPERTY LABELS lib lpc + ) diff --git a/test/lpc/main.cpp b/test/lpc/main.cpp new file mode 100644 index 0000000..0b7fd45 --- /dev/null +++ b/test/lpc/main.cpp @@ -0,0 +1,229 @@ +#include +#include + +#include + +/* テスト対象のモジュール */ +extern "C" { +#include "../../libs/lpc/src/lpc.c" +} + +/* ハンドル作成破棄テスト */ +TEST(LPCCalculatorTest, CreateDestroyHandleTest) +{ + /* ワークサイズ計算テスト */ + { + int32_t work_size; + struct LPCCalculatorConfig config; + + /* 最低限構造体本体よりは大きいはず */ + config.max_order = 1; + config.max_num_samples = 1; + work_size = LPCCalculator_CalculateWorkSize(&config); + ASSERT_TRUE(work_size > sizeof(struct LPCCalculator)); + + /* 不正なコンフィグ */ + EXPECT_TRUE(LPCCalculator_CalculateWorkSize(0) < 0); + } + + /* ワーク領域渡しによるハンドル作成(成功例) */ + { + void *work; + int32_t work_size; + struct LPCCalculatorConfig config; + struct LPCCalculator *lpcc; + + config.max_order = 1; + config.max_num_samples = 1; + work_size = LPCCalculator_CalculateWorkSize(&config); + work = malloc(work_size); + + lpcc = LPCCalculator_Create(&config, work, work_size); + ASSERT_TRUE(lpcc != NULL); + EXPECT_TRUE(lpcc->work == work); + EXPECT_EQ(lpcc->alloced_by_own, 0); + + LPCCalculator_Destroy(lpcc); + free(work); + } + + /* 自前確保によるハンドル作成(成功例) */ + { + struct LPCCalculator *lpcc; + struct LPCCalculatorConfig config; + + config.max_order = 1; + config.max_num_samples = 1; + lpcc = LPCCalculator_Create(&config, NULL, 0); + ASSERT_TRUE(lpcc != NULL); + EXPECT_TRUE(lpcc->work != NULL); + EXPECT_EQ(lpcc->alloced_by_own, 1); + + LPCCalculator_Destroy(lpcc); + } + + /* ワーク領域渡しによるハンドル作成(失敗ケース) */ + { + void *work; + int32_t work_size; + struct LPCCalculator *lpcc; + struct LPCCalculatorConfig config; + + config.max_order = 1; + config.max_num_samples = 1; + work_size = LPCCalculator_CalculateWorkSize(&config); + work = malloc(work_size); + + /* 引数が不正 */ + lpcc = LPCCalculator_Create(NULL, work, work_size); + EXPECT_TRUE(lpcc == NULL); + lpcc = LPCCalculator_Create(&config, NULL, work_size); + EXPECT_TRUE(lpcc == NULL); + lpcc = LPCCalculator_Create(&config, work, 0); + EXPECT_TRUE(lpcc == NULL); + + /* コンフィグパラメータが不正 */ + config.max_order = 0; config.max_num_samples = 1; + lpcc = LPCCalculator_Create(&config, work, work_size); + EXPECT_TRUE(lpcc == NULL); + config.max_order = 1; config.max_num_samples = 0; + lpcc = LPCCalculator_Create(&config, work, work_size); + EXPECT_TRUE(lpcc == NULL); + + free(work); + } + + /* 自前確保によるハンドル作成(失敗ケース) */ + { + struct LPCCalculator *lpcc; + struct LPCCalculatorConfig config; + + /* コンフィグパラメータが不正 */ + config.max_order = 0; config.max_num_samples = 1; + lpcc = LPCCalculator_Create(&config, NULL, 0); + EXPECT_TRUE(lpcc == NULL); + config.max_order = 1; config.max_num_samples = 0; + lpcc = LPCCalculator_Create(&config, NULL, 0); + EXPECT_TRUE(lpcc == NULL); + } +} + +/* (テスト用)PARCOR係数をLPC係数に変換 */ +static LPCError LPC_ConvertPARCORtoLPCDouble( + struct LPCCalculator* lpcc, const double* parcor_coef, uint32_t coef_order, double *lpc_coef) +{ + int32_t i, k; + double *a_vec; + + /* 引数チェック */ + if ((lpcc == NULL) || (lpc_coef == NULL) || (parcor_coef == NULL)) { + return LPC_ERROR_INVALID_ARGUMENT; + } + + /* 次数チェック */ + assert(coef_order <= lpcc->max_order); + + /* 作業領域を割り当て */ + a_vec = lpcc->a_vecs[0]; + + /* 再帰計算 */ + lpc_coef[0] = -parcor_coef[0]; + for (i = 1; i < coef_order; i++) { + const double gamma = -parcor_coef[i]; + for (k = 0; k < i; k++) { + a_vec[k] = lpc_coef[k]; + } + for (k = 0; k < i; k++) { + lpc_coef[k] = a_vec[k] + (gamma * a_vec[i - k - 1]); + } + lpc_coef[i] = gamma; + } + + return LPC_ERROR_OK; +} + +/* LPC係数をPARCOR係数に変換するテスト */ +TEST(LPCCalculatorTest, LPC_ConvertLPCandPARCORTest) +{ + /* LPC->PARCORの簡単な成功例 */ + { +#define NUM_SAMPLES 32 +#define COEF_ORDER 16 + uint32_t i; + struct LPCCalculator* lpcc; + struct LPCCalculatorConfig config; + double data[NUM_SAMPLES], lpc_coef[COEF_ORDER], answer[COEF_ORDER], test[COEF_ORDER]; + + for (i = 0; i < NUM_SAMPLES; i++) { + data[i] = sin(0.1 * i); + } + + config.max_num_samples = NUM_SAMPLES; config.max_order = COEF_ORDER; + lpcc = LPCCalculator_Create(&config, NULL, 0); + ASSERT_TRUE(lpcc != NULL); + + /* 係数計算 */ + ASSERT_EQ(LPC_APIRESULT_OK, + LPCCalculator_CalculateLPCCoefficients(lpcc, + data, NUM_SAMPLES, lpc_coef, COEF_ORDER, LPC_WINDOWTYPE_RECTANGULAR, 0.0)); + memcpy(answer, lpcc->parcor_coef, sizeof(double) * COEF_ORDER); + + LPCCalculator_Destroy(lpcc); + + /* LPC->PARCOR変換 */ + lpcc = LPCCalculator_Create(&config, NULL, 0); + EXPECT_EQ(LPC_ERROR_OK, LPC_ConvertLPCtoPARCORDouble(lpcc, lpc_coef, COEF_ORDER, test)); + + /* 一致確認 */ + for (i = 0; i < COEF_ORDER; i++) { + EXPECT_FLOAT_EQ(answer[i], test[i]); + } + + LPCCalculator_Destroy(lpcc); +#undef NUM_SAMPLES +#undef COEF_ORDER + } + + /* PARCOR->LPCの簡単な成功例 */ + { +#define NUM_SAMPLES 32 +#define COEF_ORDER 16 + uint32_t i; + struct LPCCalculator* lpcc; + struct LPCCalculatorConfig config; + double data[NUM_SAMPLES], lpc_coef[COEF_ORDER], answer[COEF_ORDER], test[COEF_ORDER]; + + for (i = 0; i < NUM_SAMPLES; i++) { + data[i] = sin(0.1 * i); + } + + config.max_num_samples = NUM_SAMPLES; config.max_order = COEF_ORDER; + lpcc = LPCCalculator_Create(&config, NULL, 0); + ASSERT_TRUE(lpcc != NULL); + + ASSERT_EQ(LPC_APIRESULT_OK, + LPCCalculator_CalculateLPCCoefficients(lpcc, + data, NUM_SAMPLES, lpc_coef, COEF_ORDER, LPC_WINDOWTYPE_RECTANGULAR, 0.0)); + memcpy(answer, lpcc->parcor_coef, sizeof(double) * COEF_ORDER); + + LPCCalculator_Destroy(lpcc); + + /* PARCOR->LPC変換 */ + lpcc = LPCCalculator_Create(&config, NULL, 0); + EXPECT_EQ(LPC_ERROR_OK, LPC_ConvertPARCORtoLPCDouble(lpcc, answer, COEF_ORDER, test)); + + for (i = 0; i < COEF_ORDER; i++) { + EXPECT_FLOAT_EQ(lpc_coef[i], test[i]); + } + + LPCCalculator_Destroy(lpcc); +#undef NUM_SAMPLES +#undef COEF_ORDER + } +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/srla_coder/CMakeLists.txt b/test/srla_coder/CMakeLists.txt new file mode 100644 index 0000000..449a7fa --- /dev/null +++ b/test/srla_coder/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# テスト名 +set(TEST_NAME srla_coder_test) + +# 実行形式ファイル +add_executable(${TEST_NAME} main.cpp) + +# インクルードディレクトリ +include_directories(${PROJECT_ROOT_PATH}/libs/srla_coder/include) + +# リンクするライブラリ +target_link_libraries(${TEST_NAME} gtest gtest_main bit_stream srla_internal srla_coder) +if (NOT MSVC) +target_link_libraries(${TEST_NAME} pthread) +endif() + +# コンパイルオプション +set_target_properties(${TEST_NAME} + PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) + +# 実行パスをtmp以下に +add_test( + NAME srla_coder + WORKING_DIRECTORY $/tmp + COMMAND $ + ) + +# run with: ctest -L lib +set_property( + TEST srla_coder + PROPERTY LABELS lib srla_coder + ) + +# ビルド後にテストリソースを持ってくる +add_custom_command( + TARGET ${TEST_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory $/tmp + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/PriChanIcon.png $/tmp + ) diff --git a/test/srla_coder/PriChanIcon.png b/test/srla_coder/PriChanIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..e7f7136aeb891859dd4467ab0fd2e4d806a8220a GIT binary patch literal 214955 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 z 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%0Ab}lz(@=#8<gwlfX=ii!CJMF!QbuH&efI?T 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 literal 0 HcmV?d00001 diff --git a/test/srla_coder/main.cpp b/test/srla_coder/main.cpp new file mode 100644 index 0000000..0d2dcfc --- /dev/null +++ b/test/srla_coder/main.cpp @@ -0,0 +1,314 @@ +#include +#include + +#include + +/* テスト対象のモジュール */ +extern "C" { +#include "../../libs/srla_coder/src/srla_coder.c" +} + +/* ハンドル作成破棄テスト */ +TEST(SRLACoderTest, CreateDestroyHandleTest) +{ + /* ワークサイズ計算テスト */ + { + int32_t work_size; + + /* 最低限構造体本体よりは大きいはず */ + work_size = SRLACoder_CalculateWorkSize(); + ASSERT_TRUE(work_size > sizeof(struct SRLACoder)); + } + + /* ワーク領域渡しによるハンドル作成(成功例) */ + { + void *work; + int32_t work_size; + struct SRLACoder *coder; + + work_size = SRLACoder_CalculateWorkSize(); + work = malloc(work_size); + + coder = SRLACoder_Create(work, work_size); + ASSERT_TRUE(coder != NULL); + EXPECT_TRUE(coder->work == work); + EXPECT_EQ(coder->alloced_by_own, 0); + + SRLACoder_Destroy(coder); + free(work); + } + + /* 自前確保によるハンドル作成(成功例) */ + { + struct SRLACoder *coder; + + coder = SRLACoder_Create(NULL, 0); + ASSERT_TRUE(coder != NULL); + EXPECT_TRUE(coder->work != NULL); + EXPECT_EQ(coder->alloced_by_own, 1); + + SRLACoder_Destroy(coder); + } + + /* ワーク領域渡しによるハンドル作成(失敗ケース) */ + { + void *work; + int32_t work_size; + struct SRLACoder *coder; + + work_size = SRLACoder_CalculateWorkSize(); + work = malloc(work_size); + + /* 引数が不正 */ + coder = SRLACoder_Create(NULL, work_size); + EXPECT_TRUE(coder == NULL); + coder = SRLACoder_Create(work, 0); + EXPECT_TRUE(coder == NULL); + + /* ワークサイズ不足 */ + coder = SRLACoder_Create(work, work_size - 1); + EXPECT_TRUE(coder == NULL); + } +} + +/* 再帰的ライス符号テスト */ +TEST(SRLACoderTest, RecursiveRiceTest) +{ + /* 簡単に出力テスト */ + { + uint32_t code; + uint8_t data[16]; + struct BitStream strm; + + /* 0を4回出力 */ + memset(data, 0, sizeof(data)); + BitWriter_Open(&strm, data, sizeof(data)); + RecursiveRice_PutCode(&strm, 1, 1, 0); + RecursiveRice_PutCode(&strm, 1, 1, 0); + RecursiveRice_PutCode(&strm, 1, 1, 0); + RecursiveRice_PutCode(&strm, 1, 1, 0); + BitStream_Close(&strm); + + /* 取得 */ + BitReader_Open(&strm, data, sizeof(data)); + RecursiveRice_GetCode(&strm, 1, 1, &code); + EXPECT_EQ(0, code); + RecursiveRice_GetCode(&strm, 1, 1, &code); + EXPECT_EQ(0, code); + RecursiveRice_GetCode(&strm, 1, 1, &code); + EXPECT_EQ(0, code); + RecursiveRice_GetCode(&strm, 1, 1, &code); + EXPECT_EQ(0, code); + BitStream_Close(&strm); + + /* 1を4回出力 */ + memset(data, 0, sizeof(data)); + BitWriter_Open(&strm, data, sizeof(data)); + RecursiveRice_PutCode(&strm, 1, 1, 1); + RecursiveRice_PutCode(&strm, 1, 1, 1); + RecursiveRice_PutCode(&strm, 1, 1, 1); + RecursiveRice_PutCode(&strm, 1, 1, 1); + BitStream_Close(&strm); + + /* 取得 */ + BitReader_Open(&strm, data, sizeof(data)); + RecursiveRice_GetCode(&strm, 1, 1, &code); + EXPECT_EQ(1, code); + RecursiveRice_GetCode(&strm, 1, 1, &code); + EXPECT_EQ(1, code); + RecursiveRice_GetCode(&strm, 1, 1, &code); + EXPECT_EQ(1, code); + RecursiveRice_GetCode(&strm, 1, 1, &code); + EXPECT_EQ(1, code); + BitStream_Close(&strm); + + /* パラメータを変えて0を4回出力 */ + memset(data, 0, sizeof(data)); + BitWriter_Open(&strm, data, sizeof(data)); + RecursiveRice_PutCode(&strm, 2, 2, 0); + RecursiveRice_PutCode(&strm, 2, 2, 0); + RecursiveRice_PutCode(&strm, 2, 2, 0); + RecursiveRice_PutCode(&strm, 2, 2, 0); + BitStream_Close(&strm); + + /* 取得 */ + BitReader_Open(&strm, data, sizeof(data)); + RecursiveRice_GetCode(&strm, 2, 2, &code); + EXPECT_EQ(0, code); + RecursiveRice_GetCode(&strm, 2, 2, &code); + EXPECT_EQ(0, code); + RecursiveRice_GetCode(&strm, 2, 2, &code); + EXPECT_EQ(0, code); + RecursiveRice_GetCode(&strm, 2, 2, &code); + EXPECT_EQ(0, code); + BitStream_Close(&strm); + + /* パラメータを変えて3を4回出力 */ + memset(data, 0, sizeof(data)); + BitWriter_Open(&strm, data, sizeof(data)); + RecursiveRice_PutCode(&strm, 2, 2, 3); + RecursiveRice_PutCode(&strm, 2, 2, 3); + RecursiveRice_PutCode(&strm, 2, 2, 3); + RecursiveRice_PutCode(&strm, 2, 2, 3); + BitStream_Close(&strm); + + /* 取得 */ + BitReader_Open(&strm, data, sizeof(data)); + RecursiveRice_GetCode(&strm, 2, 2, &code); + EXPECT_EQ(3, code); + RecursiveRice_GetCode(&strm, 2, 2, &code); + EXPECT_EQ(3, code); + RecursiveRice_GetCode(&strm, 2, 2, &code); + EXPECT_EQ(3, code); + RecursiveRice_GetCode(&strm, 2, 2, &code); + EXPECT_EQ(3, code); + BitStream_Close(&strm); + } + + /* 長めの信号を出力してみる */ + { +#define TEST_OUTPUT_LENGTH (128) + uint32_t i, code, is_ok, k1, k2; + struct BitStream strm; + int32_t test_output_pattern[TEST_OUTPUT_LENGTH]; + uint8_t data[TEST_OUTPUT_LENGTH * 2]; + double mean = 0.0; + + /* 出力の生成 */ + for (i = 0; i < TEST_OUTPUT_LENGTH; i++) { + test_output_pattern[i] = i; + mean += test_output_pattern[i]; + } + mean /= TEST_OUTPUT_LENGTH; + + /* 最適なパラメータの計算 */ + SRLACoder_CalculateOptimalRecursiveRiceParameter(mean, &k1, &k2, NULL); + + /* 出力 */ + BitWriter_Open(&strm, data, sizeof(data)); + for (i = 0; i < TEST_OUTPUT_LENGTH; i++) { + RecursiveRice_PutCode(&strm, k1, k2, test_output_pattern[i]); + } + BitStream_Close(&strm); + + /* 取得 */ + BitReader_Open(&strm, data, sizeof(data)); + is_ok = 1; + for (i = 0; i < TEST_OUTPUT_LENGTH; i++) { + uint32_t uval; + RecursiveRice_GetCode(&strm, k1, k2, &uval); + if (uval != test_output_pattern[i]) { + printf("actual:%d != test:%d \n", uval, test_output_pattern[i]); + is_ok = 0; + break; + } + } + EXPECT_EQ(1, is_ok); + BitStream_Close(&strm); +#undef TEST_OUTPUT_LENGTH + } + + /* 長めの信号を出力してみる(乱数) */ + { +#define TEST_OUTPUT_LENGTH (128) + uint32_t i, code, is_ok, k1, k2; + struct BitStream strm; + int32_t test_output_pattern[TEST_OUTPUT_LENGTH]; + uint8_t data[TEST_OUTPUT_LENGTH * 2]; + double mean = 0.0; + + /* 出力の生成 */ + srand(0); + for (i = 0; i < TEST_OUTPUT_LENGTH; i++) { + test_output_pattern[i] = rand() % 0xFF; + mean += test_output_pattern[i]; + } + mean /= TEST_OUTPUT_LENGTH; + + /* 最適なパラメータの計算 */ + SRLACoder_CalculateOptimalRecursiveRiceParameter(mean, &k1, &k2, NULL); + + /* 出力 */ + BitWriter_Open(&strm, data, sizeof(data)); + for (i = 0; i < TEST_OUTPUT_LENGTH; i++) { + RecursiveRice_PutCode(&strm, k1, k2, test_output_pattern[i]); + } + BitStream_Close(&strm); + + /* 取得 */ + BitReader_Open(&strm, data, sizeof(data)); + is_ok = 1; + for (i = 0; i < TEST_OUTPUT_LENGTH; i++) { + uint32_t uval; + RecursiveRice_GetCode(&strm, k1, k2, &uval); + if (uval != test_output_pattern[i]) { + printf("actual:%d != test:%d \n", uval, test_output_pattern[i]); + is_ok = 0; + break; + } + } + EXPECT_EQ(1, is_ok); + BitStream_Close(&strm); +#undef TEST_OUTPUT_LENGTH + } + + /* 実データを符号化してみる */ + { + uint32_t i, encsize, k1, k2; + struct stat fstat; + const char test_infile_name[] = "PriChanIcon.png"; + uint8_t *fileimg; + uint8_t *encimg; + uint8_t *decimg; + double mean; + FILE *fp; + struct BitStream strm; + + /* 入力データ読み出し */ + stat(test_infile_name, &fstat); + fileimg = (uint8_t *)malloc(fstat.st_size); + encimg = (uint8_t *)malloc(2 * fstat.st_size); /* PNG画像のため増えることを想定 */ + decimg = (uint8_t *)malloc(fstat.st_size); + fp = fopen(test_infile_name, "rb"); + fread(fileimg, sizeof(uint8_t), fstat.st_size, fp); + fclose(fp); + + /* 最適なパラメータ計算 */ + mean = 0.0; + for (i = 0; i < fstat.st_size; i++) { + mean += fileimg[i]; + } + mean /= fstat.st_size; + SRLACoder_CalculateOptimalRecursiveRiceParameter(mean, &k1, &k2, NULL); + + /* 書き込み */ + BitWriter_Open(&strm, encimg, 2 * fstat.st_size); + for (i = 0; i < fstat.st_size; i++) { + RecursiveRice_PutCode(&strm, k1, k2, fileimg[i]); + } + BitStream_Flush(&strm); + BitStream_Tell(&strm, (int32_t *)&encsize); + BitStream_Close(&strm); + + /* 読み込み */ + BitReader_Open(&strm, encimg, encsize); + for (i = 0; i < fstat.st_size; i++) { + uint32_t uval; + RecursiveRice_GetCode(&strm, k1, k2, &uval) + decimg[i] = (uint8_t)uval; + } + BitStream_Close(&strm); + + /* 一致確認 */ + EXPECT_EQ(0, memcmp(fileimg, decimg, sizeof(uint8_t) * fstat.st_size)); + + free(decimg); + free(fileimg); + } +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/srla_decoder/CMakeLists.txt b/test/srla_decoder/CMakeLists.txt new file mode 100644 index 0000000..f890a25 --- /dev/null +++ b/test/srla_decoder/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# テスト名 +set(TEST_NAME srla_decoder_test) + +# 実行形式ファイル +add_executable(${TEST_NAME} + srla_decoder_test.cpp + srla_lpc_synthesize_test.cpp + main.cpp + ) + +# インクルードディレクトリ +include_directories(${PROJECT_ROOT_PATH}/libs/srla_decoder/include) + +# リンクするライブラリ +target_link_libraries(${TEST_NAME} gtest gtest_main byte_array bit_stream srla_encoder srla_coder srla_internal lpc) +if (NOT MSVC) +target_link_libraries(${TEST_NAME} pthread) +endif() + +# コンパイルオプション +set_target_properties(${TEST_NAME} + PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) + +add_test( + NAME srla_decoder + COMMAND $ + ) + +# run with: ctest -L lib +set_property( + TEST srla_decoder + PROPERTY LABELS lib srla_decoder + ) diff --git a/test/srla_decoder/main.cpp b/test/srla_decoder/main.cpp new file mode 100644 index 0000000..96d7200 --- /dev/null +++ b/test/srla_decoder/main.cpp @@ -0,0 +1,7 @@ +#include + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/srla_decoder/srla_decoder_test.cpp b/test/srla_decoder/srla_decoder_test.cpp new file mode 100644 index 0000000..f4f33d1 --- /dev/null +++ b/test/srla_decoder/srla_decoder_test.cpp @@ -0,0 +1,537 @@ +#include +#include + +#include + +#include "srla_encoder.h" + +/* テスト対象のモジュール */ +extern "C" { +#include "../../libs/srla_decoder/src/srla_decoder.c" +} + +/* 有効なヘッダをセット */ +#define SRLA_SetValidHeader(p_header)\ + do {\ + struct SRLAHeader *header__p = p_header;\ + header__p->format_version = SRLA_FORMAT_VERSION;\ + header__p->codec_version = SRLA_CODEC_VERSION;\ + header__p->num_channels = 1;\ + header__p->sampling_rate = 44100;\ + header__p->bits_per_sample = 16;\ + header__p->num_samples = 8192;\ + header__p->num_samples_per_block = 1024;\ + header__p->preset = 0;\ + } while (0); + +/* ヘッダにある情報からエンコードパラメータを作成 */ +#define SRLAEncoder_ConvertHeaderToParameter(p_header, p_parameter)\ + do {\ + const struct SRLAHeader *header__p = p_header;\ + struct SRLAEncodeParameter *param__p = p_parameter;\ + param__p->num_channels = header__p->num_channels;\ + param__p->sampling_rate = header__p->sampling_rate;\ + param__p->bits_per_sample = header__p->bits_per_sample;\ + param__p->num_samples_per_block = header__p->num_samples_per_block;\ + param__p->preset = header__p->preset;\ + } while (0); + +/* 有効なエンコードパラメータをセット */ +#define SRLAEncoder_SetValidEncodeParameter(p_parameter)\ + do {\ + struct SRLAEncodeParameter *param__p = p_parameter;\ + param__p->num_channels = 1;\ + param__p->bits_per_sample = 16;\ + param__p->sampling_rate = 44100;\ + param__p->num_samples_per_block = 1024;\ + param__p->preset = 0;\ + } while (0); + +/* 有効なエンコーダコンフィグをセット */ +#define SRLAEncoder_SetValidConfig(p_config)\ + do {\ + struct SRLAEncoderConfig *config__p = p_config;\ + config__p->max_num_channels = 8;\ + config__p->max_num_samples_per_block = 4096;\ + config__p->max_num_parameters = 32;\ + } while (0); + +/* 有効なデコーダコンフィグをセット */ +#define SRLADecoder_SetValidConfig(p_config)\ + do {\ + struct SRLADecoderConfig *config__p = p_config;\ + config__p->max_num_channels = 8;\ + config__p->max_num_parameters = 32;\ + config__p->check_checksum = 1;\ + } while (0); + +/* ヘッダデコードテスト */ +TEST(SRLADecoderTest, DecodeHeaderTest) +{ + /* 成功例 */ + { + uint8_t data[SRLA_HEADER_SIZE] = { 0, }; + struct SRLAHeader header, tmp_header; + + SRLA_SetValidHeader(&header); + + /* エンコード->デコード */ + EXPECT_EQ(SRLA_APIRESULT_OK, SRLAEncoder_EncodeHeader(&header, data, sizeof(data))); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, sizeof(data), &tmp_header)); + + /* デコードしたヘッダの一致確認 */ + EXPECT_EQ(SRLA_FORMAT_VERSION, tmp_header.format_version); + EXPECT_EQ(SRLA_CODEC_VERSION, tmp_header.codec_version); + EXPECT_EQ(header.num_channels, tmp_header.num_channels); + EXPECT_EQ(header.sampling_rate, tmp_header.sampling_rate); + EXPECT_EQ(header.bits_per_sample, tmp_header.bits_per_sample); + EXPECT_EQ(header.num_samples, tmp_header.num_samples); + EXPECT_EQ(header.num_samples_per_block, tmp_header.num_samples_per_block); + EXPECT_EQ(header.preset, tmp_header.preset); + } + + /* ヘッダデコード失敗ケース */ + { + struct SRLAHeader header, getheader; + uint8_t valid_data[SRLA_HEADER_SIZE] = { 0, }; + uint8_t data[SRLA_HEADER_SIZE]; + + /* 有効な内容を作っておく */ + SRLA_SetValidHeader(&header); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLAEncoder_EncodeHeader(&header, valid_data, sizeof(valid_data))); + /* 有効であることを確認 */ + ASSERT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(valid_data, sizeof(valid_data), &getheader)); + + /* シグネチャが不正 */ + memcpy(data, valid_data, sizeof(valid_data)); + memset(&getheader, 0xCD, sizeof(getheader)); + ByteArray_WriteUint8(&data[0], 'a'); + EXPECT_EQ(SRLA_APIRESULT_INVALID_FORMAT, SRLADecoder_DecodeHeader(data, sizeof(data), &getheader)); + + /* 以降のテストケースでは、ヘッダは取得できるが、内部のチェック関数で失敗する */ + + /* 異常なフォーマットバージョン */ + memcpy(data, valid_data, sizeof(valid_data)); + memset(&getheader, 0xCD, sizeof(getheader)); + ByteArray_WriteUint32BE(&data[4], 0); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, sizeof(data), &getheader)); + EXPECT_EQ(SRLA_ERROR_INVALID_FORMAT, SRLADecoder_CheckHeaderFormat(&getheader)); + memcpy(data, valid_data, sizeof(valid_data)); + memset(&getheader, 0xCD, sizeof(getheader)); + ByteArray_WriteUint32BE(&data[4], SRLA_FORMAT_VERSION + 1); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, sizeof(data), &getheader)); + EXPECT_EQ(SRLA_ERROR_INVALID_FORMAT, SRLADecoder_CheckHeaderFormat(&getheader)); + + /* 異常なエンコーダバージョン */ + memcpy(data, valid_data, sizeof(valid_data)); + memset(&getheader, 0xCD, sizeof(getheader)); + ByteArray_WriteUint32BE(&data[8], 0); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, sizeof(data), &getheader)); + EXPECT_EQ(SRLA_ERROR_INVALID_FORMAT, SRLADecoder_CheckHeaderFormat(&getheader)); + memcpy(data, valid_data, sizeof(valid_data)); + memset(&getheader, 0xCD, sizeof(getheader)); + ByteArray_WriteUint32BE(&data[8], SRLA_CODEC_VERSION + 1); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, sizeof(data), &getheader)); + EXPECT_EQ(SRLA_ERROR_INVALID_FORMAT, SRLADecoder_CheckHeaderFormat(&getheader)); + + /* 異常なチャンネル数 */ + memcpy(data, valid_data, sizeof(valid_data)); + memset(&getheader, 0xCD, sizeof(getheader)); + ByteArray_WriteUint16BE(&data[12], 0); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, sizeof(data), &getheader)); + EXPECT_EQ(SRLA_ERROR_INVALID_FORMAT, SRLADecoder_CheckHeaderFormat(&getheader)); + + /* 異常なサンプル数 */ + memcpy(data, valid_data, sizeof(valid_data)); + memset(&getheader, 0xCD, sizeof(getheader)); + ByteArray_WriteUint32BE(&data[14], 0); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, sizeof(data), &getheader)); + EXPECT_EQ(SRLA_ERROR_INVALID_FORMAT, SRLADecoder_CheckHeaderFormat(&getheader)); + + /* 異常なサンプリングレート */ + memcpy(data, valid_data, sizeof(valid_data)); + memset(&getheader, 0xCD, sizeof(getheader)); + ByteArray_WriteUint32BE(&data[18], 0); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, sizeof(data), &getheader)); + EXPECT_EQ(SRLA_ERROR_INVALID_FORMAT, SRLADecoder_CheckHeaderFormat(&getheader)); + + /* 異常なサンプルあたりビット数 */ + memcpy(data, valid_data, sizeof(valid_data)); + memset(&getheader, 0xCD, sizeof(getheader)); + ByteArray_WriteUint16BE(&data[22], 0); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, sizeof(data), &getheader)); + EXPECT_EQ(SRLA_ERROR_INVALID_FORMAT, SRLADecoder_CheckHeaderFormat(&getheader)); + + /* 異常なブロックあたりサンプル数 */ + memcpy(data, valid_data, sizeof(valid_data)); + memset(&getheader, 0xCD, sizeof(getheader)); + ByteArray_WriteUint32BE(&data[24], 0); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, sizeof(data), &getheader)); + EXPECT_EQ(SRLA_ERROR_INVALID_FORMAT, SRLADecoder_CheckHeaderFormat(&getheader)); + + /* 異常なプリセット */ + memcpy(data, valid_data, sizeof(valid_data)); + memset(&getheader, 0xCD, sizeof(getheader)); + ByteArray_WriteUint8(&data[28], SRLA_NUM_PARAMETER_PRESETS); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, sizeof(data), &getheader)); + EXPECT_EQ(SRLA_ERROR_INVALID_FORMAT, SRLADecoder_CheckHeaderFormat(&getheader)); + } +} + +/* デコーダハンドル生成破棄テスト */ +TEST(SRLADecoderTest, CreateDestroyHandleTest) +{ + /* ワークサイズ計算テスト */ + { + int32_t work_size; + struct SRLADecoderConfig config; + + /* 最低限構造体本体よりは大きいはず */ + SRLADecoder_SetValidConfig(&config); + work_size = SRLADecoder_CalculateWorkSize(&config); + ASSERT_TRUE(work_size > sizeof(struct SRLADecoder)); + + /* 不正な引数 */ + EXPECT_TRUE(SRLADecoder_CalculateWorkSize(NULL) < 0); + + /* 不正なコンフィグ */ + SRLADecoder_SetValidConfig(&config); + config.max_num_channels = 0; + EXPECT_TRUE(SRLADecoder_CalculateWorkSize(&config) < 0); + + SRLADecoder_SetValidConfig(&config); + config.max_num_parameters = 0; + EXPECT_TRUE(SRLADecoder_CalculateWorkSize(&config) < 0); + } + + /* ワーク領域渡しによるハンドル作成(成功例) */ + { + void *work; + int32_t work_size; + struct SRLADecoder *decoder; + struct SRLADecoderConfig config; + + SRLADecoder_SetValidConfig(&config); + work_size = SRLADecoder_CalculateWorkSize(&config); + work = malloc(work_size); + + decoder = SRLADecoder_Create(&config, work, work_size); + ASSERT_TRUE(decoder != NULL); + EXPECT_TRUE(decoder->work == work); + EXPECT_FALSE(SRLADECODER_GET_STATUS_FLAG(decoder, SRLADECODER_STATUS_FLAG_ALLOCED_BY_OWN)); + EXPECT_FALSE(SRLADECODER_GET_STATUS_FLAG(decoder, SRLADECODER_STATUS_FLAG_SET_HEADER)); + EXPECT_TRUE(decoder->params_int != NULL); + EXPECT_TRUE(decoder->params_int[0] != NULL); + EXPECT_TRUE(decoder->rshifts != NULL); + + SRLADecoder_Destroy(decoder); + free(work); + } + + /* 自前確保によるハンドル作成(成功例) */ + { + struct SRLADecoder *decoder; + struct SRLADecoderConfig config; + + SRLADecoder_SetValidConfig(&config); + + decoder = SRLADecoder_Create(&config, NULL, 0); + ASSERT_TRUE(decoder != NULL); + EXPECT_TRUE(decoder->work != NULL); + EXPECT_TRUE(SRLADECODER_GET_STATUS_FLAG(decoder, SRLADECODER_STATUS_FLAG_ALLOCED_BY_OWN)); + EXPECT_FALSE(SRLADECODER_GET_STATUS_FLAG(decoder, SRLADECODER_STATUS_FLAG_SET_HEADER)); + EXPECT_TRUE(decoder->params_int != NULL); + EXPECT_TRUE(decoder->params_int[0] != NULL); + EXPECT_TRUE(decoder->rshifts != NULL); + + SRLADecoder_Destroy(decoder); + } + + /* ワーク領域渡しによるハンドル作成(失敗ケース) */ + { + void *work; + int32_t work_size; + struct SRLADecoder *decoder; + struct SRLADecoderConfig config; + + SRLADecoder_SetValidConfig(&config); + work_size = SRLADecoder_CalculateWorkSize(&config); + work = malloc(work_size); + + /* 引数が不正 */ + decoder = SRLADecoder_Create(NULL, work, work_size); + EXPECT_TRUE(decoder == NULL); + decoder = SRLADecoder_Create(&config, NULL, work_size); + EXPECT_TRUE(decoder == NULL); + decoder = SRLADecoder_Create(&config, work, 0); + EXPECT_TRUE(decoder == NULL); + + /* ワークサイズ不足 */ + decoder = SRLADecoder_Create(&config, work, work_size - 1); + EXPECT_TRUE(decoder == NULL); + + /* コンフィグが不正 */ + SRLADecoder_SetValidConfig(&config); + config.max_num_channels = 0; + decoder = SRLADecoder_Create(&config, work, work_size); + EXPECT_TRUE(decoder == NULL); + + SRLADecoder_SetValidConfig(&config); + config.max_num_parameters = 0; + decoder = SRLADecoder_Create(&config, work, work_size); + EXPECT_TRUE(decoder == NULL); + } + + /* 自前確保によるハンドル作成(失敗ケース) */ + { + struct SRLADecoder *decoder; + struct SRLADecoderConfig config; + + SRLADecoder_SetValidConfig(&config); + + /* 引数が不正 */ + decoder = SRLADecoder_Create(NULL, NULL, 0); + EXPECT_TRUE(decoder == NULL); + + /* コンフィグが不正 */ + SRLADecoder_SetValidConfig(&config); + config.max_num_channels = 0; + decoder = SRLADecoder_Create(&config, NULL, 0); + EXPECT_TRUE(decoder == NULL); + + SRLADecoder_SetValidConfig(&config); + config.max_num_parameters = 0; + decoder = SRLADecoder_Create(&config, NULL, 0); + EXPECT_TRUE(decoder == NULL); + } +} + +/* 1ブロックデコードテスト */ +TEST(SRLADecoderTest, DecodeBlockTest) +{ + /* ヘッダ設定前にデコードしてエラー */ + { + struct SRLADecoder *decoder; + struct SRLADecoderConfig config; + struct SRLAHeader header; + uint8_t *data; + int32_t *output[SRLA_MAX_NUM_CHANNELS]; + uint32_t ch, sufficient_size, output_size, out_num_samples; + + SRLA_SetValidHeader(&header); + SRLADecoder_SetValidConfig(&config); + + /* 十分なデータサイズ */ + sufficient_size = (2 * header.num_channels * header.num_samples_per_block * header.bits_per_sample) / 8; + + /* データ領域確保 */ + data = (uint8_t *)malloc(sufficient_size); + for (ch = 0; ch < header.num_channels; ch++) { + output[ch] = (int32_t *)malloc(sizeof(int32_t) * header.num_samples_per_block); + } + + /* デコーダ作成 */ + decoder = SRLADecoder_Create(&config, NULL, 0); + ASSERT_TRUE(decoder != NULL); + + /* ヘッダセット前にデコーダしようとする */ + EXPECT_EQ(SRLA_APIRESULT_PARAMETER_NOT_SET, + SRLADecoder_DecodeBlock(decoder, data, sufficient_size, output, header.num_channels, header.num_samples_per_block, &output_size, &out_num_samples)); + + /* ヘッダをセット */ + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_SetHeader(decoder, &header)); + + /* 領域の開放 */ + for (ch = 0; ch < header.num_channels; ch++) { + free(output[ch]); + } + free(data); + SRLADecoder_Destroy(decoder); + } + + /* 無音データをエンコードデコードしてみる */ + { + struct SRLAEncoder *encoder; + struct SRLADecoder *decoder; + struct SRLAEncoderConfig encoder_config; + struct SRLADecoderConfig decoder_config; + struct SRLAEncodeParameter parameter; + struct SRLAHeader header, tmp_header; + uint8_t *data; + int32_t *input[SRLA_MAX_NUM_CHANNELS]; + int32_t *output[SRLA_MAX_NUM_CHANNELS]; + uint32_t ch, sufficient_size, output_size, decode_output_size, out_num_samples; + + SRLA_SetValidHeader(&header); + SRLAEncoder_SetValidConfig(&encoder_config); + SRLADecoder_SetValidConfig(&decoder_config); + + /* 十分なデータサイズ */ + sufficient_size = (2 * header.num_channels * header.num_samples_per_block * header.bits_per_sample) / 8; + + /* データ領域確保 */ + data = (uint8_t *)malloc(sufficient_size); + for (ch = 0; ch < header.num_channels; ch++) { + input[ch] = (int32_t *)malloc(sizeof(int32_t) * header.num_samples_per_block); + output[ch] = (int32_t *)malloc(sizeof(int32_t) * header.num_samples_per_block); + } + + /* エンコーダデコーダ作成 */ + encoder = SRLAEncoder_Create(&encoder_config, NULL, 0); + decoder = SRLADecoder_Create(&decoder_config, NULL, 0); + ASSERT_TRUE(encoder != NULL); + ASSERT_TRUE(decoder != NULL); + + /* 入力に無音セット */ + for (ch = 0; ch < header.num_channels; ch++) { + memset(input[ch], 0, sizeof(int32_t) * header.num_samples_per_block); + } + + /* ヘッダを元にパラメータを設定 */ + SRLAEncoder_ConvertHeaderToParameter(&header, ¶meter); + + /* 入力データをエンコード */ + EXPECT_EQ(SRLA_APIRESULT_OK, SRLAEncoder_SetEncodeParameter(encoder, ¶meter)); + EXPECT_EQ(SRLA_APIRESULT_OK, + SRLAEncoder_EncodeWhole(encoder, input, header.num_samples_per_block, data, sufficient_size, &output_size)); + + /* エンコードデータを簡易チェック */ + EXPECT_TRUE(output_size > SRLA_HEADER_SIZE); + EXPECT_TRUE(output_size < sufficient_size); + + /* デコード */ + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, output_size, &tmp_header)); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_SetHeader(decoder, &tmp_header)); + EXPECT_EQ(SRLA_APIRESULT_OK, + SRLADecoder_DecodeBlock(decoder, data + SRLA_HEADER_SIZE, output_size - SRLA_HEADER_SIZE, + output, header.num_channels, tmp_header.num_samples_per_block, &decode_output_size, &out_num_samples)); + + /* 出力チェック */ + EXPECT_EQ(output_size - SRLA_HEADER_SIZE, decode_output_size); + EXPECT_EQ(header.num_samples_per_block, out_num_samples); + for (ch = 0; ch < header.num_channels; ch++) { + EXPECT_EQ(0, memcmp(input[ch], output[ch], sizeof(int32_t) * header.num_samples_per_block)); + } + + /* 領域の開放 */ + for (ch = 0; ch < header.num_channels; ch++) { + free(output[ch]); + free(input[ch]); + } + free(data); + SRLADecoder_Destroy(decoder); + SRLAEncoder_Destroy(encoder); + } + + /* デコード失敗テスト */ + { + struct SRLAEncoder *encoder; + struct SRLADecoder *decoder; + struct SRLAEncoderConfig encoder_config; + struct SRLADecoderConfig decoder_config; + struct SRLAEncodeParameter parameter; + struct SRLAHeader header, tmp_header; + uint8_t *data; + int32_t *input[SRLA_MAX_NUM_CHANNELS]; + int32_t *output[SRLA_MAX_NUM_CHANNELS]; + uint32_t ch, sufficient_size, output_size, decode_output_size, out_num_samples; + + SRLA_SetValidHeader(&header); + SRLAEncoder_SetValidConfig(&encoder_config); + SRLADecoder_SetValidConfig(&decoder_config); + + /* 十分なデータサイズ */ + sufficient_size = (2 * header.num_channels * header.num_samples_per_block * header.bits_per_sample) / 8; + + /* データ領域確保 */ + data = (uint8_t *)malloc(sufficient_size); + for (ch = 0; ch < header.num_channels; ch++) { + input[ch] = (int32_t *)malloc(sizeof(int32_t) * header.num_samples_per_block); + output[ch] = (int32_t *)malloc(sizeof(int32_t) * header.num_samples_per_block); + } + + /* エンコーダデコーダ作成 */ + encoder = SRLAEncoder_Create(&encoder_config, NULL, 0); + decoder = SRLADecoder_Create(&decoder_config, NULL, 0); + ASSERT_TRUE(encoder != NULL); + ASSERT_TRUE(decoder != NULL); + + /* 入力に無音セット */ + for (ch = 0; ch < header.num_channels; ch++) { + memset(input[ch], 0, sizeof(int32_t) * header.num_samples_per_block); + } + + /* ヘッダを元にパラメータを設定 */ + SRLAEncoder_ConvertHeaderToParameter(&header, ¶meter); + + /* 入力データをエンコード */ + EXPECT_EQ(SRLA_APIRESULT_OK, SRLAEncoder_SetEncodeParameter(encoder, ¶meter)); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLAEncoder_EncodeWhole(encoder, input, header.num_samples_per_block, data, sufficient_size, &output_size)); + + /* エンコードデータを簡易チェック */ + EXPECT_TRUE(output_size > SRLA_HEADER_SIZE); + EXPECT_TRUE(output_size < sufficient_size); + + /* ヘッダデコード */ + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_DecodeHeader(data, output_size, &tmp_header)); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLADecoder_SetHeader(decoder, &tmp_header)); + + /* 不正な引数 */ + EXPECT_EQ(SRLA_APIRESULT_INVALID_ARGUMENT, + SRLADecoder_DecodeBlock(NULL, data, output_size, output, header.num_channels, tmp_header.num_samples_per_block, &decode_output_size, &out_num_samples)); + EXPECT_EQ(SRLA_APIRESULT_INVALID_ARGUMENT, + SRLADecoder_DecodeBlock(decoder, NULL, output_size, output, header.num_channels, tmp_header.num_samples_per_block, &decode_output_size, &out_num_samples)); + EXPECT_EQ(SRLA_APIRESULT_INVALID_ARGUMENT, + SRLADecoder_DecodeBlock(decoder, data, output_size, NULL, header.num_channels, tmp_header.num_samples_per_block, &decode_output_size, &out_num_samples)); + EXPECT_EQ(SRLA_APIRESULT_INVALID_ARGUMENT, + SRLADecoder_DecodeBlock(decoder, data, output_size, output, header.num_channels, tmp_header.num_samples_per_block, NULL, &out_num_samples)); + EXPECT_EQ(SRLA_APIRESULT_INVALID_ARGUMENT, + SRLADecoder_DecodeBlock(decoder, data, output_size, output, header.num_channels, tmp_header.num_samples_per_block, &decode_output_size, NULL)); + + /* データサイズ不足 */ + EXPECT_EQ(SRLA_APIRESULT_INSUFFICIENT_DATA, + SRLADecoder_DecodeBlock(decoder, data + SRLA_HEADER_SIZE, output_size - SRLA_HEADER_SIZE - 1, + output, header.num_channels, tmp_header.num_samples_per_block, &decode_output_size, &out_num_samples)); + + /* データを一部破壊した場合にエラーを返すか */ + + /* 同期コード(データ先頭16bit)破壊 */ + EXPECT_EQ(SRLA_APIRESULT_OK, SRLAEncoder_EncodeWhole(encoder, input, header.num_samples_per_block, data, sufficient_size, &output_size)); + data[SRLA_HEADER_SIZE] ^= 0xFF; + EXPECT_EQ(SRLA_APIRESULT_INVALID_FORMAT, + SRLADecoder_DecodeBlock(decoder, data + SRLA_HEADER_SIZE, output_size - SRLA_HEADER_SIZE, + output, header.num_channels, tmp_header.num_samples_per_block, &decode_output_size, &out_num_samples)); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLAEncoder_EncodeWhole(encoder, input, header.num_samples_per_block, data, sufficient_size, &output_size)); + data[SRLA_HEADER_SIZE + 1] ^= 0xFF; + EXPECT_EQ(SRLA_APIRESULT_INVALID_FORMAT, + SRLADecoder_DecodeBlock(decoder, data + SRLA_HEADER_SIZE, output_size - SRLA_HEADER_SIZE, + output, header.num_channels, tmp_header.num_samples_per_block, &decode_output_size, &out_num_samples)); + /* ブロックデータタイプ不正: データ破損検知 */ + EXPECT_EQ(SRLA_APIRESULT_OK, SRLAEncoder_EncodeWhole(encoder, input, header.num_samples_per_block, data, sufficient_size, &output_size)); + data[SRLA_HEADER_SIZE + 8] = 0xC0; + EXPECT_EQ(SRLA_APIRESULT_DETECT_DATA_CORRUPTION, + SRLADecoder_DecodeBlock(decoder, data + SRLA_HEADER_SIZE, output_size - SRLA_HEADER_SIZE, + output, header.num_channels, tmp_header.num_samples_per_block, &decode_output_size, &out_num_samples)); + /* ブロックチャンネルあたりサンプル数不正: データ破損検知 */ + EXPECT_EQ(SRLA_APIRESULT_OK, SRLAEncoder_EncodeWhole(encoder, input, header.num_samples_per_block, data, sufficient_size, &output_size)); + data[SRLA_HEADER_SIZE + 9] ^= 0xFF; + EXPECT_EQ(SRLA_APIRESULT_DETECT_DATA_CORRUPTION, + SRLADecoder_DecodeBlock(decoder, data + SRLA_HEADER_SIZE, output_size - SRLA_HEADER_SIZE, + output, header.num_channels, tmp_header.num_samples_per_block, &decode_output_size, &out_num_samples)); + /* データの末尾1byteがビット反転: データ破損検知 */ + EXPECT_EQ(SRLA_APIRESULT_OK, SRLAEncoder_EncodeWhole(encoder, input, header.num_samples_per_block, data, sufficient_size, &output_size)); + data[output_size - 1] ^= 0xEF; /* note: Fletcherは0xFFのビット反転の破損を検知できない(mod 255の都合上) */ + EXPECT_EQ(SRLA_APIRESULT_DETECT_DATA_CORRUPTION, + SRLADecoder_DecodeBlock(decoder, data + SRLA_HEADER_SIZE, output_size - SRLA_HEADER_SIZE, + output, header.num_channels, tmp_header.num_samples_per_block, &decode_output_size, &out_num_samples)); + + /* 領域の開放 */ + for (ch = 0; ch < header.num_channels; ch++) { + free(output[ch]); + free(input[ch]); + } + free(data); + SRLADecoder_Destroy(decoder); + SRLAEncoder_Destroy(encoder); + } +} diff --git a/test/srla_decoder/srla_lpc_synthesize_test.cpp b/test/srla_decoder/srla_lpc_synthesize_test.cpp new file mode 100644 index 0000000..5342ca7 --- /dev/null +++ b/test/srla_decoder/srla_lpc_synthesize_test.cpp @@ -0,0 +1,4 @@ +/* テスト対象のモジュール */ +extern "C" { +#include "../../libs/srla_decoder/src/srla_lpc_synthesize.c" +} diff --git a/test/srla_encode_decode/CMakeLists.txt b/test/srla_encode_decode/CMakeLists.txt new file mode 100644 index 0000000..5c8da6e --- /dev/null +++ b/test/srla_encode_decode/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# テスト名 +set(TEST_NAME srla_encode_decode_test) + +# 実行形式ファイル +add_executable(${TEST_NAME} + main.cpp + ) + +# インクルードディレクトリ +include_directories(${PROJECT_ROOT_PATH}/include) + +# リンクするライブラリ +target_link_libraries(${TEST_NAME} gtest gtest_main srla_encoder srla_decoder srla_coder srla_internal byte_array bit_stream lpc) +if (NOT MSVC) +target_link_libraries(${TEST_NAME} pthread) +endif() + +# コンパイルオプション +set_target_properties(${TEST_NAME} + PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) + +add_test( + NAME srla_encode_decode + COMMAND $ + ) + +# run with: ctest -L lib +set_property( + TEST srla_encode_decode + PROPERTY LABELS lib srla_encode_decode + ) diff --git a/test/srla_encode_decode/main.cpp b/test/srla_encode_decode/main.cpp new file mode 100644 index 0000000..ae115e7 --- /dev/null +++ b/test/srla_encode_decode/main.cpp @@ -0,0 +1,532 @@ +#include +#include +#include + +#include + +#include "srla_encoder.h" +#include "srla_decoder.h" +#include "srla_utility.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* 様々な波形がエンコード -> デコードが元に戻るかを確認するテスト */ + +/* 波形生成関数 */ +typedef void (*GenerateWaveFunction)(double **data, uint32_t num_channels, uint32_t num_samples); + +/* テストケース */ +struct EncodeDecodeTestCase { + struct SRLAEncodeParameter encode_parameter; /* エンコードパラメータ */ + uint32_t offset_lshift; /* オフセット分の左シフト */ + uint32_t num_samples; /* サンプル数 */ + GenerateWaveFunction gen_wave_func; /* 波形生成関数 */ +}; + +/* 無音の生成 */ +static void SRLAEncodeDecodeTest_GenerateSilence(double **data, uint32_t num_channels, uint32_t num_samples); +/* サイン波の生成 */ +static void SRLAEncodeDecodeTest_GenerateSinWave(double **data, uint32_t num_channels, uint32_t num_samples); +/* サイン波(チャンネルごとに逆相)の部 */ +static void SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave(double **data, uint32_t num_channels, uint32_t num_samples); +/* 白色雑音の生成 */ +static void SRLAEncodeDecodeTest_GenerateWhiteNoise(double **data, uint32_t num_channels, uint32_t num_samples); +/* チャープ信号の生成 */ +static void SRLAEncodeDecodeTest_GenerateChirp(double **data, uint32_t num_channels, uint32_t num_samples); +/* 正定数信号の生成 */ +static void SRLAEncodeDecodeTest_GeneratePositiveConstant(double **data, uint32_t num_channels, uint32_t num_samples); +/* 負定数信号の生成 */ +static void SRLAEncodeDecodeTest_GenerateNegativeConstant(double **data, uint32_t num_channels, uint32_t num_samples); +/* ナイキスト周期の振動の生成 */ +static void SRLAEncodeDecodeTest_GenerateNyquistOsc(double **data, uint32_t num_channels, uint32_t num_samples); +/* ガウス雑音の生成 */ +static void SRLAEncodeDecodeTest_GenerateGaussNoise(double **data, uint32_t num_channels, uint32_t num_samples); + +/* 無音の生成 */ +static void SRLAEncodeDecodeTest_GenerateSilence( + double **data, uint32_t num_channels, uint32_t num_samples) +{ + uint32_t smpl, ch; + + assert(data != NULL); + + for (ch = 0; ch < num_channels; ch++) { + for (smpl = 0; smpl < num_samples; smpl++) { + data[ch][smpl] = 0.0f; + } + } +} + +/* サイン波の生成 */ +static void SRLAEncodeDecodeTest_GenerateSinWave( + double **data, uint32_t num_channels, uint32_t num_samples) +{ + uint32_t smpl, ch; + + assert(data != NULL); + + for (ch = 0; ch < num_channels; ch++) { + for (smpl = 0; smpl < num_samples; smpl++) { + data[ch][smpl] = sin(440.0f * 2 * M_PI * smpl / 44100.0f); + } + } +} + +/* サイン波(チャンネルごとに逆相)の部 */ +static void SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave( + double **data, uint32_t num_channels, uint32_t num_samples) +{ + uint32_t smpl, ch; + + assert(data != NULL); + + for (ch = 0; ch < num_channels; ch++) { + for (smpl = 0; smpl < num_samples; smpl++) { + data[ch][smpl] = pow(-1, ch) * sin(440.0f * 2 * M_PI * smpl / 44100.0f); + } + } +} + +/* 白色雑音の生成 */ +static void SRLAEncodeDecodeTest_GenerateWhiteNoise( + double **data, uint32_t num_channels, uint32_t num_samples) +{ + uint32_t smpl, ch; + + assert(data != NULL); + + for (ch = 0; ch < num_channels; ch++) { + for (smpl = 0; smpl < num_samples; smpl++) { + data[ch][smpl] = 2.0f * ((double)rand() / RAND_MAX - 0.5f); + } + } +} + +/* チャープ信号の生成 */ +static void SRLAEncodeDecodeTest_GenerateChirp( + double **data, uint32_t num_channels, uint32_t num_samples) +{ + uint32_t smpl, ch; + double period; + + assert(data != NULL); + + for (ch = 0; ch < num_channels; ch++) { + for (smpl = 0; smpl < num_samples; smpl++) { + period = num_samples - smpl; + data[ch][smpl] = sin((2.0f * M_PI * smpl) / period); + } + } +} + +/* 正定数信号の生成 */ +static void SRLAEncodeDecodeTest_GeneratePositiveConstant( + double **data, uint32_t num_channels, uint32_t num_samples) +{ + uint32_t smpl, ch; + + assert(data != NULL); + + for (ch = 0; ch < num_channels; ch++) { + for (smpl = 0; smpl < num_samples; smpl++) { + data[ch][smpl] = 1.0f; + } + } +} + +/* 負定数信号の生成 */ +static void SRLAEncodeDecodeTest_GenerateNegativeConstant( + double **data, uint32_t num_channels, uint32_t num_samples) +{ + uint32_t smpl, ch; + + assert(data != NULL); + + for (ch = 0; ch < num_channels; ch++) { + for (smpl = 0; smpl < num_samples; smpl++) { + data[ch][smpl] = -1.0f; + } + } +} + +/* ナイキスト周期の振動の生成 */ +static void SRLAEncodeDecodeTest_GenerateNyquistOsc( + double **data, uint32_t num_channels, uint32_t num_samples) +{ + uint32_t smpl, ch; + + assert(data != NULL); + + for (ch = 0; ch < num_channels; ch++) { + for (smpl = 0; smpl < num_samples; smpl++) { + data[ch][smpl] = (smpl % 2 == 0) ? 1.0f : -1.0f; + } + } +} + +/* ガウス雑音の生成 */ +static void SRLAEncodeDecodeTest_GenerateGaussNoise( + double **data, uint32_t num_channels, uint32_t num_samples) +{ + uint32_t smpl, ch; + double x, y; + + assert(data != NULL); + + for (ch = 0; ch < num_channels; ch++) { + for (smpl = 0; smpl < num_samples; smpl++) { + /* ボックス-ミューラー法 */ + x = (double)rand() / RAND_MAX; + y = (double)rand() / RAND_MAX; + /* 分散は0.1f */ + data[ch][smpl] = 0.25f * sqrt(-2.0f * log(x)) * cos(2.0f * M_PI * y); + data[ch][smpl] = (data[ch][smpl] >= 1.0f) ? 1.0f : data[ch][smpl]; + data[ch][smpl] = (data[ch][smpl] <= -1.0f) ? -1.0f : data[ch][smpl]; + } + } +} + +/* double入力データの固定小数化 */ +static void SRLAEncodeDecodeTest_InputDoubleToInputFixedFloat( + const struct SRLAEncodeParameter *param, uint32_t offset_lshift, + double **input_double, uint32_t num_channels, uint32_t num_samples, int32_t **input_int32) +{ + uint32_t ch, smpl; + + assert((input_double != NULL) && (input_int32 != NULL)); + + for (ch = 0; ch < num_channels; ch++) { + for (smpl = 0; smpl < num_samples; smpl++) { + assert(fabs(input_double[ch][smpl]) <= 1.0f); + /* まずはビット幅のデータを作る */ + input_int32[ch][smpl] + = (int32_t)SRLAUtility_Round(input_double[ch][smpl] * pow(2, param->bits_per_sample - 1)); + /* クリップ */ + if (input_int32[ch][smpl] >= (1L << (param->bits_per_sample - 1))) { + input_int32[ch][smpl] = (1L << (param->bits_per_sample - 1)) - 1; + } + /* 左シフト量だけ下位ビットのデータを消す */ + input_int32[ch][smpl] &= ~((1UL << offset_lshift) - 1); + } + } +} + +/* 単一のテストケースを実行 */ +static int32_t SRLAEncodeDecodeTest_ExecuteTestCase(const struct EncodeDecodeTestCase* test_case) +{ + int32_t ret; + uint32_t smpl, ch; + uint32_t num_samples, num_channels, data_size; + uint32_t output_size; + double **input_double; + int32_t **input; + uint8_t *data; + int32_t **output; + SRLAApiResult api_ret; + + struct SRLAEncoderConfig encoder_config; + struct SRLADecoderConfig decoder_config; + struct SRLAEncoder *encoder; + struct SRLADecoder *decoder; + + assert(test_case != NULL); + assert(test_case->num_samples <= (1UL << 14)); /* 長過ぎる入力はNG */ + + num_samples = test_case->num_samples; + num_channels = test_case->encode_parameter.num_channels; + /* 十分なデータサイズを用意(入力データPCMの2倍) */ + data_size = SRLA_HEADER_SIZE + (2 * num_channels * num_samples * test_case->encode_parameter.bits_per_sample) / 8; + + /* エンコード・デコードコンフィグ作成 */ + /* FIXME: 仮値 */ + encoder_config.max_num_channels = num_channels; + encoder_config.max_num_samples_per_block = test_case->encode_parameter.num_samples_per_block; + encoder_config.max_num_parameters = 32; + decoder_config.max_num_channels = num_channels; + decoder_config.max_num_parameters = 32; + decoder_config.check_checksum = 1; + + /* 一時領域の割り当て */ + input_double = (double **)malloc(sizeof(double*) * num_channels); + input = (int32_t **)malloc(sizeof(int32_t*) * num_channels); + output = (int32_t **)malloc(sizeof(int32_t*) * num_channels); + data = (uint8_t *)malloc(data_size); + for (ch = 0; ch < num_channels; ch++) { + input_double[ch] = (double *)malloc(sizeof(double) * num_samples); + input[ch] = (int32_t *)malloc(sizeof(int32_t) * num_samples); + output[ch] = (int32_t *)malloc(sizeof(int32_t) * num_samples); + } + + /* エンコード・デコードハンドル作成 */ + encoder = SRLAEncoder_Create(&encoder_config, NULL, 0); + decoder = SRLADecoder_Create(&decoder_config, NULL, 0); + if ((encoder == NULL) || (decoder == NULL)) { + ret = 1; + goto EXIT; + } + + /* 波形生成 */ + test_case->gen_wave_func(input_double, num_channels, num_samples); + + /* 固定小数化 */ + SRLAEncodeDecodeTest_InputDoubleToInputFixedFloat( + &test_case->encode_parameter, test_case->offset_lshift, input_double, num_channels, num_samples, input); + + /* 波形フォーマットと波形パラメータをセット */ + if ((api_ret = SRLAEncoder_SetEncodeParameter(encoder, &test_case->encode_parameter)) != SRLA_APIRESULT_OK) { + fprintf(stderr, "Failed to set encode parameter. ret:%d \n", api_ret); + ret = 2; + goto EXIT; + } + + /* エンコード */ + if ((api_ret = SRLAEncoder_EncodeWhole(encoder, + (const int32_t **)input, num_samples, data, data_size, &output_size)) != SRLA_APIRESULT_OK) { + fprintf(stderr, "Encode failed! ret:%d \n", api_ret); + ret = 3; + goto EXIT; + } + + /* デコード */ + if ((api_ret = SRLADecoder_DecodeWhole(decoder, data, output_size, output, num_channels, num_samples)) != SRLA_APIRESULT_OK) { + fprintf(stderr, "Decode failed! ret:%d \n", api_ret); + ret = 4; + goto EXIT; + } + + /* 一致確認 */ + for (ch = 0; ch < num_channels; ch++) { + for (smpl = 0; smpl < num_samples; smpl++) { + if (input[ch][smpl] != output[ch][smpl]) { + printf("%5d %12d vs %12d \n", smpl, input[ch][smpl], output[ch][smpl]); + ret = 5; + goto EXIT; + } + } + } + + /* ここまで来れば成功 */ + ret = 0; + +EXIT: + /* ハンドル開放 */ + SRLADecoder_Destroy(decoder); + SRLAEncoder_Destroy(encoder); + + /* 一時領域の開放 */ + for (ch = 0; ch < num_channels; ch++) { + free(input_double[ch]); + free(input[ch]); + free(output[ch]); + } + free(input_double); + free(input); + free(output); + free(data); + + return ret; +} + +/* インスタンス作成破棄テスト */ +TEST(SRLAEncodeDecodeTest, EncodeDecodeCheckTest) +{ + int32_t test_ret; + uint32_t test_no; + + /* テストケース配列 */ + static const struct EncodeDecodeTestCase test_case[] = { + /* 無音の部 */ + { { 1, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 1, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 1, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 2, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 2, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 2, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 8, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 8, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 8, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 1, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 1, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 1, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 2, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 2, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 2, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 8, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 8, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + { { 8, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSilence }, + /* サイン波の部 */ + { { 1, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 1, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 1, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 2, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 2, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 2, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 8, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 8, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 8, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 1, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 1, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 1, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 2, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 2, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 2, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 8, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 8, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + { { 8, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinWave }, + /* サイン波(チャンネルごとに逆相)の部 */ + { { 1, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 1, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 1, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 2, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 2, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 2, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 8, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 8, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 8, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 1, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 1, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 1, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 2, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 2, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 2, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 8, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 8, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + { { 8, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateSinChSignFlippedWave }, + /* 白色雑音の部 */ + { { 1, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 1, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 1, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 2, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 2, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 2, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 8, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 8, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 8, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 1, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 1, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 1, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 2, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 2, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 2, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 8, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 8, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + { { 8, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateWhiteNoise }, + /* チャープ信号の部 */ + { { 1, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 1, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 1, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 2, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 2, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 2, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 8, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 8, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 8, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 1, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 1, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 1, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 2, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 2, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 2, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 8, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 8, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + { { 8, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateChirp }, + /* 正定数信号の部 */ + { { 1, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 1, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 1, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 2, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 2, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 2, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 8, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 8, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 8, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 1, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 1, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 1, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 2, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 2, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 2, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 8, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 8, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + { { 8, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GeneratePositiveConstant }, + /* 負定数信号の部 */ + { { 1, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 1, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 1, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 2, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 2, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 2, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 8, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 8, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 8, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 1, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 1, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 1, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 2, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 2, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 2, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 8, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 8, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + { { 8, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNegativeConstant }, + /* ナイキスト周期振動信号の部 */ + { { 1, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 1, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 1, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 2, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 2, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 2, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 8, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 8, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 8, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 1, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 1, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 1, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 2, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 2, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 2, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 8, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 8, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + { { 8, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateNyquistOsc }, + /* ガウス雑音信号の部 */ + { { 1, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 1, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 1, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 2, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 2, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 2, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 8, 8, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 8, 16, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 8, 24, 8000, 1024, 0 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 1, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 1, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 1, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 2, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 2, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 2, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 8, 8, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 8, 16, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + { { 8, 24, 8000, 1024, SRLA_NUM_PARAMETER_PRESETS - 1 }, 0, 8192, SRLAEncodeDecodeTest_GenerateGaussNoise }, + }; + + /* テストケース数 */ + const uint32_t num_test_case = sizeof(test_case) / sizeof(test_case[0]); + + /* デバッグのしやすさのため、乱数シードを固定 */ + srand(0); + + for (test_no = 0; test_no < num_test_case; test_no++) { + test_ret = SRLAEncodeDecodeTest_ExecuteTestCase(&test_case[test_no]); + EXPECT_EQ(0, test_ret); + if (test_ret != 0) { + fprintf(stderr, "Encode / Decode Test Failed at case %d. ret:%d \n", test_no, test_ret); + } + } +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/srla_encoder/CMakeLists.txt b/test/srla_encoder/CMakeLists.txt new file mode 100644 index 0000000..9c244ee --- /dev/null +++ b/test/srla_encoder/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# テスト名 +set(TEST_NAME srla_encoder_test) + +# 実行形式ファイル +add_executable(${TEST_NAME} + srla_encoder_test.cpp + srla_lpc_predict_test.cpp + main.cpp + ) + +# インクルードディレクトリ +include_directories(${PROJECT_ROOT_PATH}/libs/srla_encoder/include) + +# リンクするライブラリ +target_link_libraries(${TEST_NAME} gtest gtest_main byte_array bit_stream lpc srla_internal srla_coder) +if (NOT MSVC) +target_link_libraries(${TEST_NAME} pthread) +endif() + +# コンパイルオプション +set_target_properties(${TEST_NAME} + PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) + +add_test( + NAME srla_encoder + COMMAND $ + ) + +# run with: ctest -L lib +set_property( + TEST srla_encoder + PROPERTY LABELS lib srla_encoder + ) diff --git a/test/srla_encoder/main.cpp b/test/srla_encoder/main.cpp new file mode 100644 index 0000000..96d7200 --- /dev/null +++ b/test/srla_encoder/main.cpp @@ -0,0 +1,7 @@ +#include + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/srla_encoder/srla_encoder_test.cpp b/test/srla_encoder/srla_encoder_test.cpp new file mode 100644 index 0000000..b9e88ff --- /dev/null +++ b/test/srla_encoder/srla_encoder_test.cpp @@ -0,0 +1,430 @@ +#include +#include + +#include + +/* テスト対象のモジュール */ +extern "C" { +#include "../../libs/srla_encoder/src/srla_encoder.c" +} + +/* 有効なヘッダをセット */ +#define SRLA_SetValidHeader(p_header)\ + do {\ + struct SRLAHeader *header__p = p_header;\ + header__p->format_version = SRLA_FORMAT_VERSION;\ + header__p->codec_version = SRLA_CODEC_VERSION;\ + header__p->num_channels = 1;\ + header__p->sampling_rate = 44100;\ + header__p->bits_per_sample = 16;\ + header__p->num_samples = 1024;\ + header__p->num_samples_per_block = 32;\ + header__p->preset = 0;\ + } while (0); + +/* 有効なエンコードパラメータをセット */ +#define SRLAEncoder_SetValidEncodeParameter(p_parameter)\ + do {\ + struct SRLAEncodeParameter *param__p = p_parameter;\ + param__p->num_channels = 1;\ + param__p->bits_per_sample = 16;\ + param__p->sampling_rate = 44100;\ + param__p->num_samples_per_block = 1024;\ + param__p->preset = 0;\ + } while (0); + +/* 有効なコンフィグをセット */ +#define SRLAEncoder_SetValidConfig(p_config)\ + do {\ + struct SRLAEncoderConfig *config__p = p_config;\ + config__p->max_num_channels = 8;\ + config__p->max_num_samples_per_block = 4096;\ + config__p->max_num_parameters = 32;\ + } while (0); + +/* ヘッダエンコードテスト */ +TEST(SRLAEncoderTest, EncodeHeaderTest) +{ + /* ヘッダエンコード成功ケース */ + { + struct SRLAHeader header; + uint8_t data[SRLA_HEADER_SIZE] = { 0, }; + + SRLA_SetValidHeader(&header); + EXPECT_EQ(SRLA_APIRESULT_OK, SRLAEncoder_EncodeHeader(&header, data, sizeof(data))); + + /* 簡易チェック */ + EXPECT_EQ('S', data[0]); + EXPECT_EQ('F', data[1]); + EXPECT_EQ('L', data[2]); + EXPECT_EQ('A', data[3]); + } + + /* ヘッダエンコード失敗ケース */ + { + struct SRLAHeader header; + uint8_t data[SRLA_HEADER_SIZE] = { 0, }; + + /* 引数が不正 */ + SRLA_SetValidHeader(&header); + EXPECT_EQ(SRLA_APIRESULT_INVALID_ARGUMENT, SRLAEncoder_EncodeHeader(NULL, data, sizeof(data))); + EXPECT_EQ(SRLA_APIRESULT_INVALID_ARGUMENT, SRLAEncoder_EncodeHeader(&header, NULL, sizeof(data))); + + /* データサイズ不足 */ + SRLA_SetValidHeader(&header); + EXPECT_EQ(SRLA_APIRESULT_INSUFFICIENT_BUFFER, SRLAEncoder_EncodeHeader(&header, data, sizeof(data) - 1)); + EXPECT_EQ(SRLA_APIRESULT_INSUFFICIENT_BUFFER, SRLAEncoder_EncodeHeader(&header, data, SRLA_HEADER_SIZE - 1)); + + /* 異常なチャンネル数 */ + SRLA_SetValidHeader(&header); + header.num_channels = 0; + EXPECT_EQ(SRLA_APIRESULT_INVALID_FORMAT, SRLAEncoder_EncodeHeader(&header, data, sizeof(data))); + + /* 異常なサンプル数 */ + SRLA_SetValidHeader(&header); + header.num_samples = 0; + EXPECT_EQ(SRLA_APIRESULT_INVALID_FORMAT, SRLAEncoder_EncodeHeader(&header, data, sizeof(data))); + + /* 異常なサンプリングレート */ + SRLA_SetValidHeader(&header); + header.sampling_rate = 0; + EXPECT_EQ(SRLA_APIRESULT_INVALID_FORMAT, SRLAEncoder_EncodeHeader(&header, data, sizeof(data))); + + /* 異常なビット深度 */ + SRLA_SetValidHeader(&header); + header.bits_per_sample = 0; + EXPECT_EQ(SRLA_APIRESULT_INVALID_FORMAT, SRLAEncoder_EncodeHeader(&header, data, sizeof(data))); + + /* 異常なブロックあたりサンプル数 */ + SRLA_SetValidHeader(&header); + header.num_samples_per_block = 0; + EXPECT_EQ(SRLA_APIRESULT_INVALID_FORMAT, SRLAEncoder_EncodeHeader(&header, data, sizeof(data))); + + /* 異常なプリセット */ + SRLA_SetValidHeader(&header); + header.preset = SRLA_NUM_PARAMETER_PRESETS; + EXPECT_EQ(SRLA_APIRESULT_INVALID_FORMAT, SRLAEncoder_EncodeHeader(&header, data, sizeof(data))); + } + +} + +/* エンコードハンドル作成破棄テスト */ +TEST(SRLAEncoderTest, CreateDestroyHandleTest) +{ + /* ワークサイズ計算テスト */ + { + int32_t work_size; + struct SRLAEncoderConfig config; + + /* 最低限構造体本体よりは大きいはず */ + SRLAEncoder_SetValidConfig(&config); + work_size = SRLAEncoder_CalculateWorkSize(&config); + ASSERT_TRUE(work_size > sizeof(struct SRLAEncoder)); + + /* 不正な引数 */ + EXPECT_TRUE(SRLAEncoder_CalculateWorkSize(NULL) < 0); + + /* 不正なコンフィグ */ + SRLAEncoder_SetValidConfig(&config); + config.max_num_channels = 0; + EXPECT_TRUE(SRLAEncoder_CalculateWorkSize(&config) < 0); + + SRLAEncoder_SetValidConfig(&config); + config.max_num_samples_per_block = 0; + EXPECT_TRUE(SRLAEncoder_CalculateWorkSize(&config) < 0); + + SRLAEncoder_SetValidConfig(&config); + config.max_num_parameters = 0; + EXPECT_TRUE(SRLAEncoder_CalculateWorkSize(&config) < 0); + } + + /* ワーク領域渡しによるハンドル作成(成功例) */ + { + void *work; + int32_t work_size; + struct SRLAEncoder *encoder; + struct SRLAEncoderConfig config; + + SRLAEncoder_SetValidConfig(&config); + work_size = SRLAEncoder_CalculateWorkSize(&config); + work = malloc(work_size); + + encoder = SRLAEncoder_Create(&config, work, work_size); + ASSERT_TRUE(encoder != NULL); + EXPECT_TRUE(encoder->work == work); + EXPECT_EQ(encoder->set_parameter, 0); + EXPECT_EQ(encoder->alloced_by_own, 0); + EXPECT_TRUE(encoder->coder != NULL); + + SRLAEncoder_Destroy(encoder); + free(work); + } + + /* 自前確保によるハンドル作成(成功例) */ + { + struct SRLAEncoder *encoder; + struct SRLAEncoderConfig config; + + SRLAEncoder_SetValidConfig(&config); + + encoder = SRLAEncoder_Create(&config, NULL, 0); + ASSERT_TRUE(encoder != NULL); + EXPECT_TRUE(encoder->work != NULL); + EXPECT_EQ(encoder->set_parameter, 0); + EXPECT_EQ(encoder->alloced_by_own, 1); + EXPECT_TRUE(encoder->coder != NULL); + + SRLAEncoder_Destroy(encoder); + } + + /* ワーク領域渡しによるハンドル作成(失敗ケース) */ + { + void *work; + int32_t work_size; + struct SRLAEncoder *encoder; + struct SRLAEncoderConfig config; + + SRLAEncoder_SetValidConfig(&config); + work_size = SRLAEncoder_CalculateWorkSize(&config); + work = malloc(work_size); + + /* 引数が不正 */ + encoder = SRLAEncoder_Create(NULL, work, work_size); + EXPECT_TRUE(encoder == NULL); + encoder = SRLAEncoder_Create(&config, NULL, work_size); + EXPECT_TRUE(encoder == NULL); + encoder = SRLAEncoder_Create(&config, work, 0); + EXPECT_TRUE(encoder == NULL); + + /* ワークサイズ不足 */ + encoder = SRLAEncoder_Create(&config, work, work_size - 1); + EXPECT_TRUE(encoder == NULL); + + /* コンフィグが不正 */ + SRLAEncoder_SetValidConfig(&config); + config.max_num_channels = 0; + encoder = SRLAEncoder_Create(&config, work, work_size); + EXPECT_TRUE(encoder == NULL); + + SRLAEncoder_SetValidConfig(&config); + config.max_num_samples_per_block = 0; + encoder = SRLAEncoder_Create(&config, work, work_size); + EXPECT_TRUE(encoder == NULL); + + SRLAEncoder_SetValidConfig(&config); + config.max_num_parameters = 0; + encoder = SRLAEncoder_Create(&config, work, work_size); + EXPECT_TRUE(encoder == NULL); + + free(work); + } + + /* 自前確保によるハンドル作成(失敗ケース) */ + { + struct SRLAEncoder *encoder; + struct SRLAEncoderConfig config; + + SRLAEncoder_SetValidConfig(&config); + + /* 引数が不正 */ + encoder = SRLAEncoder_Create(NULL, NULL, 0); + EXPECT_TRUE(encoder == NULL); + + /* コンフィグが不正 */ + SRLAEncoder_SetValidConfig(&config); + config.max_num_channels = 0; + encoder = SRLAEncoder_Create(&config, NULL, 0); + EXPECT_TRUE(encoder == NULL); + + SRLAEncoder_SetValidConfig(&config); + config.max_num_samples_per_block = 0; + encoder = SRLAEncoder_Create(&config, NULL, 0); + EXPECT_TRUE(encoder == NULL); + + SRLAEncoder_SetValidConfig(&config); + config.max_num_parameters = 0; + encoder = SRLAEncoder_Create(&config, NULL, 0); + EXPECT_TRUE(encoder == NULL); + } +} + +/* 1ブロックエンコードテスト */ +TEST(SRLAEncoderTest, EncodeBlockTest) +{ + /* 無効な引数 */ + { + struct SRLAEncoder *encoder; + struct SRLAEncoderConfig config; + struct SRLAEncodeParameter parameter; + int32_t *input[SRLA_MAX_NUM_CHANNELS]; + uint8_t *data; + uint32_t ch, sufficient_size, output_size, num_samples; + + SRLAEncoder_SetValidEncodeParameter(¶meter); + SRLAEncoder_SetValidConfig(&config); + + /* 十分なデータサイズ */ + sufficient_size = (2 * parameter.num_channels * parameter.num_samples_per_block * parameter.bits_per_sample) / 8; + + /* データ領域確保 */ + data = (uint8_t *)malloc(sufficient_size); + for (ch = 0; ch < parameter.num_channels; ch++) { + input[ch] = (int32_t *)malloc(sizeof(int32_t) * parameter.num_samples_per_block); + } + + /* エンコーダ作成 */ + encoder = SRLAEncoder_Create(&config, NULL, 0); + ASSERT_TRUE(encoder != NULL); + + /* 無効な引数を渡す */ + EXPECT_EQ( + SRLA_APIRESULT_INVALID_ARGUMENT, + SRLAEncoder_EncodeBlock(NULL, input, parameter.num_samples_per_block, + data, sufficient_size, &output_size)); + EXPECT_EQ( + SRLA_APIRESULT_INVALID_ARGUMENT, + SRLAEncoder_EncodeBlock(encoder, NULL, parameter.num_samples_per_block, + data, sufficient_size, &output_size)); + EXPECT_EQ( + SRLA_APIRESULT_INVALID_ARGUMENT, + SRLAEncoder_EncodeBlock(encoder, input, 0, + data, sufficient_size, &output_size)); + EXPECT_EQ( + SRLA_APIRESULT_INVALID_ARGUMENT, + SRLAEncoder_EncodeBlock(encoder, input, parameter.num_samples_per_block, + NULL, sufficient_size, &output_size)); + EXPECT_EQ( + SRLA_APIRESULT_INVALID_ARGUMENT, + SRLAEncoder_EncodeBlock(encoder, input, parameter.num_samples_per_block, + data, 0, &output_size)); + EXPECT_EQ( + SRLA_APIRESULT_INVALID_ARGUMENT, + SRLAEncoder_EncodeBlock(encoder, input, parameter.num_samples_per_block, + data, sufficient_size, NULL)); + + /* 領域の開放 */ + for (ch = 0; ch < parameter.num_channels; ch++) { + free(input[ch]); + } + free(data); + SRLAEncoder_Destroy(encoder); + } + + /* パラメータ未セットでエンコード */ + { + struct SRLAEncoder *encoder; + struct SRLAEncoderConfig config; + struct SRLAEncodeParameter parameter; + int32_t *input[SRLA_MAX_NUM_CHANNELS]; + uint8_t *data; + uint32_t ch, sufficient_size, output_size, num_samples; + + SRLAEncoder_SetValidEncodeParameter(¶meter); + SRLAEncoder_SetValidConfig(&config); + + /* 十分なデータサイズ */ + sufficient_size = (2 * parameter.num_channels * parameter.num_samples_per_block * parameter.bits_per_sample) / 8; + + /* データ領域確保 */ + data = (uint8_t *)malloc(sufficient_size); + for (ch = 0; ch < parameter.num_channels; ch++) { + input[ch] = (int32_t *)malloc(sizeof(int32_t) * parameter.num_samples_per_block); + /* 無音セット */ + memset(input[ch], 0, sizeof(int32_t) * parameter.num_samples_per_block); + } + + /* エンコーダ作成 */ + encoder = SRLAEncoder_Create(&config, NULL, 0); + ASSERT_TRUE(encoder != NULL); + + /* パラメータセット前にエンコード: エラー */ + EXPECT_EQ( + SRLA_APIRESULT_PARAMETER_NOT_SET, + SRLAEncoder_EncodeBlock(encoder, input, parameter.num_samples_per_block, + data, sufficient_size, &output_size)); + + /* パラメータ設定 */ + EXPECT_EQ( + SRLA_APIRESULT_OK, + SRLAEncoder_SetEncodeParameter(encoder, ¶meter)); + + /* 1ブロックエンコード */ + EXPECT_EQ( + SRLA_APIRESULT_OK, + SRLAEncoder_EncodeBlock(encoder, input, parameter.num_samples_per_block, + data, sufficient_size, &output_size)); + + /* 領域の開放 */ + for (ch = 0; ch < parameter.num_channels; ch++) { + free(input[ch]); + } + free(data); + SRLAEncoder_Destroy(encoder); + } + + /* 無音エンコード */ + { + struct SRLAEncoder *encoder; + struct SRLAEncoderConfig config; + struct SRLAEncodeParameter parameter; + struct BitStream stream; + int32_t *input[SRLA_MAX_NUM_CHANNELS]; + uint8_t *data; + uint32_t ch, sufficient_size, output_size, num_samples; + uint32_t bitbuf; + + SRLAEncoder_SetValidEncodeParameter(¶meter); + SRLAEncoder_SetValidConfig(&config); + + /* 十分なデータサイズ */ + sufficient_size = (2 * parameter.num_channels * parameter.num_samples_per_block * parameter.bits_per_sample) / 8; + + /* データ領域確保 */ + data = (uint8_t *)malloc(sufficient_size); + for (ch = 0; ch < parameter.num_channels; ch++) { + input[ch] = (int32_t *)malloc(sizeof(int32_t) * parameter.num_samples_per_block); + /* 無音セット */ + memset(input[ch], 0, sizeof(int32_t) * parameter.num_samples_per_block); + } + + /* エンコーダ作成 */ + encoder = SRLAEncoder_Create(&config, NULL, 0); + ASSERT_TRUE(encoder != NULL); + + /* パラメータ設定 */ + EXPECT_EQ( + SRLA_APIRESULT_OK, + SRLAEncoder_SetEncodeParameter(encoder, ¶meter)); + + /* 1ブロックエンコード */ + EXPECT_EQ( + SRLA_APIRESULT_OK, + SRLAEncoder_EncodeBlock(encoder, input, parameter.num_samples_per_block, + data, sufficient_size, &output_size)); + + /* ブロック先頭の同期コードがあるので2バイトよりは大きいはず */ + EXPECT_TRUE(output_size > 2); + + /* 内容の確認 */ + BitReader_Open(&stream, data, output_size); + /* 同期コード */ + BitReader_GetBits(&stream, &bitbuf, 16); + EXPECT_EQ(SRLA_BLOCK_SYNC_CODE, bitbuf); + /* ブロックデータタイプ */ + BitReader_GetBits(&stream, &bitbuf, 2); + EXPECT_TRUE((bitbuf == SRLA_BLOCK_DATA_TYPE_COMPRESSDATA) + || (bitbuf == SRLA_BLOCK_DATA_TYPE_SILENT) + || (bitbuf == SRLA_BLOCK_DATA_TYPE_RAWDATA)); + /* この後データがエンコードされているので、まだ終端ではないはず */ + BitStream_Tell(&stream, (int32_t *)&bitbuf); + EXPECT_TRUE(bitbuf < output_size); + BitStream_Close(&stream); + + /* 領域の開放 */ + for (ch = 0; ch < parameter.num_channels; ch++) { + free(input[ch]); + } + free(data); + SRLAEncoder_Destroy(encoder); + } +} diff --git a/test/srla_encoder/srla_lpc_predict_test.cpp b/test/srla_encoder/srla_lpc_predict_test.cpp new file mode 100644 index 0000000..49d9ec8 --- /dev/null +++ b/test/srla_encoder/srla_lpc_predict_test.cpp @@ -0,0 +1,4 @@ +/* テスト対象のモジュール */ +extern "C" { +#include "../../libs/srla_encoder/src/srla_lpc_predict.c" +} diff --git a/test/srla_internal/CMakeLists.txt b/test/srla_internal/CMakeLists.txt new file mode 100644 index 0000000..4ae09b8 --- /dev/null +++ b/test/srla_internal/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.15) + +set(PROJECT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# テスト名 +set(TEST_NAME srla_internal_test) + +# 実行形式ファイル +add_executable(${TEST_NAME} main.cpp) + +# インクルードディレクトリ +include_directories(${PROJECT_ROOT_PATH}/libs/srla_internal/include) + +# リンクするライブラリ +target_link_libraries(${TEST_NAME} gtest gtest_main) +if (NOT MSVC) +target_link_libraries(${TEST_NAME} pthread) +endif() + +# コンパイルオプション +set_target_properties(${TEST_NAME} + PROPERTIES + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" + ) + +# 実行パスをtmp以下に +add_test( + NAME srla_internal + WORKING_DIRECTORY $/tmp + COMMAND $ + ) + +# run with: ctest -L lib +set_property( + TEST srla_internal + PROPERTY LABELS lib srla_internal + ) + +# ビルド後にテストリソースを持ってくる +add_custom_command( + TARGET ${TEST_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory $/tmp + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/PriChanIcon.png $/tmp + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/a.wav $/tmp + ) diff --git a/test/srla_internal/PriChanIcon.png b/test/srla_internal/PriChanIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..23786bc5483ba19922f0f520ad16dcb64292a622 GIT binary patch literal 544324 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

VmNwH3PgSi!_bKZ#)5 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 T;1L)T2`yn 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�}Vn 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

Xl2({!qh}&tyVbZ!MEqw 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%0AbJjD#R1cEH^8$J>a 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