From 08469e113a0e387cfc29aa41c5c622b66ff63fbe Mon Sep 17 00:00:00 2001 From: tongyue Date: Tue, 3 Aug 2021 05:41:53 -0700 Subject: [PATCH] [feat][assistant][I3J6TV]add new audio operator BandrejectBiquad --- mindspore/ccsrc/minddata/dataset/api/audio.cc | 17 +++ .../dataset/audio/kernels/ir/bindings.cc | 13 ++ .../dataset/audio/ir/kernels/CMakeLists.txt | 1 + .../audio/ir/kernels/bandreject_biquad_ir.cc | 49 ++++++++ .../audio/ir/kernels/bandreject_biquad_ir.h | 58 +++++++++ .../dataset/audio/kernels/CMakeLists.txt | 3 +- .../audio/kernels/bandreject_biquad_op.cc | 51 ++++++++ .../audio/kernels/bandreject_biquad_op.h | 52 ++++++++ .../minddata/dataset/include/dataset/audio.h | 22 ++++ .../minddata/dataset/kernels/tensor_op.h | 1 + mindspore/dataset/audio/transforms.py | 33 +++++- mindspore/dataset/audio/validators.py | 15 +++ mindspore/dataset/core/validator_helpers.py | 10 +- .../ut/cpp/dataset/c_api_audio_a_to_q_test.cc | 68 +++++++++++ tests/ut/cpp/dataset/execute_test.cc | 38 ++++++ .../python/dataset/test_bandreject_biquad.py | 111 ++++++++++++++++++ 16 files changed, 535 insertions(+), 7 deletions(-) create mode 100644 mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandreject_biquad_ir.cc create mode 100644 mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandreject_biquad_ir.h create mode 100644 mindspore/ccsrc/minddata/dataset/audio/kernels/bandreject_biquad_op.cc create mode 100644 mindspore/ccsrc/minddata/dataset/audio/kernels/bandreject_biquad_op.h create mode 100644 tests/ut/python/dataset/test_bandreject_biquad.py diff --git a/mindspore/ccsrc/minddata/dataset/api/audio.cc b/mindspore/ccsrc/minddata/dataset/api/audio.cc index 8b29476c928..0287fd1b0b1 100755 --- a/mindspore/ccsrc/minddata/dataset/api/audio.cc +++ b/mindspore/ccsrc/minddata/dataset/api/audio.cc @@ -19,6 +19,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" +#include "minddata/dataset/audio/ir/kernels/bandreject_biquad_ir.h" namespace mindspore { namespace dataset { @@ -74,6 +75,22 @@ std::shared_ptr BandpassBiquad::Parse() { return std::make_shared(data_->sample_rate_, data_->central_freq_, data_->Q_, data_->const_skirt_gain_); } + +// BandrejectBiquad Transform Operation. +struct BandrejectBiquad::Data { + Data(int32_t sample_rate, float central_freq, float Q) + : sample_rate_(sample_rate), central_freq_(central_freq), Q_(Q) {} + int32_t sample_rate_; + float central_freq_; + float Q_; +}; + +BandrejectBiquad::BandrejectBiquad(int32_t sample_rate, float central_freq, float Q) + : data_(std::make_shared(sample_rate, central_freq, Q)) {} + +std::shared_ptr BandrejectBiquad::Parse() { + return std::make_shared(data_->sample_rate_, data_->central_freq_, data_->Q_); +} } // 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 index 3a4890aec0b..2002f780c5a 100755 --- 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 @@ -20,6 +20,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" +#include "minddata/dataset/audio/ir/kernels/bandreject_biquad_ir.h" #include "minddata/dataset/include/dataset/transforms.h" namespace mindspore { @@ -56,5 +57,17 @@ PYBIND_REGISTER( return bandpass_biquad; })); })); + +PYBIND_REGISTER(BandrejectBiquadOperation, 1, ([](const py::module *m) { + (void)py::class_>(*m, "BandrejectBiquadOperation") + .def(py::init([](int32_t sample_rate, float central_freq, float Q) { + auto bandreject_biquad = + std::make_shared(sample_rate, central_freq, Q); + THROW_IF_ERROR(bandreject_biquad->ValidateParams()); + return bandreject_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 fc3f6b58b07..7339098ef8c 100644 --- a/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/CMakeLists.txt +++ b/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/CMakeLists.txt @@ -5,4 +5,5 @@ add_library(audio-ir-kernels OBJECT allpass_biquad_ir.cc band_biquad_ir.cc bandpass_biquad_ir.cc + bandreject_biquad_ir.cc ) diff --git a/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandreject_biquad_ir.cc b/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandreject_biquad_ir.cc new file mode 100644 index 00000000000..0688cb6b4d6 --- /dev/null +++ b/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandreject_biquad_ir.cc @@ -0,0 +1,49 @@ +/** + * 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/bandreject_biquad_ir.h" +#include "minddata/dataset/audio/kernels/bandreject_biquad_op.h" +#include "minddata/dataset/audio/ir/validators.h" + +namespace mindspore { +namespace dataset { +namespace audio { +// BandrejectBiquadOperation +BandrejectBiquadOperation::BandrejectBiquadOperation(int32_t sample_rate, float central_freq, float Q) + : sample_rate_(sample_rate), central_freq_(central_freq), Q_(Q) {} + +Status BandrejectBiquadOperation::ValidateParams() { + RETURN_IF_NOT_OK(ValidateScalar("BandrejectBiquad", "Q", Q_, {0, 1.0}, true, false)); + RETURN_IF_NOT_OK(CheckScalarNotZero("BandrejectBiquad", "sample_rate", sample_rate_)); + return Status::OK(); +} + +std::shared_ptr BandrejectBiquadOperation::Build() { + std::shared_ptr tensor_op = std::make_shared(sample_rate_, central_freq_, Q_); + return tensor_op; +} + +Status BandrejectBiquadOperation::to_json(nlohmann::json *out_json) { + nlohmann::json args; + args["sample_rate"] = sample_rate_; + args["central_freq"] = central_freq_; + args["Q"] = Q_; + *out_json = args; + return Status::OK(); +} +} // namespace audio +} // namespace dataset +} // namespace mindspore diff --git a/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandreject_biquad_ir.h b/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandreject_biquad_ir.h new file mode 100644 index 00000000000..9a38185c4b8 --- /dev/null +++ b/mindspore/ccsrc/minddata/dataset/audio/ir/kernels/bandreject_biquad_ir.h @@ -0,0 +1,58 @@ +/** + * 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_BANDREJECT_BIQUAD_IR_H_ +#define MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_IR_KERNELS_BANDREJECT_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 kBandrejectBiquadOperation[] = "BandrejectBiquad"; + +class BandrejectBiquadOperation : public TensorOperation { + public: + explicit BandrejectBiquadOperation(int32_t sample_rate, float central_freq, float Q); + + ~BandrejectBiquadOperation() = default; + + std::shared_ptr Build() override; + + Status ValidateParams() override; + + std::string Name() const override { return kBandrejectBiquadOperation; } + + Status to_json(nlohmann::json *out_json) override; + + private: + int32_t sample_rate_; + float central_freq_; + float Q_; +}; +} // namespace audio +} // namespace dataset +} // namespace mindspore +#endif // MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_IR_KERNELS_BANDREJECT_BIQUAD_IR_H_ diff --git a/mindspore/ccsrc/minddata/dataset/audio/kernels/CMakeLists.txt b/mindspore/ccsrc/minddata/dataset/audio/kernels/CMakeLists.txt index 5b39c43c2cb..3ef080f10b5 100644 --- a/mindspore/ccsrc/minddata/dataset/audio/kernels/CMakeLists.txt +++ b/mindspore/ccsrc/minddata/dataset/audio/kernels/CMakeLists.txt @@ -5,4 +5,5 @@ add_library(audio-kernels OBJECT allpass_biquad_op.cc band_biquad_op.cc bandpass_biquad_op.cc - ) \ No newline at end of file + bandreject_biquad_op.cc + ) diff --git a/mindspore/ccsrc/minddata/dataset/audio/kernels/bandreject_biquad_op.cc b/mindspore/ccsrc/minddata/dataset/audio/kernels/bandreject_biquad_op.cc new file mode 100644 index 00000000000..d321cbf6d52 --- /dev/null +++ b/mindspore/ccsrc/minddata/dataset/audio/kernels/bandreject_biquad_op.cc @@ -0,0 +1,51 @@ +/** + * 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/bandreject_biquad_op.h" + +#include "minddata/dataset/audio/kernels/audio_utils.h" +#include "minddata/dataset/util/status.h" + +namespace mindspore { +namespace dataset { +Status BandrejectBiquadOp::Compute(const std::shared_ptr &input, std::shared_ptr *output) { + IO_CHECK(input, output); + // check input type and input shape + TensorShape input_shape = input->shape(); + CHECK_FAIL_RETURN_UNEXPECTED(input_shape.Size() > 0, "BandrejectBiquad: input dimension should be greater than 0."); + CHECK_FAIL_RETURN_UNEXPECTED(input->type() == DataType(DataType::DE_FLOAT32) || + input->type() == DataType(DataType::DE_FLOAT16) || + input->type() == DataType(DataType::DE_FLOAT64), + "BandrejectBiquad: input type should be float, but got " + input->type().ToString()); + double w0 = 2 * PI * central_freq_ / sample_rate_; + double alpha = sin(w0) / 2 / Q_; + double b0 = 1; + double b1 = -2 * cos(w0); + double b2 = 1; + double a0 = 1 + alpha; + double a1 = b1; + double 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/bandreject_biquad_op.h b/mindspore/ccsrc/minddata/dataset/audio/kernels/bandreject_biquad_op.h new file mode 100644 index 00000000000..3b42a6ccb82 --- /dev/null +++ b/mindspore/ccsrc/minddata/dataset/audio/kernels/bandreject_biquad_op.h @@ -0,0 +1,52 @@ +/** + * 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_BANDREJECT_BIQUAD_OP_H_ +#define MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_KERNELS_BANDREJECT_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 BandrejectBiquadOp : public TensorOp { + public: + BandrejectBiquadOp(int32_t sample_rate, float central_freq, float Q) + : sample_rate_(sample_rate), central_freq_(central_freq), Q_(Q) {} + + ~BandrejectBiquadOp() override = default; + + void Print(std::ostream &out) const override { + out << Name() << ": sample_rate: " << sample_rate_ << ", central_freq: " << central_freq_ << ", Q: " << Q_ + << std::endl; + } + + Status Compute(const std::shared_ptr &input, std::shared_ptr *output) override; + + std::string Name() const override { return kBandrejectBiquadOp; } + + private: + int32_t sample_rate_; + float central_freq_; + float Q_; +}; +} // namespace dataset +} // namespace mindspore +#endif // MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_BANDREJECT_BIQUAD_OP_H_ diff --git a/mindspore/ccsrc/minddata/dataset/include/dataset/audio.h b/mindspore/ccsrc/minddata/dataset/include/dataset/audio.h index 95d99399418..6729899fa10 100755 --- a/mindspore/ccsrc/minddata/dataset/include/dataset/audio.h +++ b/mindspore/ccsrc/minddata/dataset/include/dataset/audio.h @@ -102,6 +102,28 @@ class BandpassBiquad final : public TensorTransform { std::shared_ptr data_; }; +/// \brief Design two-pole band-reject filter. Similar to SoX implementation. +class BandrejectBiquad 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). + explicit BandrejectBiquad(int32_t sample_rate, float central_freq, float Q = 0.707); + + /// \brief Destructor. + ~BandrejectBiquad() = 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 cd45c71373f..b914e56f255 100644 --- a/mindspore/ccsrc/minddata/dataset/kernels/tensor_op.h +++ b/mindspore/ccsrc/minddata/dataset/kernels/tensor_op.h @@ -140,6 +140,7 @@ constexpr char kSentencepieceTokenizerOp[] = "SentencepieceTokenizerOp"; constexpr char kAllpassBiquadOp[] = "AllpassBiquadOp"; constexpr char kBandBiquadOp[] = "BandBiquadOp"; constexpr char kBandpassBiquadOp[] = "BandpassBiquadOp"; +constexpr char kBandrejectBiquadOp[] = "BandrejectBiquadOp"; // data constexpr char kConcatenateOp[] = "ConcatenateOp"; diff --git a/mindspore/dataset/audio/transforms.py b/mindspore/dataset/audio/transforms.py index 6d141241d38..a3f4486f0fd 100755 --- 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, check_bandpass_biquad +from .validators import check_allpass_biquad, check_band_biquad, check_bandpass_biquad, check_bandreject_biquad class AudioTensorOperation(TensorOperation): @@ -132,3 +132,34 @@ class BandpassBiquad(TensorOperation): def parse(self): return cde.BandpassBiquadOperation(self.sample_rate, self.central_freq, self.Q, self.const_skirt_gain) + + +class BandrejectBiquad(AudioTensorOperation): + """ + Design two-pole band filter for audio waveform of dimension of `(..., time)` + + Args: + sample_rate (int): sampling rate of the waveform, e.g. 44100 (Hz), + the value must be greater than 0 . + central_freq (float): central frequency (in Hz), + the value must be greater than 0 . + Q(float, optional): Quality factor,https://en.wikipedia.org/wiki/Q_factor, + Range: (0, 1] (Default=0.707). + + 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]]) + >>> band_biquad_op = audio.BandBiquad(44100, 200.0) + >>> waveform_filtered = band_biquad_op(waveform) + """ + + @check_bandreject_biquad + def __init__(self, sample_rate, central_freq, Q=0.707): + self.sample_rate = sample_rate + self.central_freq = central_freq + self.Q = Q + + def parse(self): + return cde.BandrejectBiquadOperation(self.sample_rate, self.central_freq, self.Q) diff --git a/mindspore/dataset/audio/validators.py b/mindspore/dataset/audio/validators.py index b9de7858af7..aa0afc53984 100755 --- a/mindspore/dataset/audio/validators.py +++ b/mindspore/dataset/audio/validators.py @@ -94,3 +94,18 @@ def check_bandpass_biquad(method): return method(self, *args, **kwargs) return new_method + + +def check_bandreject_biquad(method): + """Wrapper method to check the parameters of BandrejectBiquad.""" + + @wraps(method) + def new_method(self, *args, **kwargs): + [sample_rate, central_freq, Q], _ = parse_user_args( + method, *args, **kwargs) + check_biquad_sample_rate(sample_rate) + check_biquad_central_freq(central_freq) + check_biquad_Q(Q) + 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 f230e8e43a1..4ba42a401b6 100644 --- a/mindspore/dataset/core/validator_helpers.py +++ b/mindspore/dataset/core/validator_helpers.py @@ -210,6 +210,11 @@ def check_2tuple(value, arg_name=""): raise ValueError("Value {0} needs to be a 2-tuple.".format(arg_name)) +def check_int32(value, arg_name=""): + type_check(value, (int,), arg_name) + check_value(value, [INT32_MIN, INT32_MAX], arg_name) + + def check_uint8(value, arg_name=""): """ Validates the value of a variable is within the range of uint8. @@ -222,11 +227,6 @@ def check_uint8(value, arg_name=""): check_value(value, [UINT8_MIN, UINT8_MAX]) -def check_int32(value, arg_name=""): - type_check(value, (int,), arg_name) - check_value(value, [INT32_MIN, INT32_MAX], arg_name) - - def check_uint32(value, arg_name=""): """ Validates the value of a variable is within the range of uint32. 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 537226b69e4..d2f7bb58e0b 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 @@ -233,3 +233,71 @@ TEST_F(MindDataTestPipeline, Level0_TestBandpassBiquad002) { std::shared_ptr iter02 = ds02->CreateIterator(); EXPECT_EQ(iter02, nullptr); } + +TEST_F(MindDataTestPipeline, Level0_TestBandrejectBiquad001) { + 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 BandrejectBiquadOp = audio::BandrejectBiquad(44100, 200.0); + + ds = ds->Map({BandrejectBiquadOp}); + EXPECT_NE(ds, nullptr); + + // Filtered waveform by bandrejectbiquad + 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_TestBandrejectBiquad002) { + 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 bandreject_biquad_op_01 = audio::BandrejectBiquad(0, 200); + ds01 = ds->Map({bandreject_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 bandreject_biquad_op_02 = audio::BandrejectBiquad(44100, 200, 0); + ds02 = ds->Map({bandreject_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 7903588dffd..fd5016f4326 100644 --- a/tests/ut/cpp/dataset/execute_test.cc +++ b/tests/ut/cpp/dataset/execute_test.cc @@ -410,3 +410,41 @@ TEST_F(MindDataTestExecute, TestBandpassBiquadWithWrongArg) { Status s01 = Transform01(input_02, &input_02); EXPECT_FALSE(s01.IsOk()); } + +TEST_F(MindDataTestExecute, TestBandrejectBiquadWithEager) { + 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 bandreject_biquad_01 = std::make_shared(44100, 200); + mindspore::dataset::Execute Transform01({bandreject_biquad_01}); + // Filtered waveform by bandrejectbiquad + Status s01 = Transform01(input_02, &input_02); + EXPECT_TRUE(s01.IsOk()); +} + +TEST_F(MindDataTestExecute, TestBandrejectBiquadWithWrongArg) { + 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 bandreject_biquad_op = std::make_shared(44100, 200, 0); + mindspore::dataset::Execute Transform01({bandreject_biquad_op}); + Status s01 = Transform01(input_02, &input_02); + EXPECT_FALSE(s01.IsOk()); +} diff --git a/tests/ut/python/dataset/test_bandreject_biquad.py b/tests/ut/python/dataset/test_bandreject_biquad.py new file mode 100644 index 00000000000..3c799c6f827 --- /dev/null +++ b/tests/ut/python/dataset/test_bandreject_biquad.py @@ -0,0 +1,111 @@ +# 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_bandreject_biquad_eager(): + """ mindspore eager mode normal testcase:bandreject_biquad op""" + + # Original waveform + waveform = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float64) + # Expect waveform + expect_waveform = np.array([[9.802485108375549316e-01, 1.000000000000000000e+00, 1.000000000000000000e+00], + [1.000000000000000000e+00, 1.000000000000000000e+00, 1.000000000000000000e+00]], + dtype=np.float64) + bandreject_biquad_op = audio.BandrejectBiquad(44100, 200.0, 0.707) + # Filtered waveform by bandrejectbiquad + output = bandreject_biquad_op(waveform) + _count_unequal_element(expect_waveform, output, 0.0001, 0.0001) + + +def test_func_bandreject_biquad_pipeline(): + """ mindspore pipeline mode normal testcase:bandreject_biquad op""" + + # Original waveform + waveform = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float64) + # Expect waveform + expect_waveform = np.array([[9.802485108375549316e-01, 1.000000000000000000e+00, 1.000000000000000000e+00], + [1.000000000000000000e+00, 1.000000000000000000e+00, 1.000000000000000000e+00]], + dtype=np.float64) + label = np.random.sample((2, 1)) + data = (waveform, label) + dataset = ds.NumpySlicesDataset(data, ["channel", "sample"], shuffle=False) + bandreject_biquad_op = audio.BandrejectBiquad(44100, 200.0) + # Filtered waveform by bandrejectbiquad + dataset = dataset.map( + input_columns=["channel"], operations=bandreject_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_bandreject_biquad_invalid_input(): + def test_invalid_input(test_name, sample_rate, central_freq, Q, error, error_msg): + logger.info( + "Test BandrejectBiquad with bad input: {0}".format(test_name)) + with pytest.raises(error) as error_info: + audio.BandrejectBiquad(sample_rate, central_freq, Q) + assert error_msg in str(error_info.value) + test_invalid_input("invalid sample_rate parameter type as a float", 44100.5, 200, 0.707, 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, 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, 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, ValueError, + "Input sample_rate can not be 0.") + test_invalid_input("invalid contral_freq parameter value", 44100, 32434324324234321, 0.707, 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", TypeError, + "Argument Q with value 0.707 is not of type [, ]," + " but got .") + test_invalid_input("invalid Q parameter value", 44100, 200, 1.707, ValueError, + "Input Q is not within the required interval of (0, 1].") + test_invalid_input("invalid Q parameter value", 44100, 200, 0, ValueError, + "Input Q is not within the required interval of (0, 1].") + test_invalid_input("invalid sample_rate parameter value", 441324343243242342345300, 200, 0.707, 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, 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, TypeError, + "Argument central_freq with value None is not of type [, ]," + " but got .") + + +if __name__ == "__main__": + test_func_band_biquad_eager() + test_func_band_biquad_pipeline() + test_band_biquad_invalid_input()