2016-04-06 2 views
11

Je me sens comme c'est un problème assez commun, mais je n'ai pas encore trouvé une réponse appropriée. J'ai beaucoup de fichiers audio de discours humain que je voudrais casser sur les mots, ce qui peut être fait heuristiquement en regardant les pauses dans la forme d'onde, mais quelqu'un peut-il me diriger vers une fonction/bibliothèque en python qui le fait automatiquement?Diviser le fichier audio de la parole sur les mots en python

+2

Vous êtes à la recherche [ 'SpeechRecognition'] (https://pypi.python.org/pypi/SpeechRecognition/), qui a explicitement un exemple dédié à la [transcription de fichiers audio] (https://github.com/Uberi/speech_recognition/blob/master/examples/audio_transcribe.py). La prochaine fois, Google d'abord :) –

+1

Je n'ai pas demandé une fonction qui peut transcrire, mais plutôt scinder un fichier audio sur les mots, qui, bien que peut-être implicite dans la transcription, n'est pas la même chose. Je connais le package SpeechRecognition. – user3059201

+0

Il n'y a pas de frontières entre les mots dans le discours réel, vous dites "comment allez-vous" comme un seul morceau sans indices acoustiques. Si vous voulez séparer les mots, vous devez les transcrire. –

Répondre

2

Vous pouvez regarder Audiolab Il fournit une API décent pour convertir les échantillons vocaux en numpy tableaux. Le module Audiolab utilise la bibliothèque libsndfile C++ pour effectuer le gros du travail.

Vous pouvez ensuite analyser les tableaux pour trouver les valeurs les plus basses afin de trouver les pauses.

9

Un moyen plus simple de faire cela est d'utiliser le module pydub. ajout récent de silent utilities fait tout le levage lourd tels que setting up silence threahold, setting up silence length. etc et simplifie le code de manière significative par opposition aux autres méthodes mentionnées.

Voici une implémentation de démonstration, l'inspiration de here

Configuration:

j'avais un fichier audio avec des lettres anglais parlé de A à Z dans le fichier "a-z.wav". Un sous-répertoire splitAudio a été créé dans le répertoire de travail en cours. Lors de l'exécution du code de démonstration, les fichiers ont été divisés en 26 fichiers distincts avec chaque fichier audio stockant chaque syllabe.

Observations: Certaines des syllabes ont été coupées, nécessitant éventuellement la modification des paramètres suivants,
min_silence_len=500
silence_thresh=-16

On peut vouloir régler ces à sa propre exigence.

Code Demo:

from pydub import AudioSegment 
from pydub.silence import split_on_silence 

sound_file = AudioSegment.from_wav("a-z.wav") 
audio_chunks = split_on_silence(sound_file, 
    # must be silent for at least half a second 
    min_silence_len=500, 

    # consider it silent if quieter than -16 dBFS 
    silence_thresh=-16 
) 

for i, chunk in enumerate(audio_chunks): 

    out_file = ".//splitAudio//chunk{0}.wav".format(i) 
    print "exporting", out_file 
    chunk.export(out_file, format="wav") 

Sortie:

Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32 
Type "copyright", "credits" or "license()" for more information. 
>>> ================================ RESTART ================================ 
>>> 
exporting .//splitAudio//chunk0.wav 
exporting .//splitAudio//chunk1.wav 
exporting .//splitAudio//chunk2.wav 
exporting .//splitAudio//chunk3.wav 
exporting .//splitAudio//chunk4.wav 
exporting .//splitAudio//chunk5.wav 
exporting .//splitAudio//chunk6.wav 
exporting .//splitAudio//chunk7.wav 
exporting .//splitAudio//chunk8.wav 
exporting .//splitAudio//chunk9.wav 
exporting .//splitAudio//chunk10.wav 
exporting .//splitAudio//chunk11.wav 
exporting .//splitAudio//chunk12.wav 
exporting .//splitAudio//chunk13.wav 
exporting .//splitAudio//chunk14.wav 
exporting .//splitAudio//chunk15.wav 
exporting .//splitAudio//chunk16.wav 
exporting .//splitAudio//chunk17.wav 
exporting .//splitAudio//chunk18.wav 
exporting .//splitAudio//chunk19.wav 
exporting .//splitAudio//chunk20.wav 
exporting .//splitAudio//chunk21.wav 
exporting .//splitAudio//chunk22.wav 
exporting .//splitAudio//chunk23.wav 
exporting .//splitAudio//chunk24.wav 
exporting .//splitAudio//chunk25.wav 
exporting .//splitAudio//chunk26.wav 
>>> 
3

Utilisez IBM STT. En utilisant timestamps=true vous obtiendrez le mot rompre avec quand le système les détecte pour avoir été parlé.

Il ya beaucoup d'autres fonctionnalités intéressantes comme word_alternatives_threshold pour obtenir d'autres possibilités de mots et word_confidence pour obtenir la confiance avec laquelle le système prédit le mot. Réglez word_alternatives_threshold entre (0,1 et 0,01) pour avoir une idée réelle.

Cela nécessite une connexion, à la suite de laquelle vous pouvez utiliser le nom d'utilisateur et mot de passe généré. L'IBM STT fait déjà partie du module de reconnaissance vocale mentionné, mais pour obtenir le mot timestamp, vous devrez modifier la fonction.

Un extrait et une forme modifiée ressemble:

def extracted_from_sr_recognize_ibm(audio_data, username=IBM_USERNAME, password=IBM_PASSWORD, language="en-US", show_all=False, timestamps=False, 
           word_confidence=False, word_alternatives_threshold=0.1): 
    assert isinstance(username, str), "``username`` must be a string" 
    assert isinstance(password, str), "``password`` must be a string" 

    flac_data = audio_data.get_flac_data(
     convert_rate=None if audio_data.sample_rate >= 16000 else 16000, # audio samples should be at least 16 kHz 
     convert_width=None if audio_data.sample_width >= 2 else 2 # audio samples should be at least 16-bit 
    ) 
    url = "https://stream-fra.watsonplatform.net/speech-to-text/api/v1/recognize?{}".format(urlencode({ 
     "profanity_filter": "false", 
     "continuous": "true", 
     "model": "{}_BroadbandModel".format(language), 
     "timestamps": "{}".format(str(timestamps).lower()), 
     "word_confidence": "{}".format(str(word_confidence).lower()), 
     "word_alternatives_threshold": "{}".format(word_alternatives_threshold) 
    })) 
    request = Request(url, data=flac_data, headers={ 
     "Content-Type": "audio/x-flac", 
     "X-Watson-Learning-Opt-Out": "true", # prevent requests from being logged, for improved privacy 
    }) 
    authorization_value = base64.standard_b64encode("{}:{}".format(username, password).encode("utf-8")).decode("utf-8") 
    request.add_header("Authorization", "Basic {}".format(authorization_value)) 

    try: 
     response = urlopen(request, timeout=None) 
    except HTTPError as e: 
     raise sr.RequestError("recognition request failed: {}".format(e.reason)) 
    except URLError as e: 
     raise sr.RequestError("recognition connection failed: {}".format(e.reason)) 
    response_text = response.read().decode("utf-8") 
    result = json.loads(response_text) 

    # return results 
    if show_all: return result 
    if "results" not in result or len(result["results"]) < 1 or "alternatives" not in result["results"][0]: 
     raise Exception("Unknown Value Exception") 

    transcription = [] 
    for utterance in result["results"]: 
     if "alternatives" not in utterance: 
      raise Exception("Unknown Value Exception. No Alternatives returned") 
     for hypothesis in utterance["alternatives"]: 
      if "transcript" in hypothesis: 
       transcription.append(hypothesis["transcript"]) 
    return "\n".join(transcription)