پیدا کردن یک قطعه آهنگ با شنیدن بخشی از آن، نیاز به نمایه‌سازی مجموعه آهنگ‌ها دارد، درست مثل جستجوی واژه‌ها.

۱. مقدمه:

گاهی در بین راه یا در رستوران , در تاکسی آهنگی را می شنویم که جذبمان می کند . اما نه می توانیم خواننده ی آن و نه متن آن را تشخیص بدهیم.
برای رفع این مشکل application هایی مانند shazam , google sound search وجود دارد که با پخش موزیک برای آن , مشخصات موزیک مربوطه را پیدا
می کند.

Shazam Entertainment Ltd:
یک شرکت توسعه نرم افزار بریتانیا است که
برنامه ای را ایجاد می کند که می تواند موسیقی، فیلم، تبلیغات و برنامه های
تلویزیونی را براساس نمونه ای کوتاه و با استفاده از میکروفون در دستگاه شناسایی
کند. این نرم افزار برای ویندوز، macOS و گوشی های هوشمند در دسترس است

Google sound search :
برنامه ای برای دستگاهای اندرویدی است که به صورت widget قابل استفاده است که پخش موزیک
برای آن , نام و خواننده ی موزیک مربوطه
را به کاربر اعلام می کند.

این application ها علاوه بر تطبیق دادن صدا با آهنگ مربوطه , می بایست noise را از صدای پخش شده نیز بگیرد .
در این نوع application ها کار اصلی تبدیل سیگنال پیوسته به گسسته است که امروزه کارت صدای کامپیوتر ها این کار را انجام می دهند.

۲. کارهای مرتبط:

در این برنامه ها کار اصلی تبدیل سیگنال دیجیتال به آنالوگ است.
فررض کنید سیگنال زیر به عنوان ورودی به برنامه داده می شود.


کامپیوتر سیگنال ورودی را در هر مدت زمان مشخص 1 بار که به آن sample rate گفته می شود از ورودی می خواند و ذخیره می کند.که به آن sample ' گفته می شود.
ب طور مثال اگر sample rate 1 باشد , شکل سیگنال به صورت زیر خواهد شد.
توضیح تصویر

اصولا sample rate می بایست 2 برابر بیشترین فرکانس صورت باشد (44,100khz)

2.1. Time-Domain and Frequency-Domain:

دامنه ی ما می تواند زمان یا فرکانس باشد. الگوریتم اجرای این برنامه نیاز به دامنه ی فرکانسی دارد. از این رو باید دامنه را فرکانسی کنیم

توضیح تصویر

برای این کار از تبدیل فوریه گسسته استفاده می کنیم .
توضیح تصویر

حال هر کدام از sample هارا دسته بندی می کنیم. هر چند sample یک data chunck است .
برنامه با استفاده از این data chunck ها موزیک را سرچ می کند.

۳. آزمایش‌ها:

اجرای کد تست:
الگوریتم fingerprinting را با استفاده از پایتون و دیتابیس mysql پیاده یازی کرده ایم.

در این برنامه تعدادی آهنگ به عنوان دیتا ست در فولدر mp3 دارد و با پخش موزیک برای برنامه از طریق میکروفون لپتاپ درصورت تطبیق اهنگ با هر یک از آهنگ های دیتاست برنامه نام آهنگ را به عنوان خروجی چاپ می کند.
From mic with 2 seconds we recognized: {'song_id': 1, 'song_name': 'Brad-Sucks--Total-Breakdown', 'file_sha1': '02A83F248EFDA76A46C8B2AC97798D2CE9BC1FBE', 'confidence': 1, 'offset_seconds': 92.69406, 'offset': 1996}
درصورت پخش نشدن موزیک خروجی زیر را خواهد داد:
Nothing recognized -- did you play the song out loud so your mic could hear it? :)
این برنامه را با ران کردن فایل example.py اجرا می کنیم.
در این فایل ۲ تابع اصلی برای هر بار تشخیص آهنگ فراخوانی می شود:

djv.fingerprint_directory("mp3", [".mp3",".wma"])
که دایرکتوری قرار گرفتن موزیک هارا به آن معرفی می کنیم. همچنین فرمت هایی که در این دایرکتوری به عنوان موزیک شناخته می شوند را نیز وارد می کنیم. دیتابیس ما fingerprint های هر یک از این موزیک هارا ذخیره می کند و درصورت وجود fingerprint هر موزیک دوباره آنرا fingerprint نخواهد کرد.
if decoder.unique_hash(filename) in self.songhashes_set:    print "%s already fingerprinted, continuing..." % filename    continue
secs = 2
song = djv.recognize(MicrophoneRecognizer, seconds=secs)
این تابع موزیک را از روی میکروفون می به عنوان ورودی دریافت می کند و اهنگ را تشخیص می دهد و مشخصات آنرا به عنوان خروجی می دهد.
def recognize(self, recognizer, *options, **kwoptions):   
     r = recognizer(self)  
       return r.recognize(*options, **kwoptions)
ورودی این تابع را MicrophoneRecognizer است به این معنی که از میکروفون ورودی را دریافت میکند نه از دیسک.
def recognize(self, seconds=10):  
  self.start_recording()  
    for i in range(0, int(self.samplerate / self.chunksize    * seconds)):     
       self.process_recording()     
         self.stop_recording()    
     return self.recognize_recording()

در این تابع به اندازه یself.samplerate / self.chunksize * seconds صدا را از ورودی می خواند.
در تابع recognize_recording تابع find_matches فراخوانی شده است که عمل fingerprint را روی موزیک ها انجام می دهد.و تابع align matches بررسی میکند که fingerprint با موزیک داده شده برابر است یا ن.
در تابع fingerprint از توابع ماژول numpy برای تبدیل فوریه سریع(FFT) استفاده شده است .
پس از تبدیل فوریه الگوریتم باید local maximum هارا بیابد و انهارا ذخیره کند و با استفاده از تابع زیر این کارا می کند.

local_max = maximum_filter(arr2D, footprint=neighborhood)

سپس hash می کند و در دیتابیس ذخیره می کند.
+---------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-----------------------+------+-----+---------+-------+
| hash | binary(10) | NO | PRI | NULL | |
| song_id | mediumint(8) unsigned | NO | PRI | NULL | |
| offset | int(10) unsigned | NO | PRI | NULL | |
+---------+-----------------------+------+-----+---------+-------+
تست برنامه:
برای تست این برنامه معیار های تغییر ما ثانیه ی پخش شدن آهنگ و افزایش نویز و تغییر تعداد دیتا ست هاست.
برای این کار ابتدا ۵ موزیک را در فولدر دیتاست اضافه کردیم و به مرور موزیک های بیشتری اضافه کردیم و تست را شروع کردیم.
تغییر ثانیه ی پخش:

Number Correct Number of Seconds
1 15 / 20
2 17 / 20
3 17 / 20
4 17 / 20
5 19 / 20
6 20 / 20

تغییر نویز:

Number Correct noise
1 20 / 20
2 17 / 20
3 16 / 20

تغییر تعداد اهنگ های دیتا ست با ۵ ثانیه :

Number Correct Number of Songs
5 5 / 5
7 7 / 7
10 10 / 10
15 15 / 15
20 19 / 20

پیوست کد:
https://github.com/mehraveh/audio-finger-printing

۴. کارهای آینده:

در این برنامه موزیک هایی که در دیتابیس نیستند را به احبار به یمی از موزیک های دیتابیس مپ می کند که درآینده این مشکل حل خواهد شد.
پیوست کد:

۵. مراجع

http://www.ee.columbia.edu/%7Edpwe/papers/Wang03-shazam.pdf
http://www.cs.cmu.edu/%7Eyke/musicretrieval/
??? ????? ???????? ?????? ??? ???????? ???????

۶. پیوندهای مفید:

https://www.bbc.co.uk/education/guides/zpfdwmn/revision/3
https://www.toptal.com/algorithms/shazam-it-music-processing-fingerprinting-and-recognition
https://en.wikipedia.org/wiki/Time_domain
https://en.wikipedia.org/wiki/Sampling_%28signal_processing%29

توضیح تصویر

  1. مفهوم نمایه سازی

  2. Audio Fingerprinting with Python and Numpy

  3. Echoprint

  4. Pydub(python library)

  5. MySQL on Ubuntu

  6. Duplicate songs detector via audio fingerprinting

تایید شده

با سلام و عرض خسته نباشید بابت تلاش های انجام گرفته
مرحله پیاده سازی کامل بود و کد اجرا میشد.
اما درمورد نحوه اجرای الگوریتم توضیح کافی داده نشد و پس از اینکه گفته بودید یکی از کار های اولیه تبدیل سیگنال پیوسته به گسسته می باشد، مراحل بعدی انجام این کار را توضیح نداده بودید که چگونه سیستم متوجه یک شباهت در صدا ها میشود.
و یا درمورد پیاده سازی گفته شد از الگوریتم fingerprint استفاده میشود که توضیح کاملی داده نشده بود، اما درمورد پیاده سازی کامل و بدون مشکل بود

محمد حسن سوهان آجینی

سلام
بزرگترین ایراد موجود در این کار، ارایه ندادن جزییات روش مورد استفاده است. خواننده‌ای که با روش fingerprint آشنا نیست، پس از مطاله‌ی این گزارش، هیچ دانشی از الگوریتم را درک نخواهد کرد و چیزی به دانش او اضافه نخواهد شد! با توجه به اینکه در نقد قبلی عرض شد که بخش «کارهای مرتبط» شامل روش پیش پردازش است و توضیحات ناقص هستند، انتظار می‌رفت در این مرحله توضیحات بهتری/بیشتری در مورد الگوریتم fingerprint ارایه می‌دادید.

ضمن اینکه ایرادات نگارشی موجود را برطرف خواهید کرد، ذکر موراد زیر در گزارش نهایی شما لازم هستند:
۱- برای نویزی کردن داده‌ها، از چه نوع نویز و با چه شدتی استفاده کردید؟
۲- تعداد موزیک‌های مورد آزمایش را با یک مرجع مقایسه کنید. این تعداد از موزیک‌ها، بسیار محدود هستند و جواب گرفتن روی آن دشواری خاصی ندارد.
۳- در مورد زمان اجرای کد توضیحاتی بدهید. یکی از چالش‌های این زمینه، اجرای کد در کمترین زمان ممکن است. اگر این مورد جزو چالش‌های مورد نظر شما نیست، این نکته رادر گزارش خود ذکر کنید.