Compare commits
9 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
7dc82932be | |
|
|
201c3cafc7 | |
|
|
a4e042dd2d | |
|
|
0a2a92b356 | |
|
|
9ff4e22796 | |
|
|
04bbd2c141 | |
|
|
44df6d4bbe | |
|
|
3a85ce8538 | |
|
|
4a092f2ba3 |
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,2 @@
|
|||
(kicad_pcb (version 20240108) (generator "pcbnew") (generator_version "8.0")
|
||||
)
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
{
|
||||
"board": {
|
||||
"active_layer": 0,
|
||||
"active_layer_preset": "",
|
||||
"auto_track_width": true,
|
||||
"hidden_netclasses": [],
|
||||
"hidden_nets": [],
|
||||
"high_contrast_mode": 0,
|
||||
"net_color_mode": 1,
|
||||
"opacity": {
|
||||
"images": 0.6,
|
||||
"pads": 1.0,
|
||||
"tracks": 1.0,
|
||||
"vias": 1.0,
|
||||
"zones": 0.6
|
||||
},
|
||||
"selection_filter": {
|
||||
"dimensions": true,
|
||||
"footprints": true,
|
||||
"graphics": true,
|
||||
"keepouts": true,
|
||||
"lockedItems": false,
|
||||
"otherItems": true,
|
||||
"pads": true,
|
||||
"text": true,
|
||||
"tracks": true,
|
||||
"vias": true,
|
||||
"zones": true
|
||||
},
|
||||
"visible_items": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
39,
|
||||
40
|
||||
],
|
||||
"visible_layers": "fffffff_ffffffff",
|
||||
"zone_display_mode": 0
|
||||
},
|
||||
"git": {
|
||||
"repo_password": "",
|
||||
"repo_type": "",
|
||||
"repo_username": "",
|
||||
"ssh_key": ""
|
||||
},
|
||||
"meta": {
|
||||
"filename": "pianist_robot.kicad_prl",
|
||||
"version": 3
|
||||
},
|
||||
"project": {
|
||||
"files": []
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,392 @@
|
|||
{
|
||||
"board": {
|
||||
"3dviewports": [],
|
||||
"design_settings": {
|
||||
"defaults": {},
|
||||
"diff_pair_dimensions": [],
|
||||
"drc_exclusions": [],
|
||||
"rules": {},
|
||||
"track_widths": [],
|
||||
"via_dimensions": []
|
||||
},
|
||||
"ipc2581": {
|
||||
"dist": "",
|
||||
"distpn": "",
|
||||
"internal_id": "",
|
||||
"mfg": "",
|
||||
"mpn": ""
|
||||
},
|
||||
"layer_presets": [],
|
||||
"viewports": []
|
||||
},
|
||||
"boards": [],
|
||||
"cvpcb": {
|
||||
"equivalence_files": []
|
||||
},
|
||||
"erc": {
|
||||
"erc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"pin_map": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
]
|
||||
],
|
||||
"rule_severities": {
|
||||
"bus_definition_conflict": "error",
|
||||
"bus_entry_needed": "error",
|
||||
"bus_to_bus_conflict": "error",
|
||||
"bus_to_net_conflict": "error",
|
||||
"conflicting_netclasses": "error",
|
||||
"different_unit_footprint": "error",
|
||||
"different_unit_net": "error",
|
||||
"duplicate_reference": "error",
|
||||
"duplicate_sheet_names": "error",
|
||||
"endpoint_off_grid": "warning",
|
||||
"extra_units": "error",
|
||||
"global_label_dangling": "warning",
|
||||
"hier_label_mismatch": "error",
|
||||
"label_dangling": "error",
|
||||
"lib_symbol_issues": "warning",
|
||||
"missing_bidi_pin": "warning",
|
||||
"missing_input_pin": "warning",
|
||||
"missing_power_pin": "error",
|
||||
"missing_unit": "warning",
|
||||
"multiple_net_names": "warning",
|
||||
"net_not_bus_member": "warning",
|
||||
"no_connect_connected": "warning",
|
||||
"no_connect_dangling": "warning",
|
||||
"pin_not_connected": "error",
|
||||
"pin_not_driven": "error",
|
||||
"pin_to_pin": "warning",
|
||||
"power_pin_not_driven": "error",
|
||||
"similar_labels": "warning",
|
||||
"simulation_model_issue": "ignore",
|
||||
"unannotated": "error",
|
||||
"unit_value_mismatch": "error",
|
||||
"unresolved_variable": "error",
|
||||
"wire_dangling": "error"
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"pinned_footprint_libs": [],
|
||||
"pinned_symbol_libs": []
|
||||
},
|
||||
"meta": {
|
||||
"filename": "pianist_robot.kicad_pro",
|
||||
"version": 1
|
||||
},
|
||||
"net_settings": {
|
||||
"classes": [
|
||||
{
|
||||
"bus_width": 12,
|
||||
"clearance": 0.2,
|
||||
"diff_pair_gap": 0.25,
|
||||
"diff_pair_via_gap": 0.25,
|
||||
"diff_pair_width": 0.2,
|
||||
"line_style": 0,
|
||||
"microvia_diameter": 0.3,
|
||||
"microvia_drill": 0.1,
|
||||
"name": "Default",
|
||||
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||
"track_width": 0.2,
|
||||
"via_diameter": 0.6,
|
||||
"via_drill": 0.3,
|
||||
"wire_width": 6
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"version": 3
|
||||
},
|
||||
"net_colors": null,
|
||||
"netclass_assignments": null,
|
||||
"netclass_patterns": []
|
||||
},
|
||||
"pcbnew": {
|
||||
"last_paths": {
|
||||
"gencad": "",
|
||||
"idf": "",
|
||||
"netlist": "",
|
||||
"plot": "",
|
||||
"pos_files": "",
|
||||
"specctra_dsn": "",
|
||||
"step": "",
|
||||
"svg": "",
|
||||
"vrml": ""
|
||||
},
|
||||
"page_layout_descr_file": ""
|
||||
},
|
||||
"schematic": {
|
||||
"annotate_start_num": 0,
|
||||
"bom_export_filename": "",
|
||||
"bom_fmt_presets": [],
|
||||
"bom_fmt_settings": {
|
||||
"field_delimiter": ",",
|
||||
"keep_line_breaks": false,
|
||||
"keep_tabs": false,
|
||||
"name": "CSV",
|
||||
"ref_delimiter": ",",
|
||||
"ref_range_delimiter": "",
|
||||
"string_delimiter": "\""
|
||||
},
|
||||
"bom_presets": [],
|
||||
"bom_settings": {
|
||||
"exclude_dnp": false,
|
||||
"fields_ordered": [
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Reference",
|
||||
"name": "Reference",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Value",
|
||||
"name": "Value",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Datasheet",
|
||||
"name": "Datasheet",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Footprint",
|
||||
"name": "Footprint",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Qty",
|
||||
"name": "${QUANTITY}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "DNP",
|
||||
"name": "${DNP}",
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"filter_string": "",
|
||||
"group_symbols": true,
|
||||
"name": "Grouped By Value",
|
||||
"sort_asc": true,
|
||||
"sort_field": "Reference"
|
||||
},
|
||||
"connection_grid_size": 50.0,
|
||||
"drawing": {
|
||||
"dashed_lines_dash_length_ratio": 12.0,
|
||||
"dashed_lines_gap_length_ratio": 3.0,
|
||||
"default_line_thickness": 6.0,
|
||||
"default_text_size": 50.0,
|
||||
"field_names": [],
|
||||
"intersheets_ref_own_page": false,
|
||||
"intersheets_ref_prefix": "",
|
||||
"intersheets_ref_short": false,
|
||||
"intersheets_ref_show": false,
|
||||
"intersheets_ref_suffix": "",
|
||||
"junction_size_choice": 3,
|
||||
"label_size_ratio": 0.375,
|
||||
"operating_point_overlay_i_precision": 3,
|
||||
"operating_point_overlay_i_range": "~A",
|
||||
"operating_point_overlay_v_precision": 3,
|
||||
"operating_point_overlay_v_range": "~V",
|
||||
"overbar_offset_ratio": 1.23,
|
||||
"pin_symbol_size": 25.0,
|
||||
"text_offset_ratio": 0.15
|
||||
},
|
||||
"legacy_lib_dir": "",
|
||||
"legacy_lib_list": [],
|
||||
"meta": {
|
||||
"version": 1
|
||||
},
|
||||
"net_format_name": "",
|
||||
"page_layout_descr_file": "",
|
||||
"plot_directory": "",
|
||||
"spice_current_sheet_as_root": false,
|
||||
"spice_external_command": "spice \"%I\"",
|
||||
"spice_model_current_sheet_as_root": true,
|
||||
"spice_save_all_currents": false,
|
||||
"spice_save_all_dissipations": false,
|
||||
"spice_save_all_voltages": false,
|
||||
"subpart_first_id": 65,
|
||||
"subpart_id_separator": 0
|
||||
},
|
||||
"sheets": [
|
||||
[
|
||||
"80af7aa2-e50e-4aba-a849-d06f270efa9f",
|
||||
"Root"
|
||||
]
|
||||
],
|
||||
"text_variables": {}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
|
|
@ -1,37 +0,0 @@
|
|||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the convention is to give header files names that end with `.h'.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||
46
lib/README
46
lib/README
|
|
@ -1,46 +0,0 @@
|
|||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into the executable file.
|
||||
|
||||
The source code of each library should be placed in a separate directory
|
||||
("lib/your_library_name/[Code]").
|
||||
|
||||
For example, see the structure of the following example libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
Example contents of `src/main.c` using Foo and Bar:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries by scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
OK
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
model_checkpoint_path: "model"
|
||||
all_model_checkpoint_paths: "model"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
OK
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
model_checkpoint_path: "model"
|
||||
all_model_checkpoint_paths: "model"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
OK
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
model_checkpoint_path: "model"
|
||||
all_model_checkpoint_paths: "model"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -6,7 +6,7 @@ import serial.tools.list_ports
|
|||
|
||||
# Define the paths
|
||||
#Short notes
|
||||
NOTES_PATH = "Player\\notes\\mp3-master\\"
|
||||
NOTES_PATH = "pysrc\\notes\\mp3-master\\"
|
||||
#Long notes
|
||||
#NOTES_PATH = r"C:\Users\Balthazar\Shared\ECAM\Advance Robotique\Project\Player\notes\high-quality-master\renamed\\"
|
||||
SERIAL_PORT = "COM5"
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
import serial
|
||||
import time
|
||||
import pygame
|
||||
from pydub import AudioSegment
|
||||
import serial.tools.list_ports
|
||||
|
||||
# Define the paths
|
||||
#Short notes
|
||||
NOTES_PATH = "Player\\notes\\mp3-master\\"
|
||||
#Long notes
|
||||
#NOTES_PATH = r"C:\Users\Balthazar\Shared\ECAM\Advance Robotique\Project\Player\notes\high-quality-master\renamed\\"
|
||||
SERIAL_PORT = "COM5" #"COM3"
|
||||
BAUD_RATE = 115200
|
||||
|
||||
# New Features
|
||||
wait_note_finish = False # Set to False to play without waiting for the note to finish
|
||||
keyboard_input = False # Set to False to disable keyboard note input
|
||||
check_com3 = True # Set to False to skip COM3 check
|
||||
|
||||
pygame.mixer.init()
|
||||
|
||||
octave = 4
|
||||
|
||||
notes = ["C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"]
|
||||
|
||||
|
||||
def play_note_with_pygame(note):
|
||||
try:
|
||||
pygame_sound = pygame.mixer.Sound(f"{NOTES_PATH}{note}.mp3")
|
||||
pygame_sound.play()
|
||||
if wait_note_finish:
|
||||
while pygame.mixer.get_busy(): # Wait until sound is finished
|
||||
pygame.time.Clock().tick(10)
|
||||
except Exception as e:
|
||||
print(f"Error playing {note}: {e}")
|
||||
|
||||
|
||||
# Check if COM3 is connected
|
||||
if check_com3:
|
||||
ports = list(serial.tools.list_ports.comports())
|
||||
com3_found = any(port.device == SERIAL_PORT for port in ports)
|
||||
if not com3_found:
|
||||
print(f"{SERIAL_PORT} not found. Switching to keyboard input mode.")
|
||||
keyboard_input = True
|
||||
|
||||
try:
|
||||
ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1)
|
||||
time.sleep(2)
|
||||
except Exception as e:
|
||||
print(f"Error opening {SERIAL_PORT}: {e}")
|
||||
keyboard_input = True
|
||||
|
||||
print("Listening for Arduino input...")
|
||||
|
||||
while True:
|
||||
try:
|
||||
# Keyboard input for playing notes
|
||||
if keyboard_input:
|
||||
user_input = input("Enter note (C, Db, D, ... B) or 'q' to quit: ")
|
||||
if user_input == 'q':
|
||||
break
|
||||
if user_input in notes:
|
||||
play_note_with_pygame(f"{user_input}{octave}")
|
||||
|
||||
# Arduino input for playing notes
|
||||
data = ser.readline().decode('utf-8', errors='ignore').strip()
|
||||
if data:
|
||||
print("data : " + data)
|
||||
note = data
|
||||
if note in notes:
|
||||
play_note_with_pygame(f"{note}{octave}")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("Exiting...")
|
||||
break
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
ser.close()
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
|
||||
def separate_audio(input_file,stems,output_folder="output"):
|
||||
try:
|
||||
# Create output directory if it doesn't exist
|
||||
os.makedirs(output_folder, exist_ok=True)
|
||||
|
||||
input_file_name=input_file
|
||||
input_file_name= input_file_name.replace(".mp3","")
|
||||
# Use python -m to ensure the correct module is called
|
||||
command = [
|
||||
sys.executable, "-m", "spleeter", "separate",
|
||||
"-o", output_folder+"\\"+input_file_name+stems,
|
||||
"-p", "spleeter:"+stems,
|
||||
"C:\\Users\\louis\\Desktop\\VScode\\Python\\Songs\\"+input_file,
|
||||
]
|
||||
|
||||
print(f"Running command: {' '.join(command)}")
|
||||
subprocess.run(command, check=True)
|
||||
print(f"Separation complete! Files saved in {output_folder}/")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error running Spleeter: {e}")
|
||||
except Exception as e:
|
||||
print(f"Unexpected error: {e}")
|
||||
|
||||
# Example usage
|
||||
separate_audio("TheSylversRememberTheRain.mp3" , "4stems")
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
import crepe
|
||||
from scipy.io import wavfile
|
||||
import json
|
||||
import csv
|
||||
import numpy as np
|
||||
|
||||
|
||||
# Define file paths
|
||||
fileName = "NujabesFeather4stems/other.wav"
|
||||
audio_file = "output/"+fileName
|
||||
# Replace the slash with nothing to flatten the path
|
||||
flat_name = fileName.replace("/", "")
|
||||
# Remove the .wav extension
|
||||
without_extension = flat_name[:-4] # removes last 4 characters (.wav)
|
||||
# Create the output filename
|
||||
output_csv = "crepe_output" + without_extension + ".csv"
|
||||
|
||||
def getNotesFromFreq(freqNotesArray, freqNotesConfidence):
|
||||
notes_json='''{
|
||||
"notes": [
|
||||
{"note": "A", "octave": 0, "frequency": 27.5},
|
||||
{"note": "Bb", "octave": 0, "frequency": 29.135},
|
||||
{"note": "B", "octave": 0, "frequency": 30.868},
|
||||
|
||||
{"note": "C", "octave": 1, "frequency": 32.703},
|
||||
{"note": "Db", "octave": 1, "frequency": 34.648},
|
||||
{"note": "D", "octave": 1, "frequency": 36.708},
|
||||
{"note": "Eb", "octave": 1, "frequency": 38.891},
|
||||
{"note": "E", "octave": 1, "frequency": 41.203},
|
||||
{"note": "F", "octave": 1, "frequency": 43.654},
|
||||
{"note": "Gb", "octave": 1, "frequency": 46.249},
|
||||
{"note": "G", "octave": 1, "frequency": 48.999},
|
||||
{"note": "Ab", "octave": 1, "frequency": 51.913},
|
||||
{"note": "A", "octave": 1, "frequency": 55.0},
|
||||
{"note": "Bb", "octave": 1, "frequency": 58.27},
|
||||
{"note": "B", "octave": 1, "frequency": 61.735},
|
||||
|
||||
{"note": "C", "octave": 2, "frequency": 65.406},
|
||||
{"note": "Db", "octave": 2, "frequency": 69.296},
|
||||
{"note": "D", "octave": 2, "frequency": 73.416},
|
||||
{"note": "Eb", "octave": 2, "frequency": 77.782},
|
||||
{"note": "E", "octave": 2, "frequency": 82.407},
|
||||
{"note": "F", "octave": 2, "frequency": 87.307},
|
||||
{"note": "Gb", "octave": 2, "frequency": 92.499},
|
||||
{"note": "G", "octave": 2, "frequency": 97.999},
|
||||
{"note": "Ab", "octave": 2, "frequency": 103.826},
|
||||
{"note": "A", "octave": 2, "frequency": 110.0},
|
||||
{"note": "Bb", "octave": 2, "frequency": 116.541},
|
||||
{"note": "B", "octave": 2, "frequency": 123.471},
|
||||
|
||||
{"note": "C", "octave": 3, "frequency": 130.813},
|
||||
{"note": "Db", "octave": 3, "frequency": 138.591},
|
||||
{"note": "D", "octave": 3, "frequency": 146.832},
|
||||
{"note": "Eb", "octave": 3, "frequency": 155.563},
|
||||
{"note": "E", "octave": 3, "frequency": 164.814},
|
||||
{"note": "F", "octave": 3, "frequency": 174.614},
|
||||
{"note": "Gb", "octave": 3, "frequency": 184.997},
|
||||
{"note": "G", "octave": 3, "frequency": 195.998},
|
||||
{"note": "Ab", "octave": 3, "frequency": 207.652},
|
||||
{"note": "A", "octave": 3, "frequency": 220.0},
|
||||
{"note": "Bb", "octave": 3, "frequency": 233.082},
|
||||
{"note": "B", "octave": 3, "frequency": 246.942},
|
||||
|
||||
{"note": "C", "octave": 4, "frequency": 261.626},
|
||||
{"note": "Db", "octave": 4, "frequency": 277.183},
|
||||
{"note": "D", "octave": 4, "frequency": 293.665},
|
||||
{"note": "Eb", "octave": 4, "frequency": 311.127},
|
||||
{"note": "E", "octave": 4, "frequency": 329.628},
|
||||
{"note": "F", "octave": 4, "frequency": 349.228},
|
||||
{"note": "Gb", "octave": 4, "frequency": 369.994},
|
||||
{"note": "G", "octave": 4, "frequency": 391.995},
|
||||
{"note": "Ab", "octave": 4, "frequency": 415.305},
|
||||
{"note": "A", "octave": 4, "frequency": 440.0},
|
||||
{"note": "Bb", "octave": 4, "frequency": 466.164},
|
||||
{"note": "B", "octave": 4, "frequency": 493.883},
|
||||
|
||||
{"note": "C", "octave": 5, "frequency": 523.251},
|
||||
{"note": "Db", "octave": 5, "frequency": 554.365},
|
||||
{"note": "D", "octave": 5, "frequency": 587.33},
|
||||
{"note": "Eb", "octave": 5, "frequency": 622.254},
|
||||
{"note": "E", "octave": 5, "frequency": 659.255},
|
||||
{"note": "F", "octave": 5, "frequency": 698.456},
|
||||
{"note": "Gb", "octave": 5, "frequency": 739.989},
|
||||
{"note": "G", "octave": 5, "frequency": 783.991},
|
||||
{"note": "Ab", "octave": 5, "frequency": 830.609},
|
||||
{"note": "A", "octave": 5, "frequency": 880.0},
|
||||
{"note": "Bb", "octave": 5, "frequency": 932.328},
|
||||
{"note": "B", "octave": 5, "frequency": 987.767},
|
||||
|
||||
{"note": "C", "octave": 6, "frequency": 1046.502},
|
||||
{"note": "Db", "octave": 6, "frequency": 1108.731},
|
||||
{"note": "D", "octave": 6, "frequency": 1174.659},
|
||||
{"note": "Eb", "octave": 6, "frequency": 1244.508},
|
||||
{"note": "E", "octave": 6, "frequency": 1318.51},
|
||||
{"note": "F", "octave": 6, "frequency": 1396.913},
|
||||
{"note": "Gb", "octave": 6, "frequency": 1479.978},
|
||||
{"note": "G", "octave": 6, "frequency": 1567.982},
|
||||
{"note": "Ab", "octave": 6, "frequency": 1661.219},
|
||||
{"note": "A", "octave": 6, "frequency": 1760.0},
|
||||
{"note": "Bb", "octave": 6, "frequency": 1864.655},
|
||||
{"note": "B", "octave": 6, "frequency": 1975.533},
|
||||
|
||||
{"note": "C", "octave": 7, "frequency": 2093.005},
|
||||
{"note": "Db", "octave": 7, "frequency": 2217.461},
|
||||
{"note": "D", "octave": 7, "frequency": 2349.318},
|
||||
{"note": "Eb", "octave": 7, "frequency": 2489.016},
|
||||
{"note": "E", "octave": 7, "frequency": 2637.021},
|
||||
{"note": "F", "octave": 7, "frequency": 2793.826},
|
||||
{"note": "Gb", "octave": 7, "frequency": 2959.955},
|
||||
{"note": "G", "octave": 7, "frequency": 3135.964},
|
||||
{"note": "Ab", "octave": 7, "frequency": 3322.438},
|
||||
{"note": "A", "octave": 7, "frequency": 3520.0},
|
||||
{"note": "Bb", "octave": 7, "frequency": 3729.31},
|
||||
{"note": "B", "octave": 7, "frequency": 3951.066},
|
||||
|
||||
{"note": "C", "octave": 8, "frequency": 4186.009}
|
||||
]
|
||||
}'''
|
||||
notes_data = json.loads(notes_json)
|
||||
finalNoteArray = []
|
||||
|
||||
for i, freq in enumerate(freqNotesArray):
|
||||
bestFreqDif = float('inf')
|
||||
if freqNotesConfidence[i] < 0.5:
|
||||
finalNote = "NoNoteFound"
|
||||
else :
|
||||
for note_data in notes_data['notes']:
|
||||
freqDif = abs(note_data['frequency'] - freq)
|
||||
if freqDif < bestFreqDif:
|
||||
bestFreqDif = freqDif
|
||||
finalNote = note_data['note']
|
||||
finalNoteArray.append(finalNote)
|
||||
|
||||
|
||||
return finalNoteArray
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
# Try to read existing CSV
|
||||
with open(output_csv, newline='') as csvfile:
|
||||
reader = csv.DictReader(csvfile)
|
||||
data = list(reader)
|
||||
|
||||
# Extract frequency and confidence from CSV
|
||||
time = [float(row['time']) for row in data]
|
||||
frequency = [float(row['frequency']) for row in data]
|
||||
confidence = [float(row['confidence']) for row in data]
|
||||
|
||||
print(f"Loaded {len(frequency)} data points from existing CSV")
|
||||
|
||||
except (FileNotFoundError, KeyError) as e:
|
||||
# If file doesn't exist or has incorrect format, process the audio
|
||||
print(f"Processing audio file: {audio_file}")
|
||||
|
||||
# Read audio file
|
||||
sr, audio = wavfile.read(audio_file)
|
||||
|
||||
# Ensure audio is mono (if stereo, take first channel)
|
||||
if len(audio.shape) > 1 and audio.shape[1] > 1:
|
||||
audio = audio[:, 0]
|
||||
|
||||
# Convert audio to float32 if needed
|
||||
if audio.dtype != np.float32:
|
||||
# Normalize based on data type
|
||||
if audio.dtype == np.int16:
|
||||
audio = audio.astype(np.float32) / 32768.0
|
||||
elif audio.dtype == np.int32:
|
||||
audio = audio.astype(np.float32) / 2147483648.0
|
||||
|
||||
# Run CREPE pitch detection
|
||||
time, frequency, confidence, activation = crepe.predict(audio, sr, viterbi=True)
|
||||
|
||||
# Write results to CSV
|
||||
with open(output_csv, 'w', newline='') as csvfile:
|
||||
fieldnames = ['time', 'frequency', 'confidence']
|
||||
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
|
||||
|
||||
writer.writeheader()
|
||||
for i,ArrayCombined in enumerate(zip(time, frequency, confidence)):
|
||||
if confidence[i] >= 0.5:
|
||||
writer.writerow({
|
||||
'time': ArrayCombined[0],
|
||||
'frequency': ArrayCombined[1],
|
||||
'confidence': ArrayCombined[2]
|
||||
})
|
||||
|
||||
print(f"Saved {len(frequency)} data points to {output_csv}")
|
||||
|
||||
# Convert frequencies to notes
|
||||
notes = getNotesFromFreq(frequency, confidence)
|
||||
|
||||
# Save notes to another CSV file
|
||||
notes_csv = "notes_output.csv"
|
||||
with open(notes_csv, 'w', newline='') as csvfile:
|
||||
fieldnames = ['time', 'frequency', 'confidence', 'note']
|
||||
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
|
||||
|
||||
writer.writeheader()
|
||||
for i,ArrayCombined in enumerate(zip(time, frequency, confidence, notes)):
|
||||
if confidence[i] >= 0.5:
|
||||
writer.writerow({
|
||||
'time': ArrayCombined[0],
|
||||
'frequency': ArrayCombined[1],
|
||||
'confidence': ArrayCombined[2],
|
||||
'note': ArrayCombined[3]
|
||||
})
|
||||
print(frequency[:30])
|
||||
print(f"Saved {len(notes)} notes to {notes_csv}")
|
||||
print(f"Sample of notes: {notes[:10]}")
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import json
|
||||
import time
|
||||
|
||||
# Read the sensors positions from the sensor_positions.json file
|
||||
with open('sensor_positions.json', 'r') as f:
|
||||
config = json.load(f)
|
||||
|
||||
###########################################################################
|
||||
## SET THE NOTES TO PLAY AS SUCH:
|
||||
## notes_to_play = [NOTE1, NOTE2,...,NOTEx]
|
||||
## with the notes being
|
||||
## C, C#, D, D#, E, F, F#, G, G#, A, A#, B
|
||||
## = 1, 2 , 3, 4 , 5, 6, 7 , 8, 9 ,10, 11, 12
|
||||
##
|
||||
## To play at rythm, the duration of a note must be added after the ID
|
||||
## like so: notes_to_play = [NOTE1, NOTE2,'half', NOTE3, 'eigth',...,NOTEx]
|
||||
## to play NOTE2 for longer and NOTE3 faster
|
||||
###########################################################################
|
||||
|
||||
#note_to_play = 2 #note id to play (see sensor_positions.json)
|
||||
|
||||
#notes_to_play = [1,2,3,4,5,6,7,8,9,10,11,12]
|
||||
|
||||
#play Au clair de la Lune
|
||||
#notes_to_play = [1, 1, 1, 3, 5,'half', 3,'half', 1, 5, 3, 3, 1, 'half']
|
||||
|
||||
#play Ode yo Joy
|
||||
#notes_to_play = [5, 5, 6, 8, 8, 6, 5, 3, 1, 1, 3, 5, 5, 3, 3, 'half', 5, 5, 6, 8, 8, 6, 5, 3, 1, 1, 3, 5, 3, 1, 1, 'half', 3, 3, 5, 1, 3, 5,'eigth', 6,'eigth', 5, 1, 3, 5,'eigth', 6,'eigth', 5, 3, 1, 3, 8, 'half', 5, 5, 6, 8, 8, 6, 5, 3, 1, 1, 3, 5, 3, 1, 1]
|
||||
|
||||
#play Happy Birthday
|
||||
notes_to_play = [1, 1, 3, 1, 6, 5,'half', 1, 1, 3, 1, 8, 6,'half', 1, 1, 10, 8, 6, 5, 3,'eigth', 3,'half', 11, 11, 10, 6, 8, 6]
|
||||
|
||||
#play megalovania
|
||||
#notes_to_play = [3, 3, 10, 9, 8, 6, 3, 6, 8]
|
||||
|
||||
notes_to_play = [3,3, 5,3, 10 ,5 ,10,12,6,5,3]
|
||||
|
||||
notes_to_play.append('end') #to know when it is the end of the array
|
||||
|
||||
|
||||
|
||||
delay = 0.1
|
||||
note_delay = 0.2 #delay between notes, corresponding to tempo
|
||||
init_note_delay = note_delay
|
||||
|
||||
if os.name == 'nt':
|
||||
import msvcrt
|
||||
def getch():
|
||||
return msvcrt.getch().decode()
|
||||
else:
|
||||
import sys, tty, termios
|
||||
fd = sys.stdin.fileno()
|
||||
old_settings = termios.tcgetattr(fd)
|
||||
def getch():
|
||||
try:
|
||||
tty.setraw(sys.stdin.fileno())
|
||||
ch = sys.stdin.read(1)
|
||||
finally:
|
||||
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
||||
return ch
|
||||
|
||||
from dynamixel_sdk import * # Uses Dynamixel SDK library
|
||||
|
||||
# Control table address
|
||||
ADDR_PRO_TORQUE_ENABLE = 24 # Control table address is different in Dynamixel model
|
||||
ADDR_PRO_GOAL_POSITION = 30
|
||||
ADDR_PRO_PRESENT_POSITION = 37
|
||||
|
||||
# Protocol version
|
||||
PROTOCOL_VERSION = 2.0 # See which protocol version is used in the Dynamixel
|
||||
|
||||
# Set Dynamixel motors IDs
|
||||
DXL1_ID = 1
|
||||
DXL2_ID = 2
|
||||
DXL3_ID = 3
|
||||
|
||||
BAUDRATE = 1000000 # Dynamixel baudrate : 1000000
|
||||
DEVICENAME = 'COM10' # Check which port is being used on your controller
|
||||
# ex) Windows: "COM1" Linux: "/dev/ttyUSB0" Mac: "/dev/tty.usbserial-*"
|
||||
|
||||
TORQUE_ENABLE = 1 # Value for enabling the torque
|
||||
TORQUE_DISABLE = 0 # Value for disabling the torque
|
||||
|
||||
|
||||
|
||||
#CONNECT TO ROBOT
|
||||
# Initialize PortHandler instance
|
||||
# Set the port path
|
||||
# Get methods and members of PortHandlerLinux or PortHandlerWindows
|
||||
portHandler = PortHandler(DEVICENAME)
|
||||
|
||||
# Initialize PacketHandler instance
|
||||
# Set the protocol version
|
||||
# Get methods and members of Protocol1PacketHandler or Protocol2PacketHandler
|
||||
packetHandler = PacketHandler(PROTOCOL_VERSION)
|
||||
|
||||
# Open port
|
||||
if portHandler.openPort():
|
||||
print("Succeeded to open the port")
|
||||
else:
|
||||
print("Failed to open the port")
|
||||
print("Press any key to terminate...")
|
||||
getch()
|
||||
quit()
|
||||
|
||||
# Set port baudrate
|
||||
if portHandler.setBaudRate(BAUDRATE):
|
||||
print("Succeeded to change the baudrate")
|
||||
else:
|
||||
print("Failed to change the baudrate")
|
||||
print("Press any key to terminate...")
|
||||
getch()
|
||||
quit()
|
||||
|
||||
|
||||
|
||||
#ENABLE TORQUES
|
||||
# Enable Dynamixel#1 Torque
|
||||
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL1_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_ENABLE)
|
||||
if dxl_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||
elif dxl_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||
else:
|
||||
print("Dynamixel#%d has been successfully connected" % DXL1_ID)
|
||||
|
||||
# Enable Dynamixel#2 Torque
|
||||
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL2_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_ENABLE)
|
||||
if dxl_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||
elif dxl_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||
else:
|
||||
print("Dynamixel#%d has been successfully connected" % DXL2_ID)
|
||||
|
||||
# Enable Dynamixel#3 Torque
|
||||
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL3_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_ENABLE)
|
||||
if dxl_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||
elif dxl_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||
else:
|
||||
print("Dynamixel#%d has been successfully connected" % DXL3_ID)
|
||||
|
||||
|
||||
#PLAY NOTES
|
||||
index = 0
|
||||
dxl2_goal_position = config["sensors"][0]["q2"] # Goal position 2
|
||||
while index < len(notes_to_play):
|
||||
if notes_to_play[index]=='end': #end the loop if after last note
|
||||
break
|
||||
|
||||
time.sleep(note_delay)
|
||||
note_delay = init_note_delay
|
||||
|
||||
packetHandler.write4ByteTxRx(portHandler, 2, ADDR_PRO_GOAL_POSITION, dxl2_goal_position-80) #move up between notes to avoid collisions
|
||||
|
||||
note_to_play = notes_to_play[index] #check the current note
|
||||
if note_to_play == 'half' or note_to_play == 'eigth': #skip the position if it is a 'half' or an 'eigth'
|
||||
index = index+1
|
||||
note_to_play = notes_to_play[index]
|
||||
|
||||
|
||||
if notes_to_play[index+1] == 'half': #if the next position is /'half' wait longer/ after playing the current note
|
||||
note_delay = init_note_delay*4
|
||||
elif notes_to_play[index+1] == 'eigth': #if the next position is /'eigth' wait less/ after playing the current note
|
||||
note_delay = init_note_delay/4
|
||||
|
||||
#Get note joint values from Json file
|
||||
dxl1_goal_position = config["sensors"][note_to_play-1]["q1"] # Goal position 1
|
||||
dxl2_goal_position = config["sensors"][note_to_play-1]["q2"] # Goal position 2
|
||||
dxl3_goal_position = config["sensors"][note_to_play-1]["q3"] # Goal position 3
|
||||
|
||||
while 1:
|
||||
#print("Press any key to continue! (or press ESC to quit!)") #
|
||||
#if getch() == chr(0x1b): #causes errors
|
||||
# break #
|
||||
|
||||
|
||||
# Move motor 1, then 3, and then 2 to avoid collisions
|
||||
|
||||
# Motor 1
|
||||
# Write goal position 1
|
||||
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL1_ID, ADDR_PRO_GOAL_POSITION, dxl1_goal_position)
|
||||
if dxl_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||
elif dxl_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||
time.sleep(delay)
|
||||
|
||||
|
||||
|
||||
# Motor 3
|
||||
# Write goal position 3
|
||||
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL3_ID, ADDR_PRO_GOAL_POSITION, dxl3_goal_position)
|
||||
if dxl_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||
elif dxl_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||
time.sleep(delay)
|
||||
|
||||
|
||||
|
||||
# Motor 2
|
||||
# Write goal position 2
|
||||
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL2_ID, ADDR_PRO_GOAL_POSITION, dxl2_goal_position)
|
||||
if dxl_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||
elif dxl_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||
time.sleep(delay)
|
||||
|
||||
|
||||
index = index + 1
|
||||
break
|
||||
# go to next position
|
||||
|
||||
|
||||
|
||||
#GO TO MIDDLE POSITION
|
||||
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL2_ID, ADDR_PRO_GOAL_POSITION, 30)
|
||||
time.sleep(0.5)
|
||||
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL3_ID, ADDR_PRO_GOAL_POSITION, 500)
|
||||
time.sleep(0.5)
|
||||
dxl_comm_result, dxl_error = packetHandler.write4ByteTxRx(portHandler, DXL1_ID, ADDR_PRO_GOAL_POSITION, 500)
|
||||
time.sleep(0.5)
|
||||
|
||||
# DISABLE DYNAMIXEL TORQUES 1 2 3
|
||||
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL1_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_DISABLE)
|
||||
if dxl_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||
elif dxl_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||
|
||||
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL2_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_DISABLE)
|
||||
if dxl_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||
elif dxl_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||
|
||||
dxl_comm_result, dxl_error = packetHandler.write1ByteTxRx(portHandler, DXL3_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_DISABLE)
|
||||
if dxl_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(dxl_comm_result))
|
||||
elif dxl_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(dxl_error))
|
||||
|
||||
|
||||
|
||||
# Close port
|
||||
portHandler.closePort()
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"sensors": [
|
||||
{
|
||||
"id": 1,
|
||||
"note": "C",
|
||||
"type": "natural",
|
||||
"q1": 770,
|
||||
"q2": 170,
|
||||
"q3": 530
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"note": "C",
|
||||
"type": "sharp",
|
||||
"q1": 800,
|
||||
"q2": 89,
|
||||
"q3": 735
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"note": "D",
|
||||
"type": "natural",
|
||||
"q1": 715,
|
||||
"q2": 170,
|
||||
"q3": 530
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"note": "D",
|
||||
"type": "sharp",
|
||||
"q1": 650,
|
||||
"q2": 89,
|
||||
"q3": 735
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"note": "E",
|
||||
"type": "natural",
|
||||
"q1": 600 ,
|
||||
"q2": 170,
|
||||
"q3": 530
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"note": "F",
|
||||
"type": "natural",
|
||||
"q1": 520,
|
||||
"q2": 170,
|
||||
"q3": 530
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"note": "F",
|
||||
"type": "sharp",
|
||||
"q1": 516,
|
||||
"q2": 89,
|
||||
"q3": 735
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"note": "G",
|
||||
"type": "natural",
|
||||
"q1": 445,
|
||||
"q2": 170,
|
||||
"q3": 530
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"note": "G",
|
||||
"type": "sharp",
|
||||
"q1": 360,
|
||||
"q2": 89,
|
||||
"q3": 735
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"note": "A",
|
||||
"type": "natural",
|
||||
"q1": 333,
|
||||
"q2": 170,
|
||||
"q3": 530
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"note": "A",
|
||||
"type": "sharp",
|
||||
"q1": 229,
|
||||
"q2": 89,
|
||||
"q3": 735
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"note": "B",
|
||||
"type": "natural",
|
||||
"q1": 270,
|
||||
"q2": 170,
|
||||
"q3": 530
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/**
|
||||
* This file is used for debugging the analog values of the pins on the ESP32.
|
||||
* It reads the analog values from the specified pins and prints them to the Serial Monitor.
|
||||
* The values are color-coded based on a defined threshold.
|
||||
* Values below the threshold are printed in green, while values above the threshold are printed in red.
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
|
||||
#define THRESHOLD 3000 // Define the threshold value for analog readings
|
||||
#define COLOR_RED "\033[31m" // ANSI escape code for red color
|
||||
#define COLOR_GREEN "\033[32m" // ANSI escape code for green color
|
||||
#define COLOR_RST "\033[0m" // ANSI escape code to reset color
|
||||
|
||||
//const int pinList[] = {34, 35, 32, 33, 25, 26, 27, 14, 15, 2, 0, 4}; // Array of the pins you want to use
|
||||
const int pinList[] = {4, 0, 2, 15, 14, 27, 26, 25, 33, 32, 35, 34}; // Array of the pins you want to use
|
||||
const int numPins = sizeof(pinList) / sizeof(pinList[0]); // Number of pins in the array
|
||||
|
||||
int ArrayStates[numPins]; // Array to store previous states of pins
|
||||
float ArrayValues[numPins]; // Array to store analog values of pins
|
||||
|
||||
template <typename T>
|
||||
void printArray(T array[], int size);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
// Initialize each pin in the pinList as an input
|
||||
for (int i = 0; i < numPins; i++) {
|
||||
pinMode(pinList[i], INPUT); // Set pins as input
|
||||
ArrayStates[i] = 0; // Set initial state to 0
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for (int i = 0; i < numPins; i++) {
|
||||
int analogValue = analogRead(pinList[i]); // Read the analog value of the pin
|
||||
ArrayStates[i] = (analogValue < THRESHOLD) ? 1 : 0; // Compare with threshold
|
||||
ArrayValues[i] = analogValue; // Store the analog value
|
||||
}
|
||||
printArray(ArrayValues, numPins);
|
||||
//Serial.print(">States: ");
|
||||
//printArray(ArrayStates, numPins);
|
||||
//delay(0); // Add a small delay to avoid flooding the output
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void printArray(T array[], int size) {
|
||||
Serial.print("["); // Start of the message
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[i] < THRESHOLD) {
|
||||
Serial.print(COLOR_GREEN); // Change color to red if below threshold
|
||||
} else {
|
||||
Serial.print(COLOR_RED); // Change color to green if above threshold
|
||||
}
|
||||
Serial.print(array[i]); // Print the value
|
||||
Serial.print(COLOR_RST); // Reset color to default
|
||||
if (i < size - 1) {
|
||||
Serial.print(", "); // Add a comma and space if it's not the last element
|
||||
}
|
||||
}
|
||||
Serial.println("]"); // End of the message
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/**
|
||||
* This file is used for debugging the analog values of the pins on the ESP32.
|
||||
* It reads the analog values from the specified pins and prints them to the Serial Monitor.
|
||||
* The values are color-coded based on a defined threshold.
|
||||
* Values below the threshold are printed in green, while values above the threshold are printed in red.
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
|
||||
#define THRESHOLD 3000 // Define the threshold value for analog readings
|
||||
|
||||
//const int pinList[] = {34, 35, 32, 33, 25, 26, 27, 14, 15, 2, 0, 4}; // Array of the pins you want to use
|
||||
const int pinList[] = {4, 0, 2, 15, 14, 27, 26, 25, 33, 32, 35, 34}; // Array of the pins you want to use
|
||||
const int numPins = sizeof(pinList) / sizeof(pinList[0]); // Number of pins in the array
|
||||
const char* noteList[] = {"C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"}; // Array of note names
|
||||
|
||||
int ArrayStates[numPins]; // Array to store previous states of pins
|
||||
int LastSentStates[numPins]; // Array to store last sent states of pins
|
||||
float ArrayValues[numPins]; // Array to store analog values of pins
|
||||
|
||||
bool isArrayEmpty(int array[], int size) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array[i] != 0) { // Check if any element is not zero
|
||||
return false; // Array is not empty
|
||||
}
|
||||
}
|
||||
return true; // Array is empty
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
// Initialize each pin in the pinList as an input
|
||||
for (int i = 0; i < numPins; i++) {
|
||||
pinMode(pinList[i], INPUT); // Set pins as input
|
||||
ArrayStates[i] = 0; // Set initial state to 0
|
||||
}
|
||||
Serial.println("Starting up..."); // Print a message indicating startup
|
||||
}
|
||||
|
||||
void loop() {
|
||||
for (int i = 0; i < numPins; i++) {
|
||||
int analogValue = analogRead(pinList[i]); // Read the analog value of the pin
|
||||
ArrayStates[i] = (analogValue < THRESHOLD) ? 1 : 0; // Compare with threshold
|
||||
ArrayValues[i] = analogValue; // Store the analog value
|
||||
}
|
||||
if (memcmp(ArrayStates, LastSentStates, sizeof(ArrayStates)) != 0) {
|
||||
memcpy(LastSentStates, ArrayStates, sizeof(ArrayStates)); // Update last sent states
|
||||
if (isArrayEmpty(ArrayStates, numPins) == false) {
|
||||
for (int i = 0; i < numPins; i++) {
|
||||
if (ArrayStates[i] == 1) {
|
||||
Serial.print(noteList[i]); // Print the note name if the state is 1
|
||||
Serial.print(" "); // Add a space between note names
|
||||
}
|
||||
}
|
||||
Serial.println(); // Print a new line after printing all note names
|
||||
delay(250); //avoid flickering in the sensing
|
||||
}
|
||||
}
|
||||
}
|
||||
11
test/README
11
test/README
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||
Loading…
Reference in New Issue