I want to do make a platform to play chords like guitar does. For example - to play the E chord it playes [0, 2, 2, 1, 0, 0] (from the Low-E string to the High-E string).
I'm trying to play chords on python by playing all the different strings simultaneously (by using threads).
The problem is that every time I start playing the next strings, it seems that the last string stops playing, and that the new one replaces it. So all I hear after playing a chord is the highest string (the last one).
Do I use the threads not correctly? Or is it a problem with the current functions? Or maybe it's the winsound.Beep() function that canwt handle these kind of things?
This is my code:
from winsound import Beep
import threading
import time
def play(freq, dur):
Beep(round(freq), round(dur))
def get_freq(string, fret):
a3_freq = 220
half_tone = 2 ** (1 / 12)
higher_from_a3_by = 5 * (string - 2) + fret
if string > 4:
higher_from_a3_by += 1
return a3_freq * half_tone ** higher_from_a3_by
def strum(string, fret, time):
freq = get_freq(string, fret)
t = threading.Thread(target=play, args=(freq, time))
t.start()
return t
def chord(frets, dur):
threads = []
for i in range(6):
if frets[i] != -1:
threads.append(strum(i + 1, frets[i], dur))
for t in threads:
t.join()
chord((-1, 0, 2, 2, 2, 0), 1000) # plays the A chord for one second, for example.
From what I've cheacked, the play() and get_freq() functions donwt have any problem.
So what is the problem, and how can I fix it?
Edit:
I've tried it in C# but it didn't work either. Is this the right way of starting threads in C#?
foreach (Thread t in threads)
t.Start();
foreach (Thread t in threads)
t.Join();
Gevent would make this much easier. Though still technically single threaded, context switching is so fast it would make it appear simultaneous. You can even use GIPC for multithreaded bi-directional multiprocess communication.
However I think your problem is much simpler. Your issue is the windsound module. Beep is not asynchoronous. So that is your limitation. You need to use
winsound.SND_ASYNC
This will allow you to send multiple events to play simultaneously.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With