| @@ -20,6 +20,7 @@ | |||
| #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/audio/ir/kernels/bass_biquad_ir.h" | |||
| namespace mindspore { | |||
| namespace dataset { | |||
| @@ -91,6 +92,23 @@ BandrejectBiquad::BandrejectBiquad(int32_t sample_rate, float central_freq, floa | |||
| std::shared_ptr<TensorOperation> BandrejectBiquad::Parse() { | |||
| return std::make_shared<BandrejectBiquadOperation>(data_->sample_rate_, data_->central_freq_, data_->Q_); | |||
| } | |||
| // BassBiquad Transform Operation. | |||
| struct BassBiquad::Data { | |||
| Data(int32_t sample_rate, float gain, float central_freq, float Q) | |||
| : sample_rate_(sample_rate), gain_(gain), central_freq_(central_freq), Q_(Q) {} | |||
| int32_t sample_rate_; | |||
| float gain_; | |||
| float central_freq_; | |||
| float Q_; | |||
| }; | |||
| BassBiquad::BassBiquad(int32_t sample_rate, float gain, float central_freq, float Q) | |||
| : data_(std::make_shared<Data>(sample_rate, gain, central_freq, Q)) {} | |||
| std::shared_ptr<TensorOperation> BassBiquad::Parse() { | |||
| return std::make_shared<BassBiquadOperation>(data_->sample_rate_, data_->gain_, data_->central_freq_, data_->Q_); | |||
| } | |||
| } // namespace audio | |||
| } // namespace dataset | |||
| } // namespace mindspore | |||
| @@ -21,6 +21,7 @@ | |||
| #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/audio/ir/kernels/bass_biquad_ir.h" | |||
| #include "minddata/dataset/include/dataset/transforms.h" | |||
| namespace mindspore { | |||
| @@ -69,5 +70,16 @@ PYBIND_REGISTER(BandrejectBiquadOperation, 1, ([](const py::module *m) { | |||
| })); | |||
| })); | |||
| PYBIND_REGISTER( | |||
| BassBiquadOperation, 1, ([](const py::module *m) { | |||
| (void)py::class_<audio::BassBiquadOperation, TensorOperation, std::shared_ptr<audio::BassBiquadOperation>>( | |||
| *m, "BassBiquadOperation") | |||
| .def(py::init([](int32_t sample_rate, float gain, float central_freq, float Q) { | |||
| auto bass_biquad = std::make_shared<audio::BassBiquadOperation>(sample_rate, gain, central_freq, Q); | |||
| THROW_IF_ERROR(bass_biquad->ValidateParams()); | |||
| return bass_biquad; | |||
| })); | |||
| })); | |||
| } // namespace dataset | |||
| } // namespace mindspore | |||
| @@ -6,4 +6,5 @@ add_library(audio-ir-kernels OBJECT | |||
| band_biquad_ir.cc | |||
| bandpass_biquad_ir.cc | |||
| bandreject_biquad_ir.cc | |||
| bass_biquad_ir.cc | |||
| ) | |||
| @@ -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. | |||
| */ | |||
| #include "minddata/dataset/audio/ir/kernels/bass_biquad_ir.h" | |||
| #include "minddata/dataset/audio/kernels/bass_biquad_op.h" | |||
| #include "minddata/dataset/audio/ir/validators.h" | |||
| namespace mindspore { | |||
| namespace dataset { | |||
| namespace audio { | |||
| // BassBiquadOperation | |||
| BassBiquadOperation::BassBiquadOperation(int32_t sample_rate, float gain, float central_freq, float Q) | |||
| : sample_rate_(sample_rate), gain_(gain), central_freq_(central_freq), Q_(Q) {} | |||
| Status BassBiquadOperation::ValidateParams() { | |||
| RETURN_IF_NOT_OK(ValidateScalar("BassBiquad", "Q", Q_, {0, 1.0}, true, false)); | |||
| RETURN_IF_NOT_OK(CheckScalarNotZero("BassBiquad", "sample_rate", sample_rate_)); | |||
| return Status::OK(); | |||
| } | |||
| std::shared_ptr<TensorOp> BassBiquadOperation::Build() { | |||
| std::shared_ptr<BassBiquadOp> tensor_op = std::make_shared<BassBiquadOp>(sample_rate_, gain_, central_freq_, Q_); | |||
| return tensor_op; | |||
| } | |||
| Status BassBiquadOperation::to_json(nlohmann::json *out_json) { | |||
| nlohmann::json args; | |||
| args["sample_rate"] = sample_rate_; | |||
| args["gain"] = gain_; | |||
| args["central_freq"] = central_freq_; | |||
| args["Q"] = Q_; | |||
| *out_json = args; | |||
| return Status::OK(); | |||
| } | |||
| } // namespace audio | |||
| } // namespace dataset | |||
| } // namespace mindspore | |||
| @@ -0,0 +1,61 @@ | |||
| /** | |||
| * 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_BASS_BIQUAD_IR_H_ | |||
| #define MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_IR_KERNELS_BASS_BIQUAD_IR_H_ | |||
| #include <memory> | |||
| #include <string> | |||
| #include <utility> | |||
| #include <vector> | |||
| #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 kBassBiquadOperation[] = "BassBiquad"; | |||
| class BassBiquadOperation : public TensorOperation { | |||
| public: | |||
| explicit BassBiquadOperation(int32_t sample_rate, float gain, float central_freq, float Q); | |||
| ~BassBiquadOperation() = default; | |||
| std::shared_ptr<TensorOp> Build() override; | |||
| Status ValidateParams() override; | |||
| std::string Name() const override { return kBassBiquadOperation; } | |||
| Status to_json(nlohmann::json *out_json) override; | |||
| private: | |||
| int32_t sample_rate_; | |||
| float gain_; | |||
| float central_freq_; | |||
| float Q_; | |||
| }; | |||
| } // namespace audio | |||
| } // namespace dataset | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_IR_KERNELS_BASS_BIQUAD_IR_H_ | |||
| @@ -6,4 +6,5 @@ add_library(audio-kernels OBJECT | |||
| band_biquad_op.cc | |||
| bandpass_biquad_op.cc | |||
| bandreject_biquad_op.cc | |||
| bass_biquad_op.cc | |||
| ) | |||
| @@ -0,0 +1,61 @@ | |||
| /** | |||
| * 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/bass_biquad_op.h" | |||
| #include "minddata/dataset/audio/kernels/audio_utils.h" | |||
| #include "minddata/dataset/util/status.h" | |||
| namespace mindspore { | |||
| namespace dataset { | |||
| Status BassBiquadOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) { | |||
| IO_CHECK(input, output); | |||
| TensorShape input_shape = input->shape(); | |||
| CHECK_FAIL_RETURN_UNEXPECTED(input_shape.Size() > 0, "BassBiquad: input 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), | |||
| "BassBiquad: 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 A = exp(gain_ / 40 * log(10)); | |||
| double temp1 = 2 * sqrt(A) * alpha; | |||
| double temp2 = (A - 1) * cos(w0); | |||
| double temp3 = (A + 1) * cos(w0); | |||
| double b0 = A * ((A + 1) - temp2 + temp1); | |||
| double b1 = 2 * A * ((A - 1) - temp3); | |||
| double b2 = A * ((A + 1) - temp2 - temp1); | |||
| double a0 = (A + 1) + temp2 + temp1; | |||
| double a1 = -2 * ((A - 1) + temp3); | |||
| double a2 = (A + 1) + temp2 - temp1; | |||
| if (input->type() == DataType(DataType::DE_FLOAT32)) | |||
| return Biquad(input, output, static_cast<float>(b0 / a0), static_cast<float>(b1 / a0), static_cast<float>(b2 / a0), | |||
| static_cast<float>(1.0), static_cast<float>(a1 / a0), static_cast<float>(a2 / a0)); | |||
| else if (input->type() == DataType(DataType::DE_FLOAT64)) | |||
| return Biquad(input, output, static_cast<double>(b0 / a0), static_cast<double>(b1 / a0), | |||
| static_cast<double>(b2 / a0), static_cast<double>(1.0), static_cast<double>(a1 / a0), | |||
| static_cast<double>(a2 / a0)); | |||
| else | |||
| return Biquad(input, output, static_cast<float16>(b0 / a0), static_cast<float16>(b1 / a0), | |||
| static_cast<float16>(b2 / a0), static_cast<float16>(1.0), static_cast<float16>(a1 / a0), | |||
| static_cast<float16>(a2 / a0)); | |||
| } | |||
| } // namespace dataset | |||
| } // namespace mindspore | |||
| @@ -0,0 +1,54 @@ | |||
| /** | |||
| * 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_BASS_BIQUAD_OP_H_ | |||
| #define MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_KERNELS_BASS_BIQUAD_OP_H_ | |||
| #include <memory> | |||
| #include <string> | |||
| #include <vector> | |||
| #include "minddata/dataset/core/tensor.h" | |||
| #include "minddata/dataset/kernels/tensor_op.h" | |||
| #include "minddata/dataset/util/status.h" | |||
| namespace mindspore { | |||
| namespace dataset { | |||
| class BassBiquadOp : public TensorOp { | |||
| public: | |||
| BassBiquadOp(int32_t sample_rate, float gain, float central_freq, float Q) | |||
| : sample_rate_(sample_rate), gain_(gain), central_freq_(central_freq), Q_(Q) {} | |||
| ~BassBiquadOp() override = default; | |||
| void Print(std::ostream &out) const override { | |||
| out << Name() << ": sample_rate: " << sample_rate_ << ", gain:" << gain_ << ", central_freq: " << central_freq_ | |||
| << ", Q: " << Q_ << std::endl; | |||
| } | |||
| Status Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) override; | |||
| std::string Name() const override { return kBassBiquadOp; } | |||
| private: | |||
| int32_t sample_rate_; | |||
| float gain_; | |||
| float central_freq_; | |||
| float Q_; | |||
| }; | |||
| } // namespace dataset | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_MINDDATA_DATASET_AUDIO_KERNELS_BASS_BIQUAD_OP_H_ | |||
| @@ -124,6 +124,28 @@ class BandrejectBiquad final : public TensorTransform { | |||
| std::shared_ptr<Data> data_; | |||
| }; | |||
| /// \brief Design a bass tone-control effect. | |||
| class BassBiquad final : public TensorTransform { | |||
| public: | |||
| /// \brief Constructor. | |||
| /// \param[in] sample_rate Sampling rate of the waveform, e.g. 44100 (Hz). | |||
| /// \param[in] gain Desired gain at the boost (or attenuation) in dB. | |||
| /// \param[in] central_freq Central frequency (in Hz). | |||
| /// \param[in] Q https://en.wikipedia.org/wiki/Q_factor (Default: 0.707). | |||
| explicit BassBiquad(int32_t sample_rate, float gain, float central_freq = 100, float Q = 0.707); | |||
| /// \brief Destructor. | |||
| ~BassBiquad() = default; | |||
| protected: | |||
| /// \brief Function to convert TensorTransform object into a TensorOperation object. | |||
| /// \return Shared pointer to TensorOperation object. | |||
| std::shared_ptr<TensorOperation> Parse() override; | |||
| private: | |||
| struct Data; | |||
| std::shared_ptr<Data> data_; | |||
| }; | |||
| } // namespace audio | |||
| } // namespace dataset | |||
| } // namespace mindspore | |||
| @@ -141,6 +141,7 @@ constexpr char kAllpassBiquadOp[] = "AllpassBiquadOp"; | |||
| constexpr char kBandBiquadOp[] = "BandBiquadOp"; | |||
| constexpr char kBandpassBiquadOp[] = "BandpassBiquadOp"; | |||
| constexpr char kBandrejectBiquadOp[] = "BandrejectBiquadOp"; | |||
| constexpr char kBassBiquadOp[] = "BassBiquadOp"; | |||
| // data | |||
| constexpr char kConcatenateOp[] = "ConcatenateOp"; | |||
| @@ -20,7 +20,8 @@ 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, check_bandreject_biquad | |||
| from .validators import check_allpass_biquad, check_band_biquad, check_bandpass_biquad, check_bandreject_biquad, \ | |||
| check_bass_biquad | |||
| class AudioTensorOperation(TensorOperation): | |||
| @@ -163,3 +164,32 @@ class BandrejectBiquad(AudioTensorOperation): | |||
| def parse(self): | |||
| return cde.BandrejectBiquadOperation(self.sample_rate, self.central_freq, self.Q) | |||
| class BassBiquad(AudioTensorOperation): | |||
| """ | |||
| Design a bass tone-control effect for audio waveform of dimension of `(..., time)` | |||
| Args: | |||
| sample_rate (int): sampling rate of the waveform, e.g. 44100 (Hz) | |||
| gain (float): desired gain at the boost (or attenuation) in dB. | |||
| central_freq (float): central frequency (in Hz)(Default=100.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]]) | |||
| >>> bass_biquad_op = audio.BassBiquad(44100, 100.0) | |||
| >>> waveform_filtered = bass_biquad_op(waveform) | |||
| """ | |||
| @check_bass_biquad | |||
| def __init__(self, sample_rate, gain, central_freq=100.0, Q=0.707): | |||
| self.sample_rate = sample_rate | |||
| self.gain = gain | |||
| self.central_freq = central_freq | |||
| self.Q = Q | |||
| def parse(self): | |||
| return cde.BassBiquadOperation(self.sample_rate, self.gain, self.central_freq, self.Q) | |||
| @@ -49,6 +49,12 @@ def check_biquad_const_skirt_gain(const_skirt_gain): | |||
| type_check(const_skirt_gain, (bool,), "const_skirt_gain") | |||
| def check_biquad_gain(gain): | |||
| """Wrapper method to check the parameters of gain.""" | |||
| type_check(gain, (float, int), "gain") | |||
| check_float32(gain, "gain") | |||
| def check_band_biquad(method): | |||
| """Wrapper method to check the parameters of BandBiquad.""" | |||
| @@ -109,3 +115,19 @@ def check_bandreject_biquad(method): | |||
| return method(self, *args, **kwargs) | |||
| return new_method | |||
| def check_bass_biquad(method): | |||
| """Wrapper method to check the parameters of CutMixBatch.""" | |||
| @wraps(method) | |||
| def new_method(self, *args, **kwargs): | |||
| [sample_rate, gain, central_freq, Q], _ = parse_user_args( | |||
| method, *args, **kwargs) | |||
| check_biquad_sample_rate(sample_rate) | |||
| check_biquad_gain(gain) | |||
| check_biquad_central_freq(central_freq) | |||
| check_biquad_Q(Q) | |||
| return method(self, *args, **kwargs) | |||
| return new_method | |||
| @@ -301,3 +301,71 @@ TEST_F(MindDataTestPipeline, Level0_TestBandrejectBiquad002) { | |||
| std::shared_ptr<Iterator> iter02 = ds02->CreateIterator(); | |||
| EXPECT_EQ(iter02, nullptr); | |||
| } | |||
| TEST_F(MindDataTestPipeline, Level0_TestBassBiquad001) { | |||
| MS_LOG(INFO) << "Basic Function Test"; | |||
| // Original waveform | |||
| std::shared_ptr<SchemaObj> schema = Schema(); | |||
| ASSERT_OK(schema->add_column("inputData", mindspore::DataType::kNumberTypeFloat32, {2, 200})); | |||
| std::shared_ptr<Dataset> ds = RandomData(50, schema); | |||
| EXPECT_NE(ds, nullptr); | |||
| ds = ds->SetNumWorkers(4); | |||
| EXPECT_NE(ds, nullptr); | |||
| auto BassBiquadOp = audio::BassBiquad(44100,50,200.0); | |||
| ds = ds->Map({BassBiquadOp}); | |||
| EXPECT_NE(ds, nullptr); | |||
| // Filtered waveform by bassbiquad | |||
| std::shared_ptr<Iterator> iter = ds->CreateIterator(); | |||
| EXPECT_NE(ds, nullptr); | |||
| std::unordered_map<std::string, mindspore::MSTensor> row; | |||
| ASSERT_OK(iter->GetNextRow(&row)); | |||
| std::vector<int64_t> 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_TestBassBiquad002) { | |||
| MS_LOG(INFO) << "Wrong Arg."; | |||
| std::shared_ptr<SchemaObj> schema = Schema(); | |||
| // Original waveform | |||
| ASSERT_OK(schema->add_column("inputData", mindspore::DataType::kNumberTypeFloat32, {2, 2})); | |||
| std::shared_ptr<Dataset> ds = RandomData(50, schema); | |||
| std::shared_ptr<Dataset> ds01; | |||
| std::shared_ptr<Dataset> ds02; | |||
| EXPECT_NE(ds, nullptr); | |||
| // Check sample_rate | |||
| MS_LOG(INFO) << "sample_rate is zero."; | |||
| auto bass_biquad_op_01 = audio::BassBiquad(0,50,200.0); | |||
| ds01 = ds->Map({bass_biquad_op_01}); | |||
| EXPECT_NE(ds01, nullptr); | |||
| std::shared_ptr<Iterator> iter01 = ds01->CreateIterator(); | |||
| EXPECT_EQ(iter01, nullptr); | |||
| // Check Q_ | |||
| MS_LOG(INFO) << "Q_ is zero."; | |||
| auto bass_biquad_op_02 = audio::BassBiquad(44100,50,200.0,0); | |||
| ds02 = ds->Map({bass_biquad_op_02}); | |||
| EXPECT_NE(ds02, nullptr); | |||
| std::shared_ptr<Iterator> iter02 = ds02->CreateIterator(); | |||
| EXPECT_EQ(iter02, nullptr); | |||
| } | |||
| @@ -0,0 +1,117 @@ | |||
| # 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_bass_biquad_eager(): | |||
| """ mindspore eager mode normal testcase:bass_biquad op""" | |||
| # Original waveform | |||
| waveform = np.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]], dtype=np.float64) | |||
| # Expect waveform | |||
| expect_waveform = np.array([[0.10409035359, 0.21652136269, 0.33761211292], | |||
| [0.41636141439, 0.55381438997, 0.70088436361]], dtype=np.float64) | |||
| bass_biquad_op = audio.BassBiquad(44100, 50.0, 100.0, 0.707) | |||
| # Filtered waveform by bassbiquad | |||
| output = bass_biquad_op(waveform) | |||
| _count_unequal_element(expect_waveform, output, 0.0001, 0.0001) | |||
| def test_func_bass_biquad_pipeline(): | |||
| """ mindspore pipeline mode normal testcase:bass_biquad op""" | |||
| # Original waveform | |||
| waveform = np.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]], dtype=np.float64) | |||
| # Expect waveform | |||
| expect_waveform = np.array([[0.10409035359, 0.21652136269, 0.33761211292], | |||
| [0.41636141439, 0.55381438997, 0.70088436361]], dtype=np.float64) | |||
| label = np.random.sample((2, 1)) | |||
| data = (waveform, label) | |||
| dataset = ds.NumpySlicesDataset(data, ["channel", "sample"], shuffle=False) | |||
| bass_biquad_op = audio.BassBiquad(44100, 50, 100.0, 0.707) | |||
| # Filtered waveform by bassbiquad | |||
| dataset = dataset.map( | |||
| input_columns=["channel"], operations=bass_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_invalid_invalid_input(): | |||
| def test_invalid_input(test_name, sample_rate, gain, central_freq, Q, error, error_msg): | |||
| logger.info("Test BassBiquad with bad input: {0}".format(test_name)) | |||
| with pytest.raises(error) as error_info: | |||
| audio.BassBiquad(sample_rate, gain, central_freq, Q) | |||
| assert error_msg in str(error_info.value) | |||
| test_invalid_input("invalid sample_rate parameter type as a float", 44100.5, 50.0, 200, 0.707, TypeError, | |||
| "Argument sample_rate with value 44100.5 is not of type [<class 'int'>]," | |||
| " but got <class 'float'>.") | |||
| test_invalid_input("invalid sample_rate parameter type as a String", "44100", 50.0, 200, 0.707, TypeError, | |||
| "Argument sample_rate with value 44100 is not of type [<class 'int'>]," | |||
| " but got <class 'str'>.") | |||
| test_invalid_input("invalid gain parameter type as a String", 44100, "50.0", 200, 0.707, TypeError, | |||
| "Argument gain with value 50.0 is not of type [<class 'float'>, <class 'int'>]," | |||
| " but got <class 'str'>.") | |||
| test_invalid_input("invalid contral_freq parameter type as a String", 44100, 50.0, "200", 0.707, TypeError, | |||
| "Argument central_freq with value 200 is not of type [<class 'float'>, <class 'int'>]," | |||
| " but got <class 'str'>.") | |||
| test_invalid_input("invalid Q parameter type as a String", 44100, 50.0, 200, "0.707", TypeError, | |||
| "Argument Q with value 0.707 is not of type [<class 'float'>, <class 'int'>]," | |||
| " but got <class 'str'>.") | |||
| test_invalid_input("invalid sample_rate parameter value", 441324343243242342345300, 50.0, 200, 0.707, ValueError, | |||
| "Input sample_rate is not within the required interval of [-2147483648, 2147483647].") | |||
| test_invalid_input("invalid gain parameter value", 44100, 32434324324234321, 200, 0.707, ValueError, | |||
| "Input gain is not within the required interval of [-16777216, 16777216].") | |||
| test_invalid_input("invalid contral_freq parameter value", 44100, 50, 32434324324234321, 0.707, ValueError, | |||
| "Input central_freq is not within the required interval of [-16777216, 16777216].") | |||
| test_invalid_input("invalid sample_rate parameter value", None, 50.0, 200, 0.707, TypeError, | |||
| "Argument sample_rate with value None is not of type [<class 'int'>], " | |||
| "but got <class 'NoneType'>.") | |||
| test_invalid_input("invalid gain parameter value", 44100, None, 200, 0.707, TypeError, | |||
| "Argument gain with value None is not of type [<class 'float'>, <class 'int'>], " | |||
| "but got <class 'NoneType'>.") | |||
| test_invalid_input("invalid central_rate parameter value", 44100, 50.0, None, 0.707, TypeError, | |||
| "Argument central_freq with value None is not of type [<class 'float'>, <class 'int'>]," | |||
| " but got <class 'NoneType'>.") | |||
| test_invalid_input("invalid sample_rate parameter value", 0, 50.0, 200, 0.707, ValueError, | |||
| "Input sample_rate can not be 0.") | |||
| test_invalid_input("invalid Q parameter value", 44100, 50.0, 200, 1.707, ValueError, | |||
| "Input Q is not within the required interval of (0, 1].") | |||
| if __name__ == '__main__': | |||
| test_func_bass_biquad_eager() | |||
| test_func_bass_biquad_pipeline() | |||
| test_invalid_invalid_input() | |||