Fix normalization of impulse response in ImpulsePerturbation
State: closed | Pull request: yes
Labels: name: ASR

# What does this PR do?

Current impulse response (IR) in `ImpulsePerturbation` is not correct.
This PR fixes the issue.

Check below for
1. Audio examples
2. IR examples
3. Scripts to reproduce the issue

**Collection**: ASR

# Changelog 
- Fixed normalization to correctly normalize mean and max
- Added a new flag to make IR normalization optional
- Default to not using impulse normalization
    1. This doesn't negatively impact the current behavior, since currently IR is incorrectly normalized
    2. Normalization is in general not necessary for IRs, especially since output data is normalized to max amplitude 1
    3. If necessary, normalization can be turned on to remove the mean from the IR.
- fixed convolution and impulse shifting
    - `shift_impulse=False` used `same` convolution, which centered the output with respect to `full`. This resulted in an output which was not aligned with the RIR. This is now done by computing the full convolution and trimming the output. This is a bugfix.
    - `shift_impulse=True` used trimmed RIR. This is now done by convolving with the full RIR and shifting the output. This is a minor change.

# Detailed description

Current impulse response (IR) in `ImpulsePerturbation` is not correct.
More specifically, it introduces a DC offset in the normalized IR, resulting in an incorrect signal.
It's obvious from listening to the output audio that it doesn't correspond to a realistic IR.

## Example scripts

* [rir_normalization_issue_example.zip](https://github.com/NVIDIA/NeMo/files/11339425/rir_normalization_issue_example.zip)

To run, unpack the archive and run
```python
python example.py
```

## RIR example

This figure shows an original IR, the normalized IR with the current normalization and the normalized IR with the new normalization (in this PR).

The current normalization introduces a large DC offset.
The new normalization makes the RIR zero mean, and scales the max amplitude to 1.

![IRs](https://user-images.githubusercontent.com/108555623/234754895-c8e17fc0-30ea-462d-82c4-6e3c468a25ee.png)

## Audio examples

### Output audio with the current normalization
* [output_cur.wav.zip](https://github.com/NVIDIA/NeMo/files/11339429/output_cur.wav.zip)

![output_cur](https://user-images.githubusercontent.com/108555623/234756068-fdaf098d-20f2-4fb0-b6d9-d9814c1c7f9c.png)

### Output audio with the new normalization
* [output_new.wav.zip](https://github.com/NVIDIA/NeMo/files/11339432/output_new.wav.zip)

![output_new](https://user-images.githubusercontent.com/108555623/234756156-d9fb5149-215b-47f6-86de-2dddf7ec28cd.png)

## Test with different setups

Scripts

[rir_normalization_issue_example_with_shift.zip](https://github.com/NVIDIA/NeMo/files/11346247/rir_normalization_issue_example_with_shift.zip)

In this example, the RIR introduces a 0.5 second delay.
This was artificially constructed to test the setup with `shift_impulse`.
We expect the following
- `shift_impulse=False`: The output should be delayed by 0.5s due to delay in the RIR
- `shift_impulse=True`: The output should not include the 0.5s delay

### Input signal
![test_class_input](https://user-images.githubusercontent.com/108555623/234936926-5aae837b-f614-43cc-aabf-7347c4b66c79.png)

### Output signals

|                                                  | `shift_impulse=False` | `shift_impulse=True` | 
| ---------------------------- | ---------------------- | --------------------- | 
| `normalize_impulse=False`  | ![test_class_output_normalize_False_shift_False](https://user-images.githubusercontent.com/108555623/234936056-8a9469e2-dab4-476b-8408-727dc76325fc.png) | ![test_class_output_normalize_False_shift_True](https://user-images.githubusercontent.com/108555623/234936172-66257b7f-63d9-439d-b0aa-346412d00240.png) |
| `normalize_impulse=True`   | ![test_class_output_normalize_True_shift_False](https://user-images.githubusercontent.com/108555623/234936227-ba935b3d-13cd-4032-8fbc-ab79b2049da0.png) | ![test_class_output_normalize_True_shift_True](https://user-images.githubusercontent.com/108555623/234936255-8073bead-9bee-4267-a9b0-8bd3546baba6.png) |


# Before your PR is "Ready for review"
**Pre checks**:
- [x] Make sure you read and followed [Contributor guidelines](https://github.com/NVIDIA/NeMo/blob/main/CONTRIBUTING.md)
- [ ] Did you write any new necessary tests?
- [x] Did you add or update any necessary documentation?
- [ ] Does the PR affect components that are optional to install? (Ex: Numba, Pynini, Apex etc)
  - [ ] Reviewer: Does the PR have correct import guards for all optional libraries?
  
**PR Type**:
- [ ] New Feature
- [x] Bugfix
- [ ] Documentation

If you haven't finished some of the above items you can still open "Draft" PR.


## Who can review?

Anyone in the community is free to review the PR once the checks have passed. 
[Contributor guidelines](https://github.com/NVIDIA/NeMo/blob/main/CONTRIBUTING.md) contains specific people who can review PRs to various areas.

# Additional Information
* Related to #6429