एमपी 3 फ़ाइल में बीट्स का पता लगाएं


27

इस चुनौती में, आपका कार्य एमपी 3 प्रारूप में एक साधारण रिकॉर्डिंग लेना है और फ़ाइल में बीट्स के समय का पता लगाना है। दो उदाहरण रिकॉर्डिंग यहाँ हैं:

https://dl.dropboxusercontent.com/u/24197429/beats.mp3 https://dl.dropboxusercontent.com/u/24197429/beats2.mp3

यहाँ दो पिछले की तुलना में बहुत अधिक शोर के साथ तीसरी रिकॉर्डिंग है:

https://dl.dropboxusercontent.com/u/24197429/noisy-beats.mp3

उदाहरण के लिए, पहली रिकॉर्डिंग 65 सेकंड लंबी है और इसमें बिल्कुल (जब तक कि मैं गलत नहीं हो जाता!) 76 धड़कता है। आपका काम एक ऐसे प्रोग्राम को तैयार करना है, जो इस तरह की एमपी 3 फाइल को इनपुट के रूप में लेता है और फाइल में बीट्स के मिलीसेकंड में टाइम ऑफसेट के एक क्रम को आउटपुट करता है। निश्चित रूप से एक बीट को परिभाषित किया जाता है, जब गिटार बजाने वाला एक या एक से अधिक तार लगाता है।

आपके समाधान में यह होना चाहिए:

  • इसी तरह की "जटिलता" के किसी भी एमपी 3 फ़ाइल पर काम करें। यह शोर रिकॉर्डिंग पर या जल्दी से खेली गई धुनों पर विफल हो सकता है - मुझे परवाह नहीं है।
  • एकदम सटीक हो। सहिष्णुता +/- 50 एमएस है। इसलिए यदि हरा 1500 एमएस पर होता है और आपका समाधान 1400 रिपोर्ट करता है, तो यह अस्वीकार्य है।
  • केवल मुफ्त सॉफ्टवेयर का उपयोग करें। Ffmpeg को कॉल करने की अनुमति है क्योंकि आपकी पसंद की भाषा के लिए किसी भी स्वतंत्र रूप से उपलब्ध थर्ड पार्टी सॉफ्टवेयर का उपयोग किया जाता है।

विजयी मापदंड आपूर्ति की गई फ़ाइलों में शोर के बावजूद धड़कन का सफलतापूर्वक पता लगाने की क्षमता है। एक टाई के मामले में, सबसे छोटा समाधान जीतता है (3 पार्टी कोड की लंबाई गिनती में नहीं जोड़ी जाती है)।


1
हालांकि यह दिलचस्प लग रहा है, यह एक प्रतियोगिता है, आपको "सही" की तुलना में अधिक सटीक रूप से जीतने के मानदंडों को परिभाषित करना चाहिए।
फाबिनौट


18
एक अच्छी प्रतियोगिता ब्याज के हिस्से को अलग करती है। यहाँ आपको बीट पहचान में दिलचस्पी दिखती है, जो निश्चित रूप से एक दिलचस्प डीएसपी समस्या है। तो क्यों एमपी 3 फ़ाइल स्वरूप की जटिलताओं को प्रोग्राम (या आउटसोर्स) संभालते हैं? प्रश्न को रॉ (नमूना दर, बिट गहराई और एंडियननेस के बारे में अनुमति के साथ) या WAV (इसी तरह) के साथ ले जाकर सुधार किया जाएगा।
पीटर टेलर

3
प्रतियोगिता का उद्देश्य उन सभी टुकड़ों को संभालना है। शायद यह मुश्किल है कि इसे गोल्फस्क्रिप्ट में हल करना मुश्किल है अगर इसमें एमपी 3 के साथ एक कठिन समय है। कभी भी कम नहीं, चुनौती अच्छी तरह से निर्दिष्ट है और (afaict) पूरी तरह से विषय पर इसलिए नकारात्मकता बहुत निराशाजनक है।
ब्योर्न लिंडक्विस्ट

8
@ BjörnLindqvist आपको सुधार के लिए सुझाव नहीं लेना चाहिए। जब तक कुछ पिछली टिप्पणी को हटा नहीं दिया जाता है, मुझे यहां कोई नकारात्मक टिप्पणी नहीं दिखाई देती है, केवल सुधार के लिए सुझाव।
गारेथ

जवाबों:


6

पायथन 2.7 492 बाइट्स (केवल बीट्स। एमपी 3)

इस उत्तर में धड़क रहा है की पहचान कर सकते हैं beats.mp3, लेकिन पर सभी नोटों की पहचान नहीं होगा beats2.mp3या noisy-beats.mp3। अपने कोड के विवरण के बाद, मैं विस्तार से बताऊंगा कि क्यों।

यह MP3 में पढ़ने के लिए PyDub ( https://github.com/jiaaro/pydub ) का उपयोग करता है । अन्य सभी प्रसंस्करण NumPy है।

गोल्फ कोड

फ़ाइल नाम के साथ एक एकल कमांड लाइन तर्क लेता है। यह एमएस में प्रत्येक बीट को एक अलग लाइन पर आउटपुट देगा।

import sys
from math import *
from numpy import *
from pydub import AudioSegment
p=square(AudioSegment.from_mp3(sys.argv[1]).set_channels(1).get_array_of_samples())
n=len(p)
t=arange(n)/44.1
h=array([.54-.46*cos(i/477) for i in range(3001)])
p=convolve(p,h, 'same')
d=[p[i]-p[max(0,i-500)] for i in xrange(n)]
e=sort(d)
e=d>e[int(.94*n)]
i=0
while i<n:
 if e[i]:
  u=o=0
  j=i
  while u<2e3:
   u=0 if e[j] else u+1
   #u=(0,u+1)[e[j]]
   o+=e[j]
   j+=1
  if o>500:
   print "%g"%t[argmax(d[i:j])+i]
  i=j
 i+=1

अघोषित कोड

# Import stuff
import sys
from math import *
from numpy import *
from pydub import AudioSegment

# Read in the audio file, convert from stereo to mono
song = AudioSegment.from_mp3(sys.argv[1]).set_channels(1).get_array_of_samples()

# Convert to power by squaring it
signal = square(song)
numSamples = len(signal)

# Create an array with the times stored in ms, instead of samples
times = arange(numSamples)/44.1

# Create a Hamming Window and filter the data with it. This gets rid of a lot of
# high frequency stuff.
h = array([.54-.46*cos(i/477) for i in range(3001)])
signal = convolve(signal,h, 'same') #The same flag gets rid of the time shift from this

# Differentiate the filtered signal to find where the power jumps up.
# To reduce noise from the operation, instead of using the previous sample,
# use the sample 500 samples ago.
diff = [signal[i] - signal[max(0,i-500)] for i in xrange(numSamples)]

# Identify the top 6% of the derivative values as possible beats
ecdf = sort(diff)
exceedsThresh = diff > ecdf[int(.94*numSamples)]

# Actually identify possible peaks
i = 0
while i < numSamples:
 if exceedsThresh[i]:
  underThresh = overThresh = 0
  j=i
  # Keep saving values until 2000 consecutive ones are under the threshold (~50ms)
  while underThresh < 2000:
   underThresh =0 if exceedsThresh[j] else underThresh+1
   overThresh += exceedsThresh[j]
   j += 1
  # If at least 500 of those samples were over the threshold, take the maximum one
  # to be the beat definition
  if overThresh > 500:
   print "%g"%times[argmax(diff[i:j])+i]
  i=j
 i+=1

मुझे अन्य फ़ाइलों पर नोट्स क्यों याद आते हैं (और वे अविश्वसनीय रूप से चुनौतीपूर्ण क्यों हैं)

मेरा कोड नोटों को खोजने के लिए सिग्नल की शक्ति में परिवर्तन को देखता है। के लिए beats.mp3, यह वास्तव में अच्छी तरह से काम करता है। यह स्पेक्ट्रोग्राम दर्शाता है कि समय (एक्स अक्ष) और आवृत्ति (वाई अक्ष) पर बिजली कैसे वितरित की जाती है। मेरा कोड मूल रूप से y अक्ष को एक पंक्ति में ढहता है। beats.jpeg नेत्रहीन, यह देखना वास्तव में आसान है कि धड़कन कहां हैं। एक पीली लाइन है जो बार-बार बंद हो जाती है। मैं आपको यह सुनने के लिए प्रोत्साहित करता हूं कि beats.mp3जब आप यह देखते हैं कि यह कैसे काम करता है, तो आप स्पेक्ट्रोग्राम पर साथ चलते हैं।

आगे मैं जाऊंगा noisy-beats.mp3(क्योंकि यह वास्तव में आसान है beats2.mp3शोर-beats.pngएक बार फिर, देखें कि क्या आप रिकॉर्डिंग के साथ-साथ अनुसरण कर सकते हैं। अधिकांश लाइनें बेहोश हैं, लेकिन फिर भी वहाँ हैं। हालांकि, कुछ स्थानों में, नीचे की स्ट्रिंग अभी भी बज रही है जब शांत नोट्स शुरू होते हैं। यह उन्हें विशेष रूप से कठिन बनाता है, क्योंकि अब, आपको उन्हें केवल आयाम के बजाय आवृत्ति (y अक्ष) में परिवर्तन द्वारा खोजना होगा।

beats2.mp3अविश्वसनीय रूप से चुनौतीपूर्ण है। यहां का स्पेक्ट्रोग्राम beats2.jpeg पहले बिट में है, कुछ लाइनें हैं, लेकिन कुछ नोट वास्तव में लाइनों पर खून बह रहा है। नोटों की मज़बूती से पहचान करने के लिए, आपको नोटों की पिच (मौलिक और हार्मोनिक्स) को ट्रैक करना शुरू करना होगा और फिर देखना होगा कि वे कहाँ बदलते हैं। एक बार पहला बिट काम कर रहा है, दूसरा बिट टेम्पो दोगुना है!

मूल रूप से, इन सभी की पहचान करने के लिए, मुझे लगता है कि यह कुछ फैंसी नोट डिटेक्शन कोड लेता है। ऐसा लगता है कि डीएसपी वर्ग में किसी के लिए एक अच्छा अंतिम प्रोजेक्ट होगा।


मुझे लगता है कि इसकी अनुमति नहीं है, क्योंकि यह सभी आवश्यकताओं को पूरा नहीं करता है। अच्छा जवाब है, लेकिन इसके लिए कुछ काम चाहिए।
R

हाँ, मैं थोड़ा निराश हूं क्योंकि इस पद्धति ने काम नहीं किया जैसा कि मुझे उम्मीद थी। मुझे लगता है कि यह किसी और की मदद कर सकता है जो इस पर एक छुरा लेना चाहता है। यदि मुझे इस सप्ताह कुछ अतिरिक्त समय मिलता है, तो मुझे नए एफएफटी आधारित दृष्टिकोण की कोशिश करने की उम्मीद है जो बेहतर परिणाम दे।
डोमिनिक ए।

ठीक है। हालांकि अच्छी नौकरी।
R
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.