This commit is contained in:
Guillaume BONABAU 2025-04-24 10:36:30 +02:00
commit 04bbd2c141
23 changed files with 11256 additions and 0 deletions

BIN
Songs/NujabesFeather.mp3 Normal file

Binary file not shown.

Binary file not shown.

11007
notes_output.csv Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1 @@
OK

View File

@ -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.

View File

@ -0,0 +1 @@
OK

View File

@ -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.

View File

@ -0,0 +1 @@
OK

View File

@ -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.

29
src/Song_Spleeter.py Normal file
View File

@ -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")

211
src/WaveToNotesTests.py Normal file
View File

@ -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]}")