Mục lục:

Máy dò nốt nhạc: 3 bước
Máy dò nốt nhạc: 3 bước

Video: Máy dò nốt nhạc: 3 bước

Video: Máy dò nốt nhạc: 3 bước
Video: Hướng dẫn Guitar từ A đến Z: Bài 3- Mẹo nhớ nốt 3 ngăn đầu tiên cực dễ 2024, Tháng mười một
Anonim
Image
Image

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

Thiết lập trình dò nốt nhạc
Thiết lập trình 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: