| 383 | } |
| 384 | |
| 385 | VARP spectrogram(VARP waveform, const SpectrogramParams *params) { |
| 386 | int pad_left = 0, pad_right = 0, pad_mode = REFLECT; |
| 387 | int n_fft = 400, hop_length = 0, win_length = 0, window_type = HANNING; |
| 388 | bool center = false, normalized = false; |
| 389 | float power = 2.0; |
| 390 | if (params) { |
| 391 | pad_left = params->pad_left; |
| 392 | pad_right = params->pad_right; |
| 393 | center = params->center; |
| 394 | pad_mode = params->pad_mode; |
| 395 | n_fft = params->n_fft; |
| 396 | hop_length = params->hop_length; |
| 397 | win_length = params->win_length; |
| 398 | window_type = params->window_type; |
| 399 | normalized = params->normalized; |
| 400 | power = params->power; |
| 401 | } |
| 402 | if (pad_left > 1 || pad_right > 1) { |
| 403 | waveform = MNN::Express::_Pad(waveform, _var<int>({pad_left, pad_right}, {2}), MNN::Express::CONSTANT); |
| 404 | } |
| 405 | if (center) { |
| 406 | waveform = MNN::Express::_Pad(waveform, _var<int>({n_fft / 2, n_fft / 2}, {2}), static_cast<MNN::Express::PadValueMode>(pad_mode)); |
| 407 | } |
| 408 | waveform = _Reshape(waveform, {1, -1, 1}); |
| 409 | hop_length = hop_length ? hop_length : n_fft / 2; |
| 410 | win_length = win_length ? win_length : n_fft; |
| 411 | VARP window; |
| 412 | switch (window_type) { |
| 413 | case HANNING: |
| 414 | window = hann_window(win_length); |
| 415 | break; |
| 416 | case HAMMING: |
| 417 | window = hamming_window(win_length); |
| 418 | break; |
| 419 | default: |
| 420 | window = hann_window(win_length); |
| 421 | break; |
| 422 | } |
| 423 | std::unique_ptr<OpT> op(new OpT); |
| 424 | op->type = OpType_Stft; |
| 425 | op->main.type = OpParameter_StftParam; |
| 426 | auto param = new StftParamT; |
| 427 | param->abs = true; |
| 428 | op->main.value = param; |
| 429 | EXPRP stftexpr = Expr::create(std::move(op), {waveform, _Scalar<int>(hop_length), window}); |
| 430 | int frame_size = win_length > 0 ? win_length : n_fft; |
| 431 | int nstfts = ((waveform->getInfo()->dim[1] - frame_size) / hop_length) + 1; |
| 432 | int dft_unique_bins = n_fft / 2 + 1; |
| 433 | auto specgram = MNN::Express::Variable::create(stftexpr); |
| 434 | specgram = _Square(specgram); |
| 435 | auto startsDims = std::vector<int>{0, 0, 0, 0}; |
| 436 | auto starts1Dims = std::vector<int>{0, 0, 0, 1}; |
| 437 | auto sizeDims = std::vector<int>{1, nstfts, dft_unique_bins, 1}; |
| 438 | auto startVar = _Const(startsDims.data(), {4}, NCHW, halide_type_of<int>()); |
| 439 | auto start1Var = _Const(starts1Dims.data(), {4}, NCHW, halide_type_of<int>()); |
| 440 | auto sizeVar = _Const(sizeDims.data(), {4}, NCHW, halide_type_of<int>()); |
| 441 | auto specgramReal = _Slice(specgram, startVar, sizeVar); |
| 442 | auto specgramVirt = _Slice(specgram, start1Var, sizeVar); |
no test coverage detected