2015-06-01 17 views
14

के रूप में WAV ऑडियो स्तर खेलना चाहते हैं मैं एक बोलने वाला मुंह बनाना चाहता हूं जो एक चलती WAV फ़ाइल ध्वनि के दौरान प्रकाश या कुछ को स्थानांतरित या उत्सर्जित करता है। तो मुझे यह पता लगाने की ज़रूरत है कि जब एक WAV फ़ाइल बोल रही है या जब यह शब्दों के बीच एक मौन में है। वर्तमान में मैं एक pygame स्क्रिप्ट है कि मैंआउटपुट

import pygame 
pygame.mixer.init() 
pygame.mixer.music.load("my_sentence.wav") 
pygame.mixer.music.play() 
while pygame.mixer.music.get_busy() == True: 
    continue 

पाया है मुझे लगता है कि मैं कुछ देर के पाश ध्वनियों उत्पादन स्तर, या ऐसा ही कुछ देखने के लिए पर जाँच कर सकता है, और फिर से एक के लिए भेज उपयोग कर रहा हूँ जीपीओ आउटपुट। लेकिन मुझे नहीं पता कि इसे कैसे प्राप्त किया जाए।

किसी भी मदद की बहुत

+0

मेरे लिए यह रास्पबेरी पीई एसई के लिए एक प्रश्न की तरह लगता है ... मुझे नहीं पता कि यह क्यों माइग्रेट किया गया था। – NULL

+0

अगर मैं "music.get_busy() == True" खंड के दौरान समझता हूं, तो .wav फ़ाइल चलने पर इसे निष्पादित किया जाएगा। तो आप अपने मोटर कमांड को लूप लूप में डाल देंगे ... सही ... या क्या मुझे कुछ याद आ रहा है? उत्तर के लिए – NULL

+0

धन्यवाद @NULL। 'music.get_busy() == सही 'सच होगा, क्योंकि ध्वनि अंत तक शुरू होती है। लेकिन मैं शब्दों के बीच चुप्पी का पता लगाना चाहता हूं, मैं हर समय मुंह से गुजरना नहीं चाहता हूं। जब वाक्य मौन में है, मैं हिलना बंद करना चाहता हूं। – cor

उत्तर

7

आप बाहर काम करने के लिए जब आवाज मौजूद है WAV फ़ाइल का निरीक्षण करने की आवश्यकता होगी की सराहना की जाएगी। ऐसा करने का सबसे आसान तरीका जोरदार और शांत अवधि की तलाश में है। चूंकि ध्वनि तरंगों के साथ काम करता है, जब यह शांत होता है तो लहर फ़ाइल में मान बहुत अधिक नहीं बदलेगा, और जब यह ज़ोरदार होगा तो वे बहुत बदल जाएंगे।

जोर से अनुमान लगाने का एक तरीका variance है। जैसा कि आप लेख देख सकते हैं, इसे E[(X - mu)^2] के रूप में परिभाषित किया जा सकता है, जिसे average((X - average(X))^2) लिखा जा सकता है। यहां, एक्स किसी दिए गए बिंदु पर सिग्नल का मान है (WAV फ़ाइल में संग्रहीत मान, जिसे कोड में sample कहा जाता है)। यदि यह बहुत बदल रहा है, तो भिन्नता बड़ी होगी।

यह आपको एक पूरी फ़ाइल की जोर से गणना करने देगा। हालांकि, आप ट्रैक करना चाहते हैं कि किसी भी समय फ़ाइल कितनी जोरदार है, जिसका अर्थ है कि आपको moving average का एक रूप चाहिए। इसे पाने का एक आसान तरीका first-order low-pass filter के साथ है।

मैंने नीचे दिए गए कोड का परीक्षण नहीं किया है, इसलिए यह काम करने की बेहद असंभव है, लेकिन इसे शुरू करना चाहिए। यह डब्ल्यूएवी फ़ाइल लोड करता है, माध्य और भिन्नता को ट्रैक करने के लिए निम्न-पास फ़िल्टर का उपयोग करता है, और जब भिन्नता एक निश्चित दहलीज के ऊपर और नीचे जाती है तो काम करता है। फिर, डब्ल्यूएवी फ़ाइल खेलते समय यह उस समय का ट्रैक रखता है जब से यह खेलना शुरू कर देता है, और प्रिंट करता है कि डब्ल्यूएवी फ़ाइल ज़ोरदार या शांत है या नहीं।

यहाँ आप अभी भी करने के लिए आवश्यकता हो सकती है क्या करना है: कोड में

  • फिक्स सब मेरी जानबूझकर गलतियों
  • जोर/शांत परिवर्तन
  • बदलें सीमा और करने के लिए reaction_time पर प्रतिक्रिया करने के लिए कुछ उपयोगी जोड़े प्राप्त अपने ऑडियो के साथ अच्छे परिणाम
  • प्रकाश झिलमिलाते को रोकने के लिए कुछ hysteresis (एक चर दहलीज) जोड़े

मुझे आशा है कि इससे मदद मिलती है!

import wave 
import struct 
import time 

def get_loud_times(wav_path, threshold=10000, time_constant=0.1): 
    '''Work out which parts of a WAV file are loud. 
     - threshold: the variance threshold that is considered loud 
     - time_constant: the approximate reaction time in seconds''' 

    wav = wave.open(wav_path, 'r') 
    length = wav.getnframes() 
    samplerate = wav.getframerate() 

    assert wav.getnchannels() == 1, 'wav must be mono' 
    assert wav.getsampwidth() == 2, 'wav must be 16-bit' 

    # Our result will be a list of (time, is_loud) giving the times when 
    # when the audio switches from loud to quiet and back. 
    is_loud = False 
    result = [(0., is_loud)] 

    # The following values track the mean and variance of the signal. 
    # When the variance is large, the audio is loud. 
    mean = 0 
    variance = 0 

    # If alpha is small, mean and variance change slower but are less noisy. 
    alpha = 1/(time_constant * float(sample_rate)) 

    for i in range(length): 
     sample_time = float(i)/samplerate 
     sample = struct.unpack('<h', wav.readframes(1)) 

     # mean is the average value of sample 
     mean = (1-alpha) * mean + alpha * sample 

     # variance is the average value of (sample - mean) ** 2 
     variance = (1-alpha) * variance + alpha * (sample - mean) ** 2 

     # check if we're loud, and record the time if this changes 
     new_is_loud = variance > threshold 
     if is_loud != new_is_loud: 
      result.append((sample_time, new_is_loud)) 
     is_loud = new_is_loud 

    return result 

def play_sentence(wav_path): 
    loud_times = get_loud_times(wav_path) 
    pygame.mixer.music.load(wav_path) 

    start_time = time.time() 
    pygame.mixer.music.play() 

    for (t, is_loud) in loud_times: 
     # wait until the time described by this entry 
     sleep_time = start_time + t - time.time() 
     if sleep_time > 0: 
      time.sleep(sleep_time) 

     # do whatever 
     print 'loud' if is_loud else 'quiet' 
+0

पर खोला गया हूं, आपका उत्तर बहुत अच्छा लग रहा है, मैं इसे फिर से पढ़ूंगा और अगले दिन कोड आज़माउंगा। धन्यवाद! ;) – cor

+0

मैंने इसे समुदाय विकी बना दिया है, इसलिए उम्मीद है कि इसका मतलब है कि आप इसे किसी भी फिक्स के साथ संपादित कर सकते हैं। सौभाग्य! –