Mục lục:
- Quân nhu
- Bước 1: Xây dựng phần cứng cho máy dò nốt nhạc
- Bước 2: Lập trình máy dò nốt nhạc
- Bước 3: Thiết lập Trình dò nốt nhạc
Video: Máy dò nốt nhạc: 3 bước
2024 Tác giả: John Day | [email protected]. Sửa đổi lần cuối: 2024-01-30 13:30
Làm kinh ngạc bạn bè và gia đình của bạn với dự án phát hiện nốt nhạc được chơi bởi một nhạc cụ. Dự án này sẽ hiển thị tần số gần đúng cũng như nốt nhạc được chơi trên bàn phím điện tử, ứng dụng piano hoặc bất kỳ nhạc cụ nào khác.
Thông tin chi tiết
Đối với dự án này, đầu ra tương tự từ bộ dò mô-đun âm thanh được gửi đến đầu vào tương tự A0 của Arduino Uno. Tín hiệu tương tự được lấy mẫu và lượng tử hóa (số hóa). Mã tự tương quan, trọng số và điều chỉnh được sử dụng để tìm tần số cơ bản bằng cách sử dụng 3 giai đoạn đầu tiên. Sau đó, tần số cơ bản gần đúng được so sánh với các tần số trong phạm vi quãng tám 3, 4 và 5 để xác định tần số nốt nhạc gần nhất. Cuối cùng, ghi chú được đoán cho tần số gần nhất được in ra màn hình.
Lưu ý: Tài liệu hướng dẫn này chỉ tập trung vào cách xây dựng dự án. Để biết thêm thông tin về các chi tiết và lý do thiết kế, vui lòng truy cập liên kết này:
Quân nhu
- (1) Arduino Uno (hoặc Genuino Uno)
- (1) Tương thích với cảm biến micrô DEVMO Mô-đun phát hiện âm thanh có độ nhạy cao
- (1) Bảng mạch không hàn
- (1) Cáp USB-A đến B
- Dây nhảy
- Nguồn âm nhạc (piano, bàn phím hoặc ứng dụng paino với loa)
- (1) Máy tính hoặc máy tính xách tay
Bước 1: Xây dựng phần cứng cho máy dò nốt nhạc
Sử dụng Arduino Uno, dây kết nối, bảng mạch không hàn và Mô-đun phát hiện âm thanh có độ nhạy cao của cảm biến micrô DEVMO (hoặc tương tự) xây dựng mạch được hiển thị trong hình ảnh này
Bước 2: Lập trình máy dò nốt nhạc
Trong IDE Arduino, hãy thêm mã sau.
gistfile1.txt
/* |
Tên tệp / phác thảo: MusicalNoteDetector |
Phiên bản số: v1.0 Được tạo ngày 7 tháng 6 năm 2020 |
Tác giả gốc: Clyde A. Lettsome, PhD, PE, MEM |
Mô tả: Mã / bản phác thảo này hiển thị tần số gần đúng cũng như nốt nhạc được chơi trên bàn phím điện tử hoặc ứng dụng piano. Đối với dự án này, đầu ra tương tự từ |
bộ dò mô-đun âm thanh được gửi đến đầu vào tương tự A0 của Arduino Uno. Tín hiệu tương tự được lấy mẫu và lượng tử hóa (số hóa). Mã tự tương quan, trọng số và điều chỉnh được sử dụng để |
tìm tần số cơ bản bằng cách sử dụng 3 giai đoạn đầu tiên. Sau đó, tần số cơ bản gần đúng được so sánh với các tần số trong phạm vi quãng tám 3, 4 và 5 để xác định âm nhạc gần nhất |
tần số ghi chú. Cuối cùng, ghi chú được đoán cho tần số gần nhất được in ra màn hình. |
Giấy phép: Chương trình này là phần mềm miễn phí; bạn có thể phân phối lại và / hoặc sửa đổi nó theo các điều khoản của Giấy phép Công cộng GNU (GPL) phiên bản 3 hoặc bất kỳ sau này |
phiên bản bạn chọn, như được xuất bản bởi Tổ chức Phần mềm Tự do. |
Ghi chú: Bản quyền (c) 2020 của C. A. Lettsome Services, LLC |
Để biết thêm thông tin, hãy truy cập |
*/ |
#define MẪU 128 // Tối đa 128 cho Arduino Uno. |
#define SAMPLING_FREQUENCY 2048 // Fs = Dựa trên Nyquist, phải gấp 2 lần tần suất dự kiến cao nhất. |
#define OFFSETSAMPLES 40 // được sử dụng cho mục đích tính toán |
#define TUNER -3 // Điều chỉnh cho đến khi C3 là 130,50 |
float samplingPeriod; |
không dấu dài microSeconds; |
int X [MẪU]; // tạo vector có kích thước SAMPLES để chứa các giá trị thực |
float autoCorr [SAMPLES]; // tạo vector có kích thước SAMPLES để chứa các giá trị tưởng tượng |
float StorageNoteFreq [12] = {130,81, 138,59, 146,83, 155,56, 164,81, 174,61, 185, 196, 207,65, 220, 233,08, 246,94}; |
int sumOffSet = 0; |
int offSet [OFFSETSAMPLES]; // tạo vectơ bù đắp |
int avgOffSet; // tạo vectơ bù đắp |
int i, k, periodEnd, periodBegin, period, Adjuster, noteLocation, octaveRange; |
float maxValue, minValue; |
tổng dài; |
int thresh = 0; |
int numOfCycles = 0; |
float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, total; |
byte bang_machine = 0; |
int mẫuPerPeriod = 0; |
void setup () |
{ |
Serial.begin (115200); // Tốc độ truyền 115200 cho Màn hình nối tiếp |
} |
void loop () |
{ |
//***************************************************************** |
// Phần tính toán |
//***************************************************************** |
Serial.println ("Calabrating. Vui lòng không phát bất kỳ nốt nào trong quá trình calabration."); |
for (i = 0; i <OFFSETSAMPLES; i ++) |
{ |
offSet = analogRead (0); // Đọc giá trị từ chân tương tự 0 (A0), lượng tử hóa nó và lưu nó dưới dạng một số hạng thực. |
//Serial.println(offSet); // sử dụng điều này để điều chỉnh mô-đun phát hiện âm thanh thành khoảng một nửa hoặc 512 khi không có âm thanh nào được phát. |
sumOffSet = sumOffSet + offSet ; |
} |
mẫuPerPeriod = 0; |
maxValue = 0; |
//***************************************************************** |
// Chuẩn bị chấp nhận đầu vào từ A0 |
//***************************************************************** |
avgOffSet = round (sumOffSet / OFFSETSAMPLES); |
Serial.println ("Đang đếm ngược."); |
chậm trễ (1000); // tạm dừng trong 1 giây |
Serial.println ("3"); |
chậm trễ (1000); // tạm dừng trong 1 giây |
Serial.println ("2"); |
chậm trễ (1000); // tạm dừng trong 1 |
Serial.println ("1"); |
chậm trễ (1000); // tạm dừng trong 1 giây |
Serial.println ("Chơi ghi chú của bạn!"); |
chậm trễ (250); // tạm dừng trong 1/4 giây cho thời gian phản ứng |
//***************************************************************** |
// Thu thập SAMPLES mẫu từ A0 với khoảng thời gian lấy mẫu của samplingPeriod |
//***************************************************************** |
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // Khoảng thời gian tính bằng micro giây |
for (i = 0; i <SAMPLES; i ++) |
{ |
microSeconds = micros (); // Trả về số micro giây kể từ khi bảng Arduino bắt đầu chạy tập lệnh hiện tại. |
X = analogRead (0); // Đọc giá trị từ chân tương tự 0 (A0), lượng tử hóa nó và lưu nó dưới dạng một số hạng thực. |
/ * thời gian chờ còn lại giữa các mẫu nếu cần tính bằng giây * / |
while (micros () <(microSeconds + (samplingPeriod * 1000000))) |
{ |
// không làm gì cả chỉ đợi |
} |
} |
//***************************************************************** |
// Hàm tự tương quan |
//***************************************************************** |
for (i = 0; i <SAMPLES; i ++) // i = delay |
{ |
tổng = 0; |
for (k = 0; k <SAMPLES - i; k ++) // Kết hợp tín hiệu với tín hiệu trễ |
{ |
sum = sum + (((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] là tín hiệu và X [k + i] là phiên bản trễ |
} |
autoCorr = sum / SAMPLES; |
// Máy trạng thái phát hiện đỉnh đầu tiên |
if (state_machine == 0 && i == 0) |
{ |
thresh = autoCorr * 0,5; |
bang_machine = 1; |
} |
else if (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, tìm 1 khoảng thời gian để sử dụng chu kỳ đầu tiên |
{ |
maxValue = autoCorr ; |
} |
else if (state_machine == 1 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodBegin = i-1; |
bang_machine = 2; |
numOfCycles = 1; |
samplePerPeriod = (periodBegin - 0); |
kỳ = mẫuPerPeriod; |
bộ điều chỉnh = TUNER + (50,04 * exp (-0,102 * mẫuPerPeriod)); |
signalFrequency = ((SAMPLING_FREQUENCY) / (samplePerPeriod)) - bộ điều chỉnh; // f = fs / N |
} |
else if (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, tìm 2 kỳ cho chu kỳ 1 và 2 |
{ |
maxValue = autoCorr ; |
} |
else if (state_machine == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodEnd = i-1; |
bang_machine = 3; |
numOfCycles = 2; |
samplePerPeriod = (periodEnd - 0); |
signalFrequency2 = ((numOfCycles * SAMPLING_FREQUENCY) / (samplesPerPeriod)) - bộ điều chỉnh; // f = (2 * fs) / (2 * N) |
maxValue = 0; |
} |
else if (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3, tìm 3 kỳ cho chu kỳ 1, 2 và 3 |
{ |
maxValue = autoCorr ; |
} |
else if (state_machine == 3 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodEnd = i-1; |
bang_machine = 4; |
numOfCycles = 3; |
samplePerPeriod = (periodEnd - 0); |
signalFrequency3 = ((numOfCycles * SAMPLING_FREQUENCY) / (samplePerPeriod)) - bộ điều chỉnh; // f = (3 * fs) / (3 * N) |
} |
} |
//***************************************************************** |
// Phân tích kết quả |
//***************************************************************** |
nếu (mẫuPerPeriod == 0) |
{ |
Serial.println ("Hmm….. Tôi không chắc. Bạn đang cố lừa tôi?"); |
} |
khác |
{ |
// chuẩn bị hàm trọng số |
tổng = 0; |
if (signalFrequency! = 0) |
{ |
tổng = 1; |
} |
if (signalFrequency2! = 0) |
{ |
tổng = tổng + 2; |
} |
if (signalFrequency3! = 0) |
{ |
tổng = tổng + 3; |
} |
// tính tần suất bằng hàm trọng số |
signalFrequencyGuess = ((1 / tổng) * signalFrequency) + ((2 / tổng) * signalFrequency2) + ((3 / tổng) * signalFrequency3); // tìm tần suất có trọng số |
Serial.print ("Ghi chú bạn đã chơi gần đúng"); |
Serial.print (signalFrequencyGuess); // In đoán tần số. |
Serial.println ("Hz."); |
// tìm phạm vi quãng tám dựa trên phỏng đoán |
octaveRange = 3; |
while (! (signalFrequencyGuess> = storageNoteFreq [0] -7 && signalFrequencyGuess <= storageNoteFreq [11] +7)) |
{ |
cho (i = 0; i <12; i ++) |
{ |
storageNoteFreq = 2 * storageNoteFreq ; |
} |
octaveRange ++; |
} |
// Tìm ghi chú gần nhất |
minValue = 10000000; |
noteLocation = 0; |
cho (i = 0; i <12; i ++) |
{ |
if (minValue> abs (signalFrequencyGuess-storageNoteFreq )) |
{ |
minValue = abs (signalFrequencyGuess-ManagedNoteFreq ); |
noteLocation = i; |
} |
} |
// In ghi chú |
Serial.print ("Tôi nghĩ bạn đã chơi"); |
if (noteLocation == 0) |
{ |
Serial.print ("C"); |
} |
else if (noteLocation == 1) |
{ |
Serial.print ("C #"); |
} |
khác nếu (noteLocation == 2) |
{ |
Serial.print ("D"); |
} |
else if (noteLocation == 3) |
{ |
Serial.print ("D #"); |
} |
khác nếu (noteLocation == 4) |
{ |
Serial.print ("E"); |
} |
khác nếu (noteLocation == 5) |
{ |
Serial.print ("F"); |
} |
khác nếu (noteLocation == 6) |
{ |
Serial.print ("F #"); |
} |
else if (noteLocation == 7) |
{ |
Serial.print ("G"); |
} |
else if (noteLocation == 8) |
{ |
Serial.print ("G #"); |
} |
khác nếu (noteLocation == 9) |
{ |
Serial.print ("A"); |
} |
khác nếu (noteLocation == 10) |
{ |
Serial.print ("A #"); |
} |
khác nếu (noteLocation == 11) |
{ |
Serial.print ("B"); |
} |
Serial.println (octaveRange); |
} |
//***************************************************************** |
//Dừng ở đây. Nhấn nút đặt lại trên Arduino để khởi động lại |
//***************************************************************** |
trong khi (1); |
} |
xem rawgistfile1.txt được lưu trữ bằng ❤ bởi GitHub
Bước 3: Thiết lập Trình dò nốt nhạc
Kết nối Arduino Uno với PC bằng mã được viết hoặc tải trong Arduino IDE. Biên dịch và tải mã lên Arduino. Đặt mạch gần nguồn nhạc. Lưu ý: Trong video giới thiệu, tôi sử dụng một ứng dụng được cài đặt trên máy tính bảng kết hợp với loa PC làm nguồn nhạc của mình. Nhấn nút đặt lại trên Bảng Arduino và sau đó phát một nốt trên nguồn nhạc. Sau một vài giây, Bộ dò nốt nhạc sẽ hiển thị nốt nhạc đã phát và tần số của nó.
Đề xuất:
Cách tạo máy nghe nhạc MP3 với màn hình LCD bằng Arduino và DFPlayer Mô-đun máy nghe nhạc MP3 mini: 6 bước
Cách tạo máy nghe nhạc MP3 với màn hình LCD bằng mô-đun máy nghe nhạc MP3 mini Arduino và DFPlayer: Hôm nay chúng ta sẽ tạo máy nghe nhạc MP3 với màn hình LCD bằng mô-đun máy nghe nhạc MP3 mini DFPlayer và Arduino. Dự án có thể đọc các tệp MP3 trong thẻ SD và có thể tạm dừng và chơi giống như thiết bị 10 năm trước. Và nó cũng có bài hát trước và bài hát tiếp theo vui nhộn
Bộ dò nốt nhạc Arduino: 3 bước
Arduino Music Notes Detector: Việc phát hiện các nốt nhạc từ tín hiệu âm thanh rất khó thực hiện, đặc biệt là trên Arduino do bộ nhớ và sức mạnh xử lý có hạn. Nói chung, nốt nhạc không phải là một sóng hình sin thuần túy khiến việc phát hiện khó khăn. Nếu chúng ta lấy biến đổi tần số của va
Nốt nhạc nhấp nháy: 5 bước
Nhạc nhấp nháy Ghi chú: Vật liệu: 4 đèn LED (xanh ngọc, xanh lam) Máy CNC Dây máy in 3D SolidWorks Hàn sắt và hàn 2 điện trở 200 Ohm Keo nóng Pin 9 Volt và đầu nối snap Máy khoan Dự án này rất đơn giản và không mất nhiều thời gian
Hộp nhạc / nhạc cụ 6 nốt cầm tay (Dễ chế tạo và cải tiến!): 5 bước (có hình ảnh)
Hộp / Nhạc cụ 6 nốt cầm tay (Dễ chế tạo & Cải tiến!): Xin chào! Lấy cảm hứng từ Martin Molin, thành viên của ban nhạc Thụy Điển tên là Wintergatan, gần đây tôi đã yêu thích những chiếc hộp âm nhạc và mọi thứ về chúng. Những người tạo bài hát cho hộp âm nhạc vẫn đang sử dụng cách truyền thống cũ là nhấn vào bài hát không
Cách đưa nhạc vào máy nghe nhạc MP3 loại thanh: 12 bước
Cách đưa nhạc vào máy nghe nhạc MP3 dạng thanh: Xin chào, đây là hướng dẫn ĐẦU TIÊN của tôi! Woo Hoo. Vì vậy, đây là … Tôi sẽ cố gắng dạy bạn cách đưa nhạc vào máy nghe nhạc MP3 loại thanh. VUI THÍCH