mirror of
https://github.com/kennethreitz/pytheory.git
synced 2026-06-05 06:46:14 +00:00
Refactor hello.py to rename it to examples/chord_charts.py and improve chord chart display and playback
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
from pytheory import Tone, Fretboard, CHARTS
|
||||
|
||||
# Create standard tuning (from high E to low E)
|
||||
standard_tuning = [
|
||||
Tone.from_string("E4"), # High E
|
||||
Tone.from_string("B3"), # B
|
||||
Tone.from_string("G3"), # G
|
||||
Tone.from_string("D3"), # D
|
||||
Tone.from_string("A2"), # A
|
||||
Tone.from_string("E2"), # Low E
|
||||
]
|
||||
|
||||
# Create fretboard with standard tuning
|
||||
fretboard = Fretboard(tones=standard_tuning)
|
||||
|
||||
# Define flat to sharp note mappings (updated to include all possible flats)
|
||||
flat_to_sharp = {"Ab": "G#", "Bb": "A#", "Db": "C#", "Eb": "D#", "Gb": "F#"}
|
||||
|
||||
# Add sharp to flat mappings
|
||||
sharp_to_flat = {v: k for k, v in flat_to_sharp.items()}
|
||||
|
||||
# Get all available chords from CHARTS
|
||||
all_chords = sorted(CHARTS["western"].keys())
|
||||
|
||||
print("Standard Guitar Chord Charts:")
|
||||
print("-" * 30)
|
||||
|
||||
|
||||
def fingering_to_tab(fingering):
|
||||
if not fingering:
|
||||
return ""
|
||||
|
||||
# Create 6 strings of dashes, representing the guitar strings
|
||||
strings = ["-" * 15 for _ in range(6)]
|
||||
|
||||
# For each string (starting from high E)
|
||||
for string_num, fret in enumerate(fingering):
|
||||
if fret is not None:
|
||||
# Place the fret number at the correct position
|
||||
if fret == 0:
|
||||
strings[string_num] = "0" + strings[string_num][1:]
|
||||
else:
|
||||
strings[string_num] = (
|
||||
"-" * (fret - 1) + str(fret) + strings[string_num][fret:]
|
||||
)
|
||||
|
||||
# Combine strings with newlines, and add string names
|
||||
tab = "e|" + strings[0] + "\n"
|
||||
tab += "B|" + strings[1] + "\n"
|
||||
tab += "G|" + strings[2] + "\n"
|
||||
tab += "D|" + strings[3] + "\n"
|
||||
tab += "A|" + strings[4] + "\n"
|
||||
tab += "E|" + strings[5] + "\n"
|
||||
return tab
|
||||
|
||||
|
||||
for chord_name in all_chords:
|
||||
# Store original chord name for lookup
|
||||
lookup_name = chord_name
|
||||
|
||||
# Convert flat notation to sharp only for display
|
||||
base_note = chord_name.rstrip("dim7956maj")
|
||||
if base_note in flat_to_sharp:
|
||||
# Replace the base note with its sharp equivalent for display only
|
||||
sharp_base = flat_to_sharp[base_note]
|
||||
sharp_name = chord_name.replace(base_note, sharp_base)
|
||||
print(f" Converting {chord_name} to {sharp_name}") # Debug line
|
||||
display_name = sharp_name
|
||||
else:
|
||||
display_name = chord_name
|
||||
|
||||
chord = CHARTS["western"][lookup_name] # Use original name for lookup
|
||||
|
||||
try:
|
||||
fingering = chord.fingering(fretboard=fretboard)
|
||||
print(f"\n{display_name}:")
|
||||
print(fingering_to_tab(fingering))
|
||||
except Exception as e:
|
||||
print(f"{display_name}: Unable to calculate fingering - {str(e)}")
|
||||
# Add more detailed debug information
|
||||
print(f"Debug - Chord data: {chord}")
|
||||
print(
|
||||
f"Debug - Chord tones: {chord.tones if hasattr(chord, 'tones') else 'No tones available'}"
|
||||
)
|
||||
print(f"Debug - Fretboard tuning: {[str(t) for t in fretboard.tones]}")
|
||||
print(f"Debug - Available fretboard tones: {[str(t) for t in fretboard.tones]}")
|
||||
@@ -0,0 +1,78 @@
|
||||
from time import sleep
|
||||
|
||||
from pytheory import TonedScale, Tone, CHARTS, play
|
||||
|
||||
|
||||
# Add this constant at the top of the file, after the imports
|
||||
EIGHTH_NOTE = 0.25
|
||||
QUARTER_NOTE = 0.5
|
||||
|
||||
# Add scale definition after the constants
|
||||
C_MAJOR = TonedScale(tonic="C4")
|
||||
|
||||
|
||||
def play_note(note, t=0.1):
|
||||
# Convert scale degree (1-7) to note name (0-based index)
|
||||
scale_notes = ["C4", "D4", "E4", "F4", "G4", "A4", "B4"]
|
||||
note_name = scale_notes[note - 1] # Subtract 1 because scale degrees are 1-based
|
||||
tone = Tone(note_name)
|
||||
play(tone, t=t * 1_000)
|
||||
sleep(t)
|
||||
|
||||
|
||||
# Twinkle Twinkle Little Star in C major
|
||||
# C C G G A A G (first line)
|
||||
# F F E E D D C (second line)
|
||||
# G G F F E E D (third line)
|
||||
# G G F F E E D (fourth line)
|
||||
# C C G G A A G (fifth line)
|
||||
# F F E E D D C (sixth line)
|
||||
|
||||
|
||||
def play_twinkle():
|
||||
# Define the patterns using scale degrees instead of note names
|
||||
line1 = [
|
||||
(1, EIGHTH_NOTE), # C4
|
||||
(1, EIGHTH_NOTE), # C4
|
||||
(5, EIGHTH_NOTE), # G4
|
||||
(5, EIGHTH_NOTE), # G4
|
||||
(6, EIGHTH_NOTE), # A4
|
||||
(6, EIGHTH_NOTE), # A4
|
||||
(5, QUARTER_NOTE), # G4
|
||||
]
|
||||
line2 = [
|
||||
(4, EIGHTH_NOTE), # F4
|
||||
(4, EIGHTH_NOTE), # F4
|
||||
(3, EIGHTH_NOTE), # E4
|
||||
(3, EIGHTH_NOTE), # E4
|
||||
(2, EIGHTH_NOTE), # D4
|
||||
(2, EIGHTH_NOTE), # D4
|
||||
(1, QUARTER_NOTE), # C4
|
||||
]
|
||||
line3 = [
|
||||
(5, EIGHTH_NOTE), # G4
|
||||
(5, EIGHTH_NOTE), # G4
|
||||
(4, EIGHTH_NOTE), # F4
|
||||
(4, EIGHTH_NOTE), # F4
|
||||
(3, EIGHTH_NOTE), # E4
|
||||
(3, EIGHTH_NOTE), # E4
|
||||
(2, QUARTER_NOTE), # D4
|
||||
]
|
||||
|
||||
# Construct the full melody using the patterns
|
||||
melody = (
|
||||
line1 # Twinkle twinkle little star
|
||||
+ line2 # How I wonder what you are
|
||||
+ line3 # Up above the world so high
|
||||
+ line3 # Like a diamond in the sky
|
||||
+ line1 # Twinkle twinkle little star
|
||||
+ line2 # How I wonder what you are
|
||||
)
|
||||
|
||||
print("Playing Twinkle Twinkle Little Star...")
|
||||
for note, duration in melody:
|
||||
play_note(note, duration)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
play_twinkle()
|
||||
Reference in New Issue
Block a user