2013-02-22 59 views
9

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

मुझे मिले कई उदाहरण विज़ुअलाइज़र और ग्राफिकल सामान कर रहे हैं। मुझे बस एफएफटी डेटा चाहिए, और कुछ नहीं। मुझे ऑडियो डेटा प्राप्त करने की आवश्यकता है, और उस पर एक एफएफटी करें। मेरा अंत लक्ष्य सभी आवृत्तियों (भारित आयाम), बीपीएम, और शायद कुछ अन्य अच्छी विशेषताओं पर औसत/औसत/मोड, 25 वीं-प्रतिशत, और 75 वें-प्रतिशत की गणना करने के लिए कुछ अन्य चीजों की गणना करना है, बाद में समान ध्वनि को क्लस्टर करने में सक्षम होना ।

सबसे पहले मैं माणिक ऑडियो और fftw3 का उपयोग करने की कोशिश की, लेकिन मैं जाना दो वास्तव में एक साथ काम करने के लिए कभी नहीं। प्रलेखन अच्छा नहीं था इसलिए मुझे वास्तव में पता नहीं था कि डेटा किस प्रकार घूम रहा था। अगला मैंने bplay/ब्रेक का उपयोग करने की कोशिश की और मेरी रूबी स्क्रिप्ट को केवल STDIN का उपयोग करने के लिए सीमित करें और उस पर एक एफएफटी निष्पादित करें (अभी भी fftw3 का उपयोग कर)। लेकिन मुझे काम करने के लिए bplay/brec नहीं मिल सका क्योंकि सर्वर के पास ध्वनि कार्ड नहीं है और मैंने पहले ऑडियो डिवाइस पर जाने के बिना सीधे ऑडियो को STDOUT तक प्रबंधित करने का प्रबंधन नहीं किया था। तो अब मैं अटक कर रहा हूँ और गूगल पर किसी भी अधिक अच्छे परिणाम नहीं मिल सकता है

# extracting audio from wav with ruby-audio 
buf = RubyAudio::Buffer.float(1024) 
RubyAudio::Sound.open(fname) do |snd| 
    while snd.read(buf) != 0 
     # ??? 
    end 
end 

# performing FFT on audio 
def get_fft(input, window_size) 
    data = input.read(window_size).unpack("s*") 
    na = NArray.to_na(data) 
    fft = FFTW3.fft(na).to_a[0, window_size/2] 
    return fft 
end 

:

यहाँ निकटतम मैं मिल गया है है। तो शायद आप लोग मेरी मदद कर सकते हैं?

धन्यवाद!

+0

शायद यह पिछली चर्चा उपयोगी हो सकता है: http://stackoverflow.com/questions/2834548/ruby-play-pause-resume -एएसी-ऑडियो-फाइलें – fmendez

+0

क्या आप विस्तारित कर सकते हैं कि आप क्यों फंस गए हैं? चीजों को कैसे काम करना चाहिए, इस बारे में आपकी समझ में त्रुटि संदेश या अंतराल शामिल करें। –

+0

मैंने अभी तक अपना कोड जोड़ा है। रूबी-ऑडियो का उपयोग करके डेटा पढ़ने और fftw3 का उपयोग करके एफएफटी निकालने के बीच मेरे पास एक बड़ा अंतर है। तीन प्रश्न चिह्नों के साथ टिप्पणी देखें। मेरे पास बफ के अंदर WAV डेटा है लेकिन मुझे नहीं पता कि डेटा वास्तव में क्या है/प्रतिनिधित्व करता है। क्या वहां हेडर हैं? क्या यह संकुचित/एन्कोडेड है? इत्यादि, आदि। मैं डेटा को get_fft में प्राप्त करना चाहता हूं (जिसे किसी अन्य एसओ पोस्ट से लगभग वर्बैटिम लिया जाता है)। –

उत्तर

8

रैंडल कुक की सहायक सलाह के लिए बहुत कुछ धन्यवाद, जो मैं प्राप्त करने की कोशिश कर रहा था, उसका अंतिम समाधान यहां दिया गया है। कोड रूबी में ध्वनि तरंग और एक wav फ़ाइल के FFT निकालने के लिए:

require "ruby-audio" 
require "fftw3" 

fname = ARGV[0] 
window_size = 1024 
wave = Array.new 
fft = Array.new(window_size/2,[]) 

begin 
    buf = RubyAudio::Buffer.float(window_size) 
    RubyAudio::Sound.open(fname) do |snd| 
     while snd.read(buf) != 0 
      wave.concat(buf.to_a) 
      na = NArray.to_na(buf.to_a) 
      fft_slice = FFTW3.fft(na).to_a[0, window_size/2] 
      j=0 
      fft_slice.each { |x| fft[j] << x; j+=1 } 
     end 
    end 

rescue => err 
    log.error "error reading audio file: " + err 
    exit 
end 

# now I can work on analyzing the "fft" and "wave" arrays... 
+1

यह सही दिखता है। अपना कोड पोस्ट करने के लिए +1। मुझे खुशी है कि आप अनब्लॉक हो गए हैं और कुछ ऐसा काम कर सकते हैं जो काम करता है। बीटीडब्लू, स्टैक ओवरफ्लो पर धन्यवाद देने का एक शानदार तरीका है अगर आपने पहले से ऐसा नहीं किया है, तो उत्तर देने और/या एक उत्तर स्वीकार करना है। ;) –

+0

मैंने आपकी पोस्ट को ऊपर उठाया लेकिन मुझे अपना जवाब स्वीकार करने से पहले कुछ देर इंतजार करना पड़ा। :) –

+0

@ ChristofferBrodd-Reijer आपका कोड फिंगरप्रिंट WAV फ़ाइलों के लिए बहुत अच्छा काम करता है, लेकिन फिंगरप्रिंट बहुत बड़ा है। क्या आपको गति सुधारने और फिंगरप्रिंट को कम करने का समाधान मिला? –

7

मुझे लगता है कि यहां दो समस्याएं हैं। एक नमूने प्राप्त कर रहा है, दूसरा एफएफटी कर रहा है।

नमूने प्राप्त करने के लिए, दो मुख्य चरण हैं: डिकोडिंग और डाउनमैक्सिंग। WAV फ़ाइलों को डीकोड करने के लिए, आपको केवल हेडर को पार्स करने की आवश्यकता है ताकि आप नमूने की व्याख्या कैसे कर सकें। एमपी 3 फाइलों के लिए, आपको एक पूर्ण डिकोड करने की आवश्यकता होगी। एक बार ऑडियो डीकोड हो जाने पर, यदि आप स्टीरियो चैनलों को अलग से संसाधित करने में रूचि नहीं रखते हैं, तो आपको इसे मोनो में डाउनमैक्स करने की आवश्यकता हो सकती है, क्योंकि एफएफटी इनपुट के रूप में एक चैनल की अपेक्षा करता है। यदि आपको रुबी के बाहर उद्यम करने की कोई बात नहीं है, तो sox tool यह आसान बनाता है। उदाहरण के लिए sox song.mp3 -b 16 song.raw channels 1 को एक एमपी 3 को शुद्ध पीसीएम नमूने (यानी 16-बिट पूर्णांक) की एक मोनो फ़ाइल में परिवर्तित करना चाहिए। बीटीडब्ल्यू, एक त्वरित खोज ने ruby/audio लाइब्रेरी का खुलासा किया (शायद यह आपकी पोस्ट में उल्लिखित है)। यह बहुत अच्छा लग रहा है, खासकर जब से यह libsndfile लपेटता है।

एफएफटी करने के लिए, मुझे तीन विकल्प दिखाई देते हैं। एक कोड का this snippet उपयोग करना है जो एक एफएफटी करता है। मैं रूबी विशेषज्ञ नहीं हूं, लेकिन ऐसा लगता है कि यह ठीक हो सकता है। दूसरा विकल्प NArray का उपयोग करना है। इसमें एक अलग मॉड्यूल में उपलब्ध एफएफटीडब्लू सहित गणितीय तरीकों का एक टन है, जिसके लिए एक टैरबॉल है जिसके लिए नेरे पेज के बीच में जुड़ा हुआ है। तीसरा विकल्प अपना खुद का एफएफटी कोड लिखना है। यह एक विशेष रूप से जटिल एल्गोरिदम नहीं है, और रूबी में संख्यात्मक प्रसंस्करण के साथ आपको बहुत अच्छा अनुभव दे सकता है (यदि आपको इसकी आवश्यकता है)।

आप शायद इस बारे में जानते हैं, लेकिन एफएफटी जटिल इनपुट की अपेक्षा करता है और जटिल आउटपुट उत्पन्न करता है। ऑडियो संकेत वास्तविक हैं, इसलिए इनपुट का काल्पनिक घटक हमेशा शून्य होना चाहिए (a + 0*i)। चूंकि आपका इनपुट वास्तविक है, आउटपुट आउटपुट सरणी के मध्य बिंदु के बारे में सममित होगा। आप ऊपरी आधे को सुरक्षित रूप से अनदेखा कर सकते हैं। यदि आप किसी विशेष आवृत्ति बिन में ऊर्जा चाहते हैं (वे रैखिक रूप से आधा नमूना दर तक दूरी पर हैं), तो आपको जटिल मूल्य (sqrt(real*real + imag*imag)) की परिमाण की गणना करने की आवश्यकता होगी।

एक और बात: क्योंकि आवृत्ति शून्य (सिग्नल की डीसी ऑफसेट) और Nyquist आवृत्ति (नमूना दर आधा) के पास कोई चरण घटक नहीं है, कुछ एफएफटी कार्यान्वयन उन्हें एक ही जटिल बिन में डाल देते हैं (वास्तविक में से एक घटक, काल्पनिक घटक में से एक, आमतौर पर पहले बिन के)। आप कुछ सरल सिग्नल बना सकते हैं (केवल डीसी सिग्नल के लिए सभी 1s, और निक्विस्ट सिग्नल के लिए +1 +1 -1) और देखें कि एफएफटी आउटपुट कैसा दिखता है।

+0

लंबे उत्तर के लिए धन्यवाद। यह काफी है कि मैं कैसे सोच रहा था। लेकिन मैं वास्तव में यह सब एक साथ रखने में सक्षम नहीं हूं। मैंने कुछ कोड जोड़ा ताकि रूबी-ऑडियो (जिसे आपने लिंक किया) और fftw3 मणि का उपयोग करते समय मुझे सबसे दूर दिखाया गया। –

+0

अक्सर जब मुझे चीजों को एक साथ रखने में परेशानी हो रही है, तो मैं बहुत छोटा शुरू करता हूं और एक समय में एक कदम जोड़ता हूं, यह सुनिश्चित करने के लिए कि चीजें काम कर रही हैं, सुनिश्चित करने के लिए बहुत सारे डायग्नोस्टिक कोड (या डीबगर में बारीकी से जांच चर) जोड़ना: क्या मैं खोल सकता हूं फ़ाइल? क्या मैं डेटा पढ़ सकता हूं? डेटा की प्रारूप क्या है जो मैं उम्मीद करता हूं? क्या मैं डेटा बदल सकता हूं? क्या यह अभी भी सही दिखता है? आदि –

+0

हां, लेकिन मैं इसके साथ अटक गया हूं: यह डेटा क्या है जिसे मैं देख रहा हूं और इसे इसे एफएफटी फ़ंक्शन में कैसे खिलाया जाना चाहिए? क्या मुझे इसे बफर की सामग्री देना चाहिए (buf पर to_a पर कॉल करें) या क्या मुझे इसे पहले संसाधित करने की आवश्यकता है? मुझे यकीन नहीं है कि मुझे रूबी-ऑडियो का प्रतिनिधित्व करने वाला डेटा क्या है। –