Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multiprocessing bug #84

Open
jbaumgarten opened this issue Aug 28, 2022 · 1 comment
Open

multiprocessing bug #84

jbaumgarten opened this issue Aug 28, 2022 · 1 comment

Comments

@jbaumgarten
Copy link

jbaumgarten commented Aug 28, 2022

Sir, Madam,

I may need some help in order to use webrtcvad in multiprocess environment.
I'm working with pcm alaw audio which are converted in linear pcm for analysis purpose. Before processing the analysis, I'm using webrtcvad library in order to detect silences. Everything is ok if I'm doing one analysis at a time but as long I'm doing several silence detection at a time it fails.

The following code detect the silences:

import asyncio
import audioop
import concurrent.futures
import os
import webrtcvad

n = int(16000 * (30 / 1000.0) * 2)
vad = webrtcvad.Vad(2)

file1_name = "44022"
file2_name = "44024"

def process_chunk(data, file):
    while len(data) >= n:
        audio_30ms = data[0:n]
        data = data[n:]
        is_speech = vad.is_speech(audio_30ms, 16000)
        print(f"{file} - Is speech? {'true' if is_speech else 'false'}")


async def file1(pool):
    loop = asyncio.get_running_loop()
    f = open(f"{file1_name}-1.raw", "rb")
    data = f.read(960)
    while data:
        audioop.alaw2lin(data, 2)
        data = audioop.ratecv(data, 2, 1, 8000, 16000, None)[0]
        await loop.run_in_executor(pool, process_chunk, data, file1_name)
        data = f.read(960)


async def file2(pool):
    loop = asyncio.get_running_loop()
    f = open(f"{file2_name}-1.raw", "rb")
    data = f.read(960)
    while data:
        audioop.alaw2lin(data, 2)
        data = audioop.ratecv(data, 2, 1, 8000, 16000, None)[0]
        await loop.run_in_executor(pool, process_chunk, data, file2_name)
        data = f.read(960)


async def test():
    pool = concurrent.futures.ThreadPoolExecutor((os.cpu_count() or 1))
    await file1(pool)
    await file2(pool)


if __name__ == '__main__':
    asyncio.run(test())

The following doesn't detect the silences

import asyncio
import audioop
import concurrent.futures
import os
import webrtcvad

n = int(16000 * (30 / 1000.0) * 2)
vad = webrtcvad.Vad(2)

file1_name = "44022"
file2_name = "44024"

def process_chunk(data, file):
    while len(data) >= n:
        audio_30ms = data[0:n]
        data = data[n:]
        is_speech = vad.is_speech(audio_30ms, 16000)
        print(f"{file} - Is speech? {'true' if is_speech else 'false'}")


async def file1(pool):
    loop = asyncio.get_running_loop()
    f = open(f"{file1_name}-1.raw", "rb")
    data = f.read(960)
    while data:
        audioop.alaw2lin(data, 2)
        data = audioop.ratecv(data, 2, 1, 8000, 16000, None)[0]
        await loop.run_in_executor(pool, process_chunk, data, file1_name)
        data = f.read(960)


async def file2(pool):
    loop = asyncio.get_running_loop()
    f = open(f"{file2_name}-1.raw", "rb")
    data = f.read(960)
    while data:
        audioop.alaw2lin(data, 2)
        data = audioop.ratecv(data, 2, 1, 8000, 16000, None)[0]
        await loop.run_in_executor(pool, process_chunk, data, file2_name)
        data = f.read(960)


async def test():
    pool = concurrent.futures.ThreadPoolExecutor((os.cpu_count() or 1))
    await asyncio.gather(file1(pool), file2(pool))


if __name__ == '__main__':
    asyncio.run(test())

Did I miss something?

I also added some logs to display the buffer which is analized, and in both case, the buffer is the same

audio.zip

@jbaumgarten
Copy link
Author

jbaumgarten commented Aug 28, 2022

Another strange thing. The following source code


vad = webrtcvad.Vad(2)

audio_30ms = b'\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5'
is_speech = vad.is_speech(audio_30ms, 16000)
print(f"Is speech? {'true' if is_speech else 'false'}")
is_speech = vad.is_speech(audio_30ms, 16000)
print(f"Is speech? {'true' if is_speech else 'false'} --> {audio_30ms}")
is_speech = vad.is_speech(audio_30ms, 16000)
print(f"Is speech? {'true' if is_speech else 'false'} --> {audio_30ms}")
is_speech = vad.is_speech(audio_30ms, 16000)
print(f"Is speech? {'true' if is_speech else 'false'} --> {audio_30ms}")
is_speech = vad.is_speech(audio_30ms, 16000)
print(f"Is speech? {'true' if is_speech else 'false'} --> {audio_30ms}")
is_speech = vad.is_speech(audio_30ms, 16000)
print(f"Is speech? {'true' if is_speech else 'false'} --> {audio_30ms}")
is_speech = vad.is_speech(audio_30ms, 16000)
print(f"Is speech? {'true' if is_speech else 'false'} --> {audio_30ms}")

The output

Is speech? true
Is speech? true
Is speech? false
Is speech? false
Is speech? false
Is speech? false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant