Repository: speechbrain/speechbrain

Issue:
VAD.get_boundaries RuntimeError: shape '[-1, 2]' is invalid for input of size 5
Hello,
the code:
```
VAD = VAD.from_hparams(source="speechbrain/vad-crdnn-libriparty", savedir="pretrained_models/vad-crdnn-libriparty")
prob_chunks = VAD.get_speech_prob_file(audio_file)
prob_th = VAD.apply_threshold(prob_chunks, activation_th=0.5, deactivation_th=0.25).float()
boundaries = VAD.get_boundaries(prob_th)
VAD.save_boundaries(boundaries, audio_file=audio_file)
```
reports runtime error in `boundaries = VAD.get_boundaries(prob_th)`,
`indexes = (prob_th == 1).nonzero()[:, 1].reshape(-1, 2)
RuntimeError: shape '[-1, 2]' is invalid for input of size 5`

I found that when reporting this error, the number of nonzero elements in (prob_th==1) is odd (which should be even) , and the last element of `prob_th` is 1.     Should the last element be set to 0 when there're odd nonzero elements?

The audio prob figure is below:
[
![6850070556935454723_2_prob](https://user-images.githubusercontent.com/14331395/141082834-25a02799-67eb-420d-acb9-f3181568d79b.jpg)
](url)

And the audio threshold figure is below:
[
![6850070556935454723_2_threshold](https://user-images.githubusercontent.com/14331395/141082979-a5281a7e-0398-40cc-9af0-cfac92694621.jpg)
](url)

Best regards!


Discussion:
Hi @devotedtaylorm,
thank for reporting this potential issue and sorry for my late reply.  Unfortunately, I'm not able to replicate it. Could you please share the audio_file that triggers this issue?

Also, are you sure you are using the latest version of the code? These [lines](https://github.com/mravanelli/speechbrain-1/blob/develop/speechbrain/pretrained/interfaces.py#L1337) seems to address edge cases.
> Hi @devotedtaylorm, thank for reporting this potential issue and sorry for my late reply. Unfortunately, I'm not able to replicate it. Could you please share the audio_file that triggers this issue?

Sorry, I couldn't share the audio_file due to privacy, but I could retrieve the ffmpeg information as below:
![111](https://user-images.githubusercontent.com/14331395/147744636-54c11a1a-748b-455e-ad58-f20c951a05ea.png)


> Also, are you sure you are using the latest version of the code? These [lines](https://github.com/mravanelli/speechbrain-1/blob/develop/speechbrain/pretrained/interfaces.py#L1337) seems to address edge cases.

I'm using speechbrain version 0.5.1, and these lines are included in the 0.5.1 version.
I tried to solve this problem by adding below codes in function _get_boundaries()_
![image](https://user-images.githubusercontent.com/14331395/147747228-e63fcf27-eea3-4fe4-829c-e359bbc8e2b9.png)
Then I'm able to get the result, but I'm not sure whether I get a correct one.

Unfortunately, I'm also running into this problem, and I sadly can't share any of my example files where this occurs.
Hello, I am also facing this problem. 

The current code can only provide an even number of bounds, so if the audio ends with speech (start bound but no end bound), then the code breaks.

Here is a short code snippet to replicate the problem.

```python
import torch

# Simulate fame-level binary decision
prob_th = torch.zeros(1, 15, 1)
prob_th[:,5:10,:] = 1

# Simulate speech in final frames: commenting the following two lines the problem is avoided.
prob_th[:,-1,:] = 1
prob_th[:,-2,:] = 1
print(prob_th)

# Shifting frame-levels binary decision by 1
# This allows detecting changes in speech/non-speech activities
prob_th_shifted = torch.roll(prob_th, dims=1, shifts=1)
prob_th_shifted[:, 0, :] = 0
prob_th = prob_th + prob_th_shifted

# Needed to first and last time step
prob_th[:, 0, :] = (prob_th[:, 0, :] >= 1).int()
prob_th[:, -1, :] = (prob_th[:, -1, :] >= 1).int()

# Fix edge cases (when a new sentence starts in the last frame)
if prob_th[:, -1, :] == 1 and prob_th[:, -2, :] == 1:
    prob_th[:, -2, :] = 2

if prob_th[:, -1, :] == 1 and prob_th[:, -2, :] == 0:
    prob_th[:, -2, :] = 1

print(prob_th)

# FIXME: Where prob_th is 1 there is a change
print((prob_th == 1).nonzero()[:, 1])
indexes = (prob_th == 1).nonzero()[:, 1].reshape(-1, 2)
```

Resolving patch:
diff --git a/speechbrain/pretrained/interfaces.py b/speechbrain/pretrained/interfaces.py
--- a/speechbrain/pretrained/interfaces.py
+++ b/speechbrain/pretrained/interfaces.py
@@ -1286,12 +1286,11 @@ def get_boundaries(self, prob_th, output_value="seconds"):
         prob_th[:, 0, :] = (prob_th[:, 0, :] >= 1).int()
         prob_th[:, -1, :] = (prob_th[:, -1, :] >= 1).int()
 
-        # Fix edge cases (when a new sentence starts in the last frame)
-        if prob_th[:, -1, :] == 1 and prob_th[:, -2, :] == 1:
-            prob_th[:, -2, :] = 2
-
-        if prob_th[:, -1, :] == 1 and prob_th[:, -2, :] == 0:
-            prob_th[:, -2, :] = 1
+        # Fix edge cases (when a speech starts in the last frames)
+        if (prob_th == 1).nonzero().shape[0] % 2 == 1:
+            prob_th = torch.cat(
+                (prob_th, torch.Tensor([1.0]).unsqueeze(0).unsqueeze(2)), dim=1
+            )
 
         # Where prob_th is 1 there is a change
         indexes = (prob_th == 1).nonzero()[:, 1].reshape(-1, 2)


Test patch: