สารบัญ:

Arduino Music Notes Detector: 3 ขั้นตอน
Arduino Music Notes Detector: 3 ขั้นตอน

วีดีโอ: Arduino Music Notes Detector: 3 ขั้นตอน

วีดีโอ: Arduino Music Notes Detector: 3 ขั้นตอน
วีดีโอ: สอนการใช้ Buzzer กับ Arduino 2024, ธันวาคม
Anonim
Image
Image

การตรวจจับโน้ตเพลงจากสัญญาณเสียงทำได้ยากโดยเฉพาะบน Arduino เนื่องจากหน่วยความจำและกำลังประมวลผลที่จำกัด โดยทั่วไป โน้ตไม่ใช่คลื่นไซน์บริสุทธิ์ที่ทำให้การตรวจจับทำได้ยาก หากเราใช้การแปลงความถี่ของเครื่องดนตรีต่างๆ เครื่องดนตรีนั้นอาจมีฮาร์โมนิกหลายแบบตามโน้ตที่กำลังเล่นอยู่ เครื่องดนตรีทุกชิ้นมีการผสมผสานที่เป็นเอกลักษณ์เฉพาะของฮาร์โมนิกต่างๆ ในโค้ดนี้ ฉันพยายามสร้างโปรแกรมที่สามารถครอบคลุมเครื่องมือต่างๆ ได้มากที่สุด คุณอาจอ้างอิงวิดีโอที่แนบมาซึ่งฉันพยายามทดสอบเครื่องดนตรีประเภทต่างๆ โทนเสียงต่างๆ ที่สร้างโดยแป้นพิมพ์ และแม้แต่เสียงร้องก็ถูกตรวจสอบ ความแม่นยำในการตรวจจับจะแตกต่างกันไปตามเครื่องมือ สำหรับเครื่องดนตรีบางประเภท (เช่น เปียโน) ในช่วงจำกัด (200-500Hz) จะมีความแม่นยำ ในขณะที่เครื่องดนตรีบางชนิดมีความแม่นยำต่ำ (เช่น ฮาร์โมนิกา)

รหัสนี้ใช้รหัส FFT ที่พัฒนาขึ้นก่อนหน้านี้ซึ่งเรียกว่า EasyFFT

การสาธิตโค้ดแสดงในวิดีโอด้านบนพร้อมเสียงเครื่องดนตรีประเภทต่างๆ และเสียงร้อง

เสบียง

- Arduino Nano/Uno หรือสูงกว่า

- โมดูลไมโครโฟนสำหรับ Arduino

ขั้นตอนที่ 1: อัลกอริธึมสำหรับการตรวจจับโน้ต

ดังที่กล่าวไว้ในขั้นตอนก่อนหน้านี้ การตรวจจับทำได้ยากเนื่องจากมีหลายความถี่ในตัวอย่างเสียง

โปรแกรมทำงานในโฟลว์ต่อไปนี้:

1. การได้มาซึ่งข้อมูล:

- ส่วนนี้ใช้ 128 ตัวอย่างจากข้อมูลเสียง การแยกระหว่างสองตัวอย่าง (ความถี่สุ่มตัวอย่าง) ขึ้นอยู่กับความถี่ของความสนใจ ในกรณีนี้ เราใช้ระยะห่างระหว่างสองตัวอย่างเพื่อใช้ฟังก์ชันหน้าต่าง Hann เช่นเดียวกับการคำนวณแอมพลิจูด/RMS รหัสนี้ยังทำให้เป็นศูนย์อย่างคร่าวๆ โดยการลบ 500 จากค่าแอนะล็อก ค่านี้สามารถเปลี่ยนแปลงได้หากต้องการ สำหรับกรณีทั่วไป ค่านี้ใช้ได้ดี นอกจากนี้ ต้องเพิ่มการหน่วงเวลาเพื่อให้มีความถี่สุ่มตัวอย่างประมาณ 1200Hz ในกรณีของความถี่สุ่มตัวอย่าง 1200Hz สูงสุดที่ความถี่ 600 HZ สามารถตรวจจับได้

สำหรับ (int i=0;i<128;i++) {a=analogRead(Mic_pin)-500; // กะศูนย์อย่างคร่าวๆ sum1=sum1+a; //ไปยังค่าเฉลี่ย sum2=sum2+a*a; // เป็นค่า RMS a=a*(sin(i*3.14/128)*sin(i*3.14/128)); // หน้าต่าง Hann ใน=4*a; // ปรับขนาดสำหรับการแปลง float เป็น int ล่าช้าไมโครวินาที (195); // ขึ้นอยู่กับช่วงความถี่การทำงาน }

2. เอฟเอฟที:

เมื่อข้อมูลพร้อมแล้ว FFT จะดำเนินการโดยใช้ EasyFFT ฟังก์ชัน EasyFFT นี้ได้รับการแก้ไขเพื่อแก้ไข FFT สำหรับตัวอย่าง 128 ตัวอย่าง รหัสยังถูกแก้ไขเพื่อลดการใช้หน่วยความจำ ฟังก์ชัน EasyFFT ดั้งเดิมได้รับการออกแบบให้มีตัวอย่างสูงสุด 1,028 ตัวอย่าง (ด้วยบอร์ดที่เข้ากันได้) ในขณะที่เราต้องการเพียง 128 ตัวอย่างเท่านั้น รหัสนี้ช่วยลดการใช้หน่วยความจำได้ประมาณ 20% เมื่อเทียบกับฟังก์ชัน EasyFFT ดั้งเดิม

เมื่อทำ FFT เสร็จแล้ว โค้ดจะส่งคืนความถี่สูงสุด 5 อันดับแรกที่เด่นที่สุดสำหรับการวิเคราะห์เพิ่มเติม ความถี่นี้ถูกจัดเรียงตามลำดับแอมพลิจูดจากมากไปน้อย

3. สำหรับทุกจุดพีค รหัสจะตรวจจับบันทึกที่อาจเชื่อมโยงกับมัน รหัสนี้สแกนได้สูงถึง 1200 Hz เท่านั้น ไม่จำเป็นต้องจดบันทึกเหมือนกับความถี่ที่มีแอมพลิจูดสูงสุด

ความถี่ทั้งหมดถูกแมประหว่าง 0 ถึง 255

ที่นี่ตรวจพบอ็อกเทฟแรก เช่น 65.4 Hz ถึง 130.8 แทนหนึ่งอ็อกเทฟ 130.8 Hz ถึง 261.6 Hz แทนอ็อกเทฟอื่น สำหรับทุกอ็อกเทฟ ความถี่จะถูกจับคู่จาก 0 ถึง 255 ที่นี่การแมปเริ่มต้นจาก C ถึง C'

if(f_peaks>1040){f_peaks=0;} if(f_peaks>=65.4 && f_peaks=130.8 && f_peaks=261.6 && f_peaks=523.25 && f_peaks =1046 && f_peaks<=2093) {f_peaks=255*((f_peaks/1046)-1);}

ค่าอาร์เรย์ NoteV ใช้เพื่อกำหนดโน้ตให้กับความถี่ที่ตรวจพบ

ไบต์ NoteV[13]={8, 23, 40, 57, 76, 96, 116, 138, 162, 187, 213, 241, 255};

4. หลังจากคำนวณโน้ตสำหรับทุกความถี่แล้ว อาจเป็นกรณีที่มีหลายความถี่ที่มีอยู่ซึ่งแนะนำโน้ตตัวเดียวกัน เพื่อให้ได้รหัสเอาต์พุตที่ถูกต้อง ให้พิจารณาการทำซ้ำด้วย รหัสจะเพิ่มค่าความถี่ทั้งหมดตามลำดับแอมพลิจูดและการซ้ำซ้อน และเพิ่มค่าสูงสุดของโน้ตด้วยแอมพลิจูดสูงสุด

ขั้นตอนที่ 2: การสมัคร

การใช้โค้ดนั้นตรงไปตรงมา แต่ก็มีข้อจำกัดหลายประการที่ต้องคำนึงถึงในขณะใช้งาน สามารถคัดลอกรหัสได้เนื่องจากใช้สำหรับการตรวจจับบันทึกย่อ จุดด้านล่างจะต้องได้รับการพิจารณาในขณะที่ใช้งาน

1. การกำหนดพิน:

จำเป็นต้องแก้ไขการมอบหมายพินที่แนบมาด้วย สำหรับการทดลองของฉัน ฉันเก็บไว้ที่ขาอะนาล็อก 7

การตั้งค่าเป็นโมฆะ () {Serial.begin(250000); Mic_pin = A7; }

2. ความไวของไมโครโฟน:

ความไวของไมโครโฟนจำเป็นต้องแก้ไขรูปคลื่นดังกล่าวสามารถสร้างได้ด้วยแอมพลิจูดที่ดี ส่วนใหญ่ โมดูลไมโครโฟนมาพร้อมกับการตั้งค่าความไว ความไวที่เหมาะสมที่จะเลือกเพื่อให้สัญญาณไม่เล็กเกินไปและไม่ถูกตัดออกเนื่องจากแอมพลิจูดที่สูงขึ้น

3. เกณฑ์แอมพลิจูด:

รหัสนี้จะเปิดใช้งานก็ต่อเมื่อแอมพลิจูดของสัญญาณสูงพอ ผู้ใช้ต้องตั้งค่าการตั้งค่านี้ด้วยตนเอง ค่านี้ขึ้นอยู่กับความไวของไมโครโฟนและการใช้งาน

ถ้า(sum2-sum1>5){

..

ในโค้ดด้านบน sum2 ให้ค่า RMS ในขณะที่ sum 1 ให้ค่าเฉลี่ย ดังนั้นความแตกต่างระหว่างสองค่านี้จึงให้แอมพลิจูดของสัญญาณเสียง ในกรณีของฉัน มันทำงานอย่างถูกต้องโดยมีค่าแอมพลิจูดประมาณ 5

4. โดยค่าเริ่มต้น รหัสนี้จะพิมพ์บันทึกที่ตรวจพบ อย่างไรก็ตาม หากคุณวางแผนที่จะใช้บันทึกเพื่อวัตถุประสงค์อื่น ควรใช้หมายเลขที่กำหนดโดยตรง ตัวอย่างเช่น C=0;C#=1, D=2, D#=3 เป็นต้นไป

5. หากอุปกรณ์มีความถี่สูง รหัสอาจให้ผลลัพธ์ที่ผิดพลาด ความถี่สูงสุดถูกจำกัดโดยความถี่สุ่มตัวอย่าง ดังนั้นคุณอาจเล่นค่าหน่วงเวลาด้านล่างเพื่อให้ได้ผลลัพธ์ที่ดีที่สุด ในโค้ดล่าช้าด้านล่าง 195 ไมโครวินาที ซึ่งอาจปรับแต่งเพื่อให้ได้ผลลัพธ์ที่ดีที่สุด ซึ่งจะส่งผลต่อเวลาดำเนินการโดยรวม

{ a=analogRead(Mic_pin)-500; // กะศูนย์กะคร่าวๆ

sum1=sum1+a; //ไปยังค่าเฉลี่ย sum2=sum2+a*a; // เป็นค่า RMS a=a*(sin(i*3.14/128)*sin(i*3.14/128)); // หน้าต่าง Hann ใน=4*a; // ปรับขนาดสำหรับการแปลง float เป็น int ล่าช้าไมโครวินาที (195); // ขึ้นอยู่กับช่วงความถี่การทำงาน }

6. รหัสนี้จะใช้ได้จนถึงความถี่ 2000Hz เท่านั้น โดยขจัดความล่าช้าระหว่างการสุ่มตัวอย่างประมาณ 3-4 kHz ของความถี่สุ่มตัวอย่างสามารถรับได้

ข้อควรระวัง:

  • ดังที่กล่าวไว้ในบทช่วยสอน EasyFFT FFT กินหน่วยความจำ Arduino จำนวนมาก ดังนั้นหากคุณมีโปรแกรมที่ต้องการเก็บค่าบางค่า ขอแนะนำให้ใช้บอร์ดที่มีหน่วยความจำสูงกว่า
  • รหัสนี้อาจใช้ได้ดีกับเครื่องดนตรี/นักร้องคนหนึ่งและไม่ดีสำหรับอีกคนหนึ่ง การตรวจจับที่แม่นยำแบบเรียลไทม์ไม่สามารถทำได้เนื่องจากข้อจำกัดในการคำนวณ

ขั้นตอนที่ 3: Summery

การตรวจจับโน้ตเป็นงานที่ต้องใช้คอมพิวเตอร์มาก การรับเอาต์พุตแบบเรียลไทม์นั้นยากมาก โดยเฉพาะใน Arduino รหัสนี้สามารถให้ตัวอย่างได้ประมาณ 6.6 ตัวอย่าง/วินาที (สำหรับการเพิ่มการหน่วงเวลา 195 ไมโครวินาที) รหัสนี้ใช้งานได้ดีกับเปียโนและเครื่องดนตรีอื่นๆ

ฉันหวังว่าโค้ดและบทช่วยสอนนี้จะเป็นประโยชน์ในโครงการที่เกี่ยวข้องกับดนตรีของคุณ ในกรณีที่มีข้อสงสัยหรือข้อเสนอแนะโปรดแสดงความคิดเห็นหรือข้อความ

ในบทช่วยสอนที่กำลังจะถึงนี้ ฉันจะแก้ไขโค้ดนี้สำหรับการตรวจจับคอร์ดเพลง ดังนั้นคอยติดตาม

แนะนำ: