[Add] support for prepending data prefix
State: closed | Pull request: yes

# Add support for prepending data prefix to manifests paths and `audio_paths`

This feature is to add support for automatically adding prefix to manifest paths as well as the `audio_filepath` field in the manifest. The simple trick is by adding a `data_prefix` in the top level of your yaml config file. The program has a default value of `None` for  `data_prefix`, so that it's compatible with all previous config files.

# Features
- Adding single prefix to all input manifests. Each train/val/test dataset can have their own data prefix.
- Add different prefix to different input manifests, where the number of specified prefix must match the number of input manifests.
- Fully compatible with previous manifest, since `data_prefix=None` by default.

# Why Data Prefix?

Consider the following dataset folder:
```
/home/steve/libri_speech/
----------------------------->: train_manifest.json
----------------------------->: wav/
------------------------------------->: 11111.wav
------------------------------------->: 22222.wav
```
and the content of ` train_manifest.json` is:
```
{"audio_filepath": "/home/steve/libri_speech/wav/11111.wav", duration: "2.3",  "text": "one one one one one"}
```

If say, Kevin, wants to use my dataset on his project by copying my folder : `cp -r /home/steve/libri_speech/  /home/kevin/`, then he must also change all the `audio_filepath` in  the manifest `/home/steve/libri_speech/train_manifest.json`, which is certainly a tedious work.

However, if we allow `audio_filepath` to be relative paths to the data folder, then we can have a more flexible `train_manifest.json`:
```
{"audio_filepath": "wav/11111.wav", duration: "2.3",  "text": "one one one one one"}
```

Also, when added with a `data_prefix`, we can move the dataset to anywhere without modifying the manifest. For example, all Kevin has to do is simply:
```
python train.py \
    --config-path=../conf/conformer --config-name=config \ 
    model.train_ds.data_prefix=/home/kevin/libri_speech \
    model.train_ds.manifest_filepath="train_manifest.json"
```

And the program will automatically resolve the path for manifest as `/home/kevin/libri_speech/train_manifest.json`, and all `audio_filepath` in the manifest will also be added with the prefix: 
```
{"audio_filepath": "wav/11111.wav", duration: "2.3",  "text": "one one one one one"}
becomes
{"audio_filepath": "/home/kevin/libri_speech/wav/11111.wav", duration: "2.3",  "text": "one one one one one"}

```

# Example Usage

Take the `examples/asr/conf/config.yaml` as an example. We just need to add `data_prefix` as follows:
```yaml
name: &name "QuartzNet15x5"
sample_rate: &sample_rate 16000
repeat: &repeat 1
dropout: &dropout 0.0
separable: &separable true
labels: &labels [" ", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
         "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "'"]

data_prefix: null

model:
  train_ds:
    data_prefix: null
    manifest_filepath: ???
    .......(other params)

  validation_ds:
    data_prefix: null
    manifest_filepath: ???
    ......(other params)
```

Then suppose the data folder is `/home/heh/libri_speech`, and the `audio_filepath` are relative paths to the data folder, we can run the program by:

```bash
python speech_to_text_ctc.py \
    --config-path=../conf --config-name=config \
    model.train_ds.data_prefix="/home/heh/libri_speech" \
    model.train_ds.manifest_filepath="train_manifest.json" \
    model.validation_ds.data_prefix="/home/heh/libri_speech" \
    model.validation_ds.manifest_filepath="train_manifest.json" \
    trainer.devices=2 \
    trainer.max_epochs=2 \
```

# Change Log
- [5/10/2022] Modified config example: remove global `data_prefix`, and let `model.train_ds`, `model.validation_ds` and `model.test_ds` have their own `data_prefix`.
- [5/10/2022] Prioritize absolute path for manifest over relative path resolution. Now the `item_iter()` first try to locate the original manifest file, and will try to prepend `data_prefix` to the manifest path only if the file is not found at the original manifest path.

# Suggested Future Change
- In data downloading scripts, change all absolute `audio_filepath` to relative paths.