From 29d57a89fb5fb55ada1cc8b3326bb1ad42b8b068 Mon Sep 17 00:00:00 2001 From: administrator <1297030928@qq.com> Date: Mon, 2 Aug 2021 07:08:47 -0700 Subject: [PATCH] [feat][assistant][I3TDRD]add new audio operator BandpassBiquad --- mindspore/ccsrc/minddata/dataset/api/audio.cc | 19 +++ .../dataset/audio/kernels/ir/bindings.cc | 12 ++ .../dataset/audio/ir/kernels/CMakeLists.txt | 1 + .../audio/ir/kernels/bandpass_biquad_ir.cc | 53 ++++++++ .../audio/ir/kernels/bandpass_biquad_ir.h | 59 +++++++++ .../dataset/audio/kernels/CMakeLists.txt | 4 +- .../audio/kernels/bandpass_biquad_op.cc | 60 +++++++++ .../audio/kernels/bandpass_biquad_op.h | 53 ++++++++ .../minddata/dataset/include/dataset/audio.h | 24 ++++ .../minddata/dataset/kernels/tensor_op.h | 1 + mindspore/dataset/audio/transforms.py | 32 ++++- mindspore/dataset/audio/validators.py | 22 ++++ mindspore/dataset/core/validator_helpers.py | 1 + .../ut/cpp/dataset/c_api_audio_a_to_q_test.cc | 68 +++++++++++ tests/ut/cpp/dataset/execute_test.cc | 38 ++++++ .../ut/python/dataset/test_bandpass_biquad.py | 114 ++++++++++++++++++ 16 files changed, 558 insertions(+), 3 deletions(-) mode change 100644 => 100755 mindspore/ccsrc/minddata/dataset/api/audio.cc mode change 100644 => 100755 mindspore/ccsrc/minddata/dataset/api/python/bindings/dataset/audio/kernels/ir/bindings.cc create mode 100755 mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandpass_biquad_ir.cc create mode 100755 mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandpass_biquad_ir.h create mode 100755 mindspore/ccsrc/minddata/dataset/audio/kernels/bandpass_biquad_op.cc create mode 100755 mindspore/ccsrc/minddata/dataset/audio/kernels/bandpass_biquad_op.h mode change 100644 => 100755 mindspore/ccsrc/minddata/dataset/include/dataset/audio.h mode change 100644 => 100755 mindspore/dataset/audio/transforms.py mode change 100644 => 100755 mindspore/dataset/audio/validators.py create mode 100644 tests/ut/python/dataset/test_bandpass_biquad.py diff --git a/mindspore/ccsrc/minddata/dataset/api/audio.cc b/mindspore/ccsrc/minddata/dataset/api/audio.cc old mode 100644 new mode 100755 index 1cdd4f84aab..8b29476c928 --- a/mindspore/ccsrc/minddata/dataset/api/audio.cc +++ b/mindspore/ccsrc/minddata/dataset/api/audio.cc @@ -18,6 +18,7 @@ #include "minddata/dataset/audio/ir/kernels/allpass_biquad_ir.h" #include "minddata/dataset/audio/ir/kernels/band_biquad_ir.h" +#include "minddata/dataset/audio/ir/kernels/bandpass_biquad_ir.h" namespace mindspore { namespace dataset { @@ -55,6 +56,24 @@ BandBiquad::BandBiquad(int32_t sample_rate, float central_freq, float Q, bool no std::shared_ptr BandBiquad::Parse() { return std::make_shared(data_->sample_rate_, data_->central_freq_, data_->Q_, data_->noise_); } + +// BandpassBiquad Transform Operation. +struct BandpassBiquad::Data { + Data(int32_t sample_rate, float central_freq, float Q, bool const_skirt_gain) + : sample_rate_(sample_rate), central_freq_(central_freq), Q_(Q), const_skirt_gain_(const_skirt_gain) {} + int32_t sample_rate_; + float central_freq_; + float Q_; + bool const_skirt_gain_; +}; + +BandpassBiquad::BandpassBiquad(int32_t sample_rate, float central_freq, float Q, bool const_skirt_gain) + : data_(std::make_shared(sample_rate, central_freq, Q, const_skirt_gain)) {} + +std::shared_ptr BandpassBiquad::Parse() { + return std::make_shared(data_->sample_rate_, data_->central_freq_, data_->Q_, + data_->const_skirt_gain_); +} } // namespace audio } // namespace dataset } // namespace mindspore diff --git a/mindspore/ccsrc/minddata/dataset/api/python/bindings/dataset/audio/kernels/ir/bindings.cc b/mindspore/ccsrc/minddata/dataset/api/python/bindings/dataset/audio/kernels/ir/bindings.cc old mode 100644 new mode 100755 index 9908d95d356..3a4890aec0b --- a/mindspore/ccsrc/minddata/dataset/api/python/bindings/dataset/audio/kernels/ir/bindings.cc +++ b/mindspore/ccsrc/minddata/dataset/api/python/bindings/dataset/audio/kernels/ir/bindings.cc @@ -19,6 +19,7 @@ #include "minddata/dataset/api/python/pybind_register.h" #include "minddata/dataset/audio/ir/kernels/allpass_biquad_ir.h" #include "minddata/dataset/audio/ir/kernels/band_biquad_ir.h" +#include "minddata/dataset/audio/ir/kernels/bandpass_biquad_ir.h" #include "minddata/dataset/include/dataset/transforms.h" namespace mindspore { @@ -44,5 +45,16 @@ PYBIND_REGISTER( return band_biquad; })); })); +PYBIND_REGISTER( + BandpassBiquadOperation, 1, ([](const py::module *m) { + (void)py::class_>( + *m, "BandpassBiquadOperation") + .def(py::init([](int32_t sample_rate, float central_freq, float Q, bool const_skirt_gain) { + auto bandpass_biquad = + std::make_shared(sample_rate, central_freq, Q, const_skirt_gain); + THROW_IF_ERROR(bandpass_biquad->ValidateParams()); + return bandpass_biquad; + })); + })); } // namespace dataset } // namespace mindspore diff --git a/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/CMakeLists.txt b/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/CMakeLists.txt index cb914381aae..fc3f6b58b07 100644 --- a/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/CMakeLists.txt +++ b/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/CMakeLists.txt @@ -4,4 +4,5 @@ set_property(SOURCE ${_CURRENT_SRC_FILES} PROPERTY COMPILE_DEFINITIONS SUBMODULE add_library(audio-ir-kernels OBJECT allpass_biquad_ir.cc band_biquad_ir.cc + bandpass_biquad_ir.cc ) diff --git a/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandpass_biquad_ir.cc b/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandpass_biquad_ir.cc new file mode 100755 index 00000000000..a335f6500fd --- /dev/null +++ b/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandpass_biquad_ir.cc @@ -0,0 +1,53 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "minddata/dataset/audio/ir/kernels/bandpass_biquad_ir.h" + +#include "minddata/dataset/audio/kernels/bandpass_biquad_op.h" + +#include "minddata/dataset/audio/ir/validators.h" + +namespace mindspore { +namespace dataset { +namespace audio { +// BandpassBiquadOperation +BandpassBiquadOperation::BandpassBiquadOperation(int32_t sample_rate, float central_freq, float Q, + bool const_skirt_gain) + : sample_rate_(sample_rate), central_freq_(central_freq), Q_(Q), const_skirt_gain_(const_skirt_gain) {} + +Status BandpassBiquadOperation::ValidateParams() { + RETURN_IF_NOT_OK(ValidateScalar("BandpassBiquad", "Q", Q_, {0, 1.0}, true, false)); + RETURN_IF_NOT_OK(CheckScalarNotZero("BandpassBiquad", "sample_rate", sample_rate_)); + return Status::OK(); +} +std::shared_ptr BandpassBiquadOperation::Build() { + std::shared_ptr tensor_op = + std::make_shared(sample_rate_, central_freq_, Q_, const_skirt_gain_); + return tensor_op; +} + +Status BandpassBiquadOperation::to_json(nlohmann::json *out_json) { + nlohmann::json args; + args["sample_rate"] = sample_rate_; + args["central_freq"] = central_freq_; + args["Q"] = Q_; + args["const_skirt_gain"] = const_skirt_gain_; + *out_json = args; + return Status::OK(); +} +} // namespace audio +} // namespace dataset +} // namespace mindspore diff --git a/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandpass_biquad_ir.h b/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandpass_biquad_ir.h new file mode 100755 index 00000000000..23cb220e9f1 --- /dev/null +++ b/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandpass_biquad_ir.h @@ -0,0 +1,59 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_IR_KERNELS_BANDPASS_BIQUAD_IR_H_ +#define MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_IR_KERNELS_BANDPASS_BIQUAD_IR_H_ + +#include +#include +#include +#include +#include "include/api/status.h" +#include "minddata/dataset/include/dataset/constants.h" +#include "minddata/dataset/include/dataset/transforms.h" +#include "minddata/dataset/kernels/ir/tensor_operation.h" + +namespace mindspore { +namespace dataset { + +namespace audio { +// Char arrays storing name of corresponding classes (in alphabetical order) +constexpr char kBandpassBiquadOperation[] = "BandpassBiquad"; + +class BandpassBiquadOperation : public TensorOperation { + public: + explicit BandpassBiquadOperation(int32_t sample_rate, float central_freq, float Q, bool const_skirt_gain); + + ~BandpassBiquadOperation() = default; + + std::shared_ptr Build() override; + + Status ValidateParams() override; + + std::string Name() const override { return kBandpassBiquadOperation; } + + Status to_json(nlohmann::json *out_json) override; + + private: + int32_t sample_rate_; + float central_freq_; + float Q_; + bool const_skirt_gain_; +}; +} // namespace audio +} // namespace dataset +} // namespace mindspore +#endif // MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_IR_KERNELS_BANDPASS_BIQUAD_IR_H_ diff --git a/mindspore/ccsrc/minddata/dataset/audio/kernels/CMakeLists.txt b/mindspore/ccsrc/minddata/dataset/audio/kernels/CMakeLists.txt index 09a18ab494b..5b39c43c2cb 100644 --- a/mindspore/ccsrc/minddata/dataset/audio/kernels/CMakeLists.txt +++ b/mindspore/ccsrc/minddata/dataset/audio/kernels/CMakeLists.txt @@ -4,5 +4,5 @@ set_property(SOURCE ${_CURRENT_SRC_FILES} PROPERTY COMPILE_DEFINITIONS SUBMODULE add_library(audio-kernels OBJECT allpass_biquad_op.cc band_biquad_op.cc - ) - + bandpass_biquad_op.cc + ) \ No newline at end of file diff --git a/mindspore/ccsrc/minddata/dataset/audio/kernels/bandpass_biquad_op.cc b/mindspore/ccsrc/minddata/dataset/audio/kernels/bandpass_biquad_op.cc new file mode 100755 index 00000000000..475485f0e1a --- /dev/null +++ b/mindspore/ccsrc/minddata/dataset/audio/kernels/bandpass_biquad_op.cc @@ -0,0 +1,60 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "minddata/dataset/audio/kernels/bandpass_biquad_op.h" + +#include "minddata/dataset/audio/kernels/audio_utils.h" +#include "minddata/dataset/util/status.h" + +namespace mindspore { +namespace dataset { + +Status BandpassBiquadOp::Compute(const std::shared_ptr &input, std::shared_ptr *output) { + IO_CHECK(input, output); + TensorShape input_shape = input->shape(); + CHECK_FAIL_RETURN_UNEXPECTED(input_shape.Size() > 0, "BandpassBiquad: inpute dimension should be greater than 0."); + // check input type, it should be DE_FLOAT32 or DE_FLOAT16 or DE_FLOAT64 + CHECK_FAIL_RETURN_UNEXPECTED(input->type() == DataType(DataType::DE_FLOAT32) || + input->type() == DataType(DataType::DE_FLOAT16) || + input->type() == DataType(DataType::DE_FLOAT64), + "BandpassBiquad: input type should be float, but got " + input->type().ToString()); + float w0 = 2 * PI * central_freq_ / sample_rate_; + float alpha = sin(w0) / 2 / Q_; + float temp; + if (const_skirt_gain_) { + temp = sin(w0) / 2; + } else { + temp = alpha; + } + + float b0 = temp; + float b1 = 0.0; + float b2 = -temp; + float a0 = 1 + alpha; + float a1 = (-2) * cos(w0); + float a2 = 1 - alpha; + + if (input->type() == DataType(DataType::DE_FLOAT32)) + return Biquad(input, output, static_cast(b0), static_cast(b1), static_cast(b2), + static_cast(a0), static_cast(a1), static_cast(a2)); + else if (input->type() == DataType(DataType::DE_FLOAT64)) + return Biquad(input, output, static_cast(b0), static_cast(b1), static_cast(b2), + static_cast(a0), static_cast(a1), static_cast(a2)); + else + return Biquad(input, output, static_cast(b0), static_cast(b1), static_cast(b2), + static_cast(a0), static_cast(a1), static_cast(a2)); +} +} // namespace dataset +} // namespace mindspore diff --git a/mindspore/ccsrc/minddata/dataset/audio/kernels/bandpass_biquad_op.h b/mindspore/ccsrc/minddata/dataset/audio/kernels/bandpass_biquad_op.h new file mode 100755 index 00000000000..0fb21441425 --- /dev/null +++ b/mindspore/ccsrc/minddata/dataset/audio/kernels/bandpass_biquad_op.h @@ -0,0 +1,53 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_KERNELS_BANDPASS_BIQUAD_OP_H_ +#define MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_KERNELS_BANDPASS_BIQUAD_OP_H_ + +#include +#include +#include + +#include "minddata/dataset/core/tensor.h" +#include "minddata/dataset/kernels/tensor_op.h" +#include "minddata/dataset/util/status.h" + +namespace mindspore { +namespace dataset { +class BandpassBiquadOp : public TensorOp { + public: + BandpassBiquadOp(int32_t sample_rate, float central_freq, float Q, bool const_skirt_gain) + : sample_rate_(sample_rate), central_freq_(central_freq), Q_(Q), const_skirt_gain_(const_skirt_gain) {} + + ~BandpassBiquadOp() override = default; + + void Print(std::ostream &out) const override { + out << Name() << ": sample_rate: " << sample_rate_ << ", central_freq: " << central_freq_ << ", Q: " << Q_ + << ", const_skirt_gain: " << const_skirt_gain_ << std::endl; + } + + Status Compute(const std::shared_ptr &input, std::shared_ptr *output) override; + + std::string Name() const override { return kBandpassBiquadOp; } + + private: + int32_t sample_rate_; + float central_freq_; + float Q_; + bool const_skirt_gain_; +}; +} // namespace dataset +} // namespace mindspore +#endif // MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_KERNELS_BANDPASS_BIQUAD_OP_H_ diff --git a/mindspore/ccsrc/minddata/dataset/include/dataset/audio.h b/mindspore/ccsrc/minddata/dataset/include/dataset/audio.h old mode 100644 new mode 100755 index 7401bc2258d..95d99399418 --- a/mindspore/ccsrc/minddata/dataset/include/dataset/audio.h +++ b/mindspore/ccsrc/minddata/dataset/include/dataset/audio.h @@ -78,6 +78,30 @@ class AllpassBiquad final : public TensorTransform { std::shared_ptr data_; }; +/// \brief Design two-pole band-pass filter. +class BandpassBiquad final : public TensorTransform { + public: + /// \brief Constructor. + /// \param[in] sample_rate Sampling rate of the waveform, e.g. 44100 (Hz). + /// \param[in] central_freq Central frequency (in Hz). + /// \param[in] Q Quality factor, https://en.wikipedia.org/wiki/Q_factor (Default: 0.707). + /// \param[in] const_skirt_gain, If ``True``, uses a constant skirt gain (peak gain = Q). If ``False``, uses a + /// constant 0dB peak gain. (Default: False). + explicit BandpassBiquad(int32_t sample_rate, float central_freq, float Q = 0.707, bool const_skirt_gain = false); + + /// \brief Destructor. + ~BandpassBiquad() = default; + + protected: + /// \brief Function to convert TensorTransform object into a TensorOperation object. + /// \return Shared pointer to TensorOperation object. + std::shared_ptr Parse() override; + + private: + struct Data; + std::shared_ptr data_; +}; + } // namespace audio } // namespace dataset } // namespace mindspore diff --git a/mindspore/ccsrc/minddata/dataset/kernels/tensor_op.h b/mindspore/ccsrc/minddata/dataset/kernels/tensor_op.h index 0f923a00a8e..cd45c71373f 100644 --- a/mindspore/ccsrc/minddata/dataset/kernels/tensor_op.h +++ b/mindspore/ccsrc/minddata/dataset/kernels/tensor_op.h @@ -139,6 +139,7 @@ constexpr char kSentencepieceTokenizerOp[] = "SentencepieceTokenizerOp"; // audio constexpr char kAllpassBiquadOp[] = "AllpassBiquadOp"; constexpr char kBandBiquadOp[] = "BandBiquadOp"; +constexpr char kBandpassBiquadOp[] = "BandpassBiquadOp"; // data constexpr char kConcatenateOp[] = "ConcatenateOp"; diff --git a/mindspore/dataset/audio/transforms.py b/mindspore/dataset/audio/transforms.py old mode 100644 new mode 100755 index 28f6db79811..6d141241d38 --- a/mindspore/dataset/audio/transforms.py +++ b/mindspore/dataset/audio/transforms.py @@ -20,7 +20,7 @@ to improve their training models. import mindspore._c_dataengine as cde import numpy as np from ..transforms.c_transforms import TensorOperation -from .validators import check_allpass_biquad, check_band_biquad +from .validators import check_allpass_biquad, check_band_biquad, check_bandpass_biquad class AudioTensorOperation(TensorOperation): @@ -102,3 +102,33 @@ class BandBiquad(AudioTensorOperation): def parse(self): return cde.BandBiquadOperation(self.sample_rate, self.central_freq, self.Q, self.noise) + + +class BandpassBiquad(TensorOperation): + """ + Design two-pole band-pass filter. Similar to SoX implementation. + + Args: + sample_rate (int): sampling rate of the waveform, e.g. 44100 (Hz) + central_freq (float): central frequency (in Hz) + Q (float, optional): https://en.wikipedia.org/wiki/Q_factor Range: (0,1] (Default=0.707). + const_skirt_gain (bool, optional) : If ``True``, uses a constant skirt gain (peak gain = Q). + If ``False``, uses a constant 0dB peak gain. (Default: ``False``) + + Examples: + >>> import mindspore.dataset.audio.transforms as audio + >>> import numpy as np + + >>> waveform = np.array([[2.716064453125e-03, 6.34765625e-03],[9.246826171875e-03, 1.0894775390625e-02]]) + >>> bandpass_biquad_op = audio.BandpassBiquad(44100, 200.0) + >>> waveform_filtered = bandpass_biquad_op(waveform) + """ + @check_bandpass_biquad + def __init__(self, sample_rate, central_freq, Q=0.707, const_skirt_gain=False): + self.sample_rate = sample_rate + self.central_freq = central_freq + self.Q = Q + self.const_skirt_gain = const_skirt_gain + + def parse(self): + return cde.BandpassBiquadOperation(self.sample_rate, self.central_freq, self.Q, self.const_skirt_gain) diff --git a/mindspore/dataset/audio/validators.py b/mindspore/dataset/audio/validators.py old mode 100644 new mode 100755 index ea005103c0b..b9de7858af7 --- a/mindspore/dataset/audio/validators.py +++ b/mindspore/dataset/audio/validators.py @@ -44,6 +44,11 @@ def check_biquad_noise(noise): type_check(noise, (bool,), "noise") +def check_biquad_const_skirt_gain(const_skirt_gain): + """Wrapper method to check the parameters of const_skirt_gain.""" + type_check(const_skirt_gain, (bool,), "const_skirt_gain") + + def check_band_biquad(method): """Wrapper method to check the parameters of BandBiquad.""" @@ -59,6 +64,7 @@ def check_band_biquad(method): return new_method + def check_allpass_biquad(method): """Wrapper method to check the parameters of CutMixBatch.""" @@ -72,3 +78,19 @@ def check_allpass_biquad(method): return method(self, *args, **kwargs) return new_method + + +def check_bandpass_biquad(method): + """Wrapper method to check the parameters of BandpassBiquad.""" + + @ wraps(method) + def new_method(self, *args, **kwargs): + [sample_rate, central_freq, Q, const_skirt_gain], _ = parse_user_args( + method, *args, **kwargs) + check_biquad_sample_rate(sample_rate) + check_biquad_central_freq(central_freq) + check_biquad_Q(Q) + check_biquad_const_skirt_gain(const_skirt_gain) + return method(self, *args, **kwargs) + + return new_method diff --git a/mindspore/dataset/core/validator_helpers.py b/mindspore/dataset/core/validator_helpers.py index cb5ecd5b59d..f230e8e43a1 100644 --- a/mindspore/dataset/core/validator_helpers.py +++ b/mindspore/dataset/core/validator_helpers.py @@ -682,3 +682,4 @@ def check_c_tensor_op(param, param_name): def replace_none(value, default): """ replaces None with a default value.""" return value if value is not None else default + \ No newline at end of file diff --git a/tests/ut/cpp/dataset/c_api_audio_a_to_q_test.cc b/tests/ut/cpp/dataset/c_api_audio_a_to_q_test.cc index fa532a1167b..537226b69e4 100644 --- a/tests/ut/cpp/dataset/c_api_audio_a_to_q_test.cc +++ b/tests/ut/cpp/dataset/c_api_audio_a_to_q_test.cc @@ -165,3 +165,71 @@ TEST_F(MindDataTestPipeline, Level0_TestAllpassBiquad002) { std::shared_ptr iter02 = ds02->CreateIterator(); EXPECT_EQ(iter02, nullptr); } + +TEST_F(MindDataTestPipeline, Level0_TestBandpassBiquad001) { + MS_LOG(INFO) << "Basic Function Test"; + // Original waveform + std::shared_ptr schema = Schema(); + ASSERT_OK(schema->add_column("inputData", mindspore::DataType::kNumberTypeFloat32, {2, 200})); + std::shared_ptr ds = RandomData(50, schema); + EXPECT_NE(ds, nullptr); + + ds = ds->SetNumWorkers(4); + EXPECT_NE(ds, nullptr); + + auto BandpassBiquadOp = audio::BandpassBiquad(44100, 200.0); + + ds = ds->Map({BandpassBiquadOp}); + EXPECT_NE(ds, nullptr); + + // Filtered waveform by bandpassbiquad + std::shared_ptr iter = ds->CreateIterator(); + EXPECT_NE(ds, nullptr); + + std::unordered_map row; + ASSERT_OK(iter->GetNextRow(&row)); + + std::vector expected = {2, 200}; + + int i = 0; + while (row.size() != 0) { + auto col = row["inputData"]; + ASSERT_EQ(col.Shape(), expected); + ASSERT_EQ(col.Shape().size(), 2); + ASSERT_EQ(col.DataType(), mindspore::DataType::kNumberTypeFloat32); + ASSERT_OK(iter->GetNextRow(&row)); + i++; + } + EXPECT_EQ(i, 50); + + iter->Stop(); +} + +TEST_F(MindDataTestPipeline, Level0_TestBandpassBiquad002) { + MS_LOG(INFO) << "Wrong Arg."; + std::shared_ptr schema = Schema(); + // Original waveform + ASSERT_OK(schema->add_column("inputData", mindspore::DataType::kNumberTypeFloat32, {2, 2})); + std::shared_ptr ds = RandomData(50, schema); + std::shared_ptr ds01; + std::shared_ptr ds02; + EXPECT_NE(ds, nullptr); + + // Check sample_rate + MS_LOG(INFO) << "sample_rate is zero."; + auto bandpass_biquad_op_01 = audio::BandpassBiquad(0, 200); + ds01 = ds->Map({bandpass_biquad_op_01}); + EXPECT_NE(ds01, nullptr); + + std::shared_ptr iter01 = ds01->CreateIterator(); + EXPECT_EQ(iter01, nullptr); + + // Check Q_ + MS_LOG(INFO) << "Q_ is zero."; + auto bandpass_biquad_op_02 = audio::BandpassBiquad(44100, 200, 0); + ds02 = ds->Map({bandpass_biquad_op_02}); + EXPECT_NE(ds02, nullptr); + + std::shared_ptr iter02 = ds02->CreateIterator(); + EXPECT_EQ(iter02, nullptr); +} diff --git a/tests/ut/cpp/dataset/execute_test.cc b/tests/ut/cpp/dataset/execute_test.cc index c961db7a690..7903588dffd 100644 --- a/tests/ut/cpp/dataset/execute_test.cc +++ b/tests/ut/cpp/dataset/execute_test.cc @@ -372,3 +372,41 @@ TEST_F(MindDataTestExecute, TestBandBiquadWithWrongArg) { Status s01 = Transform01(input_02, &input_02); EXPECT_FALSE(s01.IsOk()); } + +TEST_F(MindDataTestExecute, TestBandpassBiquadWithEager) { + MS_LOG(INFO) << "Basic Function Test With Eager."; + // Original waveform + std::vector labels = { + 2.716064453125000000e-03, 6.347656250000000000e-03, 9.246826171875000000e-03, 1.089477539062500000e-02, + 1.138305664062500000e-02, 1.156616210937500000e-02, 1.394653320312500000e-02, 1.550292968750000000e-02, + 1.614379882812500000e-02, 1.840209960937500000e-02, 1.718139648437500000e-02, 1.599121093750000000e-02, + 1.647949218750000000e-02, 1.510620117187500000e-02, 1.385498046875000000e-02, 1.345825195312500000e-02, + 1.419067382812500000e-02, 1.284790039062500000e-02, 1.052856445312500000e-02, 9.368896484375000000e-03}; + std::shared_ptr input; + ASSERT_OK(Tensor::CreateFromVector(labels, TensorShape({2, 10}), &input)); + auto input_02 = mindspore::MSTensor(std::make_shared(input)); + std::shared_ptr bandpass_biquad_01 = std::make_shared(44100, 200); + mindspore::dataset::Execute Transform01({bandpass_biquad_01}); + // Filtered waveform by bandpassbiquad + Status s01 = Transform01(input_02, &input_02); + EXPECT_TRUE(s01.IsOk()); +} + +TEST_F(MindDataTestExecute, TestBandpassBiquadWithWrongArg) { + MS_LOG(INFO) << "Wrong Arg."; + std::vector labels = { + 2.716064453125000000e-03, 6.347656250000000000e-03, 9.246826171875000000e-03, 1.089477539062500000e-02, + 1.138305664062500000e-02, 1.156616210937500000e-02, 1.394653320312500000e-02, 1.550292968750000000e-02, + 1.614379882812500000e-02, 1.840209960937500000e-02, 1.718139648437500000e-02, 1.599121093750000000e-02, + 1.647949218750000000e-02, 1.510620117187500000e-02, 1.385498046875000000e-02, 1.345825195312500000e-02, + 1.419067382812500000e-02, 1.284790039062500000e-02, 1.052856445312500000e-02, 9.368896484375000000e-03}; + std::shared_ptr input; + ASSERT_OK(Tensor::CreateFromVector(labels, TensorShape({2, 10}), &input)); + auto input_02 = mindspore::MSTensor(std::make_shared(input)); + // Check Q + MS_LOG(INFO) << "Q is zero."; + std::shared_ptr bandpass_biquad_op = std::make_shared(44100, 200, 0); + mindspore::dataset::Execute Transform01({bandpass_biquad_op}); + Status s01 = Transform01(input_02, &input_02); + EXPECT_FALSE(s01.IsOk()); +} diff --git a/tests/ut/python/dataset/test_bandpass_biquad.py b/tests/ut/python/dataset/test_bandpass_biquad.py new file mode 100644 index 00000000000..90a8ddc78b1 --- /dev/null +++ b/tests/ut/python/dataset/test_bandpass_biquad.py @@ -0,0 +1,114 @@ +# Copyright 2021 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +import numpy as np +import pytest +import mindspore.dataset as ds +import mindspore.dataset.audio.transforms as audio +from mindspore import log as logger + + +def _count_unequal_element(data_expected, data_me, rtol, atol): + + assert data_expected.shape == data_me.shape + total_count = len(data_expected.flatten()) + error = np.abs(data_expected - data_me) + greater = np.greater(error, atol + np.abs(data_expected) * rtol) + loss_count = np.count_nonzero(greater) + assert (loss_count / total_count) < rtol, \ + "\ndata_expected_std:{0}\ndata_me_error:{1}\nloss:{2}". \ + format(data_expected[greater], data_me[greater], error[greater]) + + +def test_func_bandpass_biquad_eager(): + """ mindspore eager mode normal testcase:bandpass_biquad op""" + + # Original waveform + waveform = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float64) + # Expect waveform + expect_waveform = np.array([[0.01979545, 0.07838227, 0.17417782], + [0.07918181, 0.25414270, 0.46156447]], dtype=np.float64) + bandpass_biquad_op = audio.BandpassBiquad(44000, 200.0, 0.707, False) + # Filtered waveform by bandpassbiquad + output = bandpass_biquad_op(waveform) + _count_unequal_element(expect_waveform, output, 0.0001, 0.0001) + + +def test_func_bandpass_biquad_pipeline(): + """ mindspore pipeline mode normal testcase:bandpass_biquad op""" + + # Original waveform + waveform = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float64) + # Expect waveform + expect_waveform = np.array([[0.01979545, 0.07838227, 0.17417782], + [0.07918181, 0.25414270, 0.46156447]], dtype=np.float64) + label = np.random.sample((2, 1)) + data = (waveform, label) + dataset = ds.NumpySlicesDataset(data, ["channel", "sample"], shuffle=False) + bandpass_biquad_op = audio.BandpassBiquad(44000, 200.0) + # Filtered waveform by bandpassbiquad + dataset = dataset.map( + input_columns=["channel"], operations=bandpass_biquad_op, num_parallel_workers=8) + i = 0 + for _ in dataset.create_dict_iterator(output_numpy=True): + _count_unequal_element(expect_waveform[i, :], + _['channel'], 0.0001, 0.0001) + i += 1 + + +def test_bandpass_biquad_invalid_input(): + def test_invalid_input(test_name, sample_rate, central_freq, Q, const_skirt_gain, error, error_msg): + logger.info( + "Test BandpassBiquad with bad input: {0}".format(test_name)) + with pytest.raises(error) as error_info: + audio.BandpassBiquad( + sample_rate, central_freq, Q, const_skirt_gain) + assert error_msg in str(error_info.value) + + test_invalid_input("invalid sample_rate parameter type as a float", 44100.5, 200, 0.707, True, TypeError, + "Argument sample_rate with value 44100.5 is not of type []," + " but got .") + test_invalid_input("invalid sample_rate parameter type as a String", "44100", 200, 0.707, True, TypeError, + "Argument sample_rate with value 44100 is not of type [], but got .") + test_invalid_input("invalid contral_freq parameter type as a String", 44100, "200", 0.707, True, TypeError, + "Argument central_freq with value 200 is not of type [, ]," + " but got .") + test_invalid_input("invalid sample_rate parameter value", 0, 200, 0.707, True, ValueError, + "Input sample_rate can not be 0.") + test_invalid_input("invalid contral_freq parameter value", 44100, 32434324324234321, 0.707, True, ValueError, + "Input central_freq is not within the required interval of [-16777216, 16777216].") + test_invalid_input("invalid Q parameter type as a String", 44100, 200, "0.707", True, TypeError, + "Argument Q with value 0.707 is not of type [, ]," + " but got .") + test_invalid_input("invalid Q parameter value", 44100, 200, 1.707, True, ValueError, + "Input Q is not within the required interval of (0, 1].") + test_invalid_input("invalid Q parameter value", 44100, 200, 0, True, ValueError, + "Input Q is not within the required interval of (0, 1].") + test_invalid_input("invalid sample_rate parameter value", 441324343243242342345300, 200, 0.707, True, ValueError, + "Input sample_rate is not within the required interval of [-2147483648, 2147483647].") + test_invalid_input("invalid sample_rate parameter value", None, 200, 0.707, True, TypeError, + "Argument sample_rate with value None is not of type []," + " but got .") + test_invalid_input("invalid central_rate parameter value", 44100, None, 0.707, True, TypeError, + "Argument central_freq with value None is not of type [, ]," + " but got .") + test_invalid_input("invalid const_skirt_gain parameter type as a String", 44100, 200, 0.707, "False", TypeError, + "Argument const_skirt_gain with value False is not of type [], " + + "but got .") + + +if __name__ == "__main__": + test_func_bandpass_biquad_eager() + test_func_bandpass_biquad_pipeline() + test_bandpass_biquad_invalid_input()