Does any body have an example piece of code for allowing computer microphone input using the minim library on the python platform? I am trying to build a sound reactive drawing tool but am not able to find and example mic input code anywhere…
This is a Catalina issue – Processing, regardless of the mode or code, cannot access your mic. According to the GitHub thread, you can resolve the issue by launching Processing from the Terminal.
Launch Processing via the Terminal, switch to Java mode, then test an example (File > Examples > Sound > IO > AudioInput). If it works in Java mode, it should work in Python mode too. Either way, this will help pinpoint the problem.
Unfortunately I cannot test this because I have no access to a Catalina machine right now.
I have managed to get it working on a different operating system. And I’m going to use the Sound Library to try and put this thing together.
I would like to create a toggle switch with my key board to turn the mic (and amp.analzye() for the effects) on and off with a small ellipse that changes from red to green in the bottom corner when the mic is active… Ideally I would have this done with the space bar.
This is what I have so far in terms of a switch. From what I can gather I might need to create a global variable that is initially set to off eg mic_switch = False? Then have this change to True with the keyPressed() function. I am not sure what part of the mic = AudioIn(this)/mic.start() command I can convert into a boolean to have switched?
Yes, you can use a global variable. Here’s some code to illustrate:
add_library('sound')
mic_on = True # global variable for mic state
def setup():
global mic, amp
size(500, 500)
mic = AudioIn(this, 0)
mic.start()
amp = Amplitude(this)
amp.input(mic)
def draw():
background('#FFFFFF')
if mic_on:
# things to do when the mic is on
fill('#00FF00')
circle(450, 450, 20)
diameter = map(amp.analyze(), 0, 1, 10, width)
circle(width/2, height/2, diameter)
else:
# things to do when the mic is off
fill('#FF0000')
circle(450, 450, 20)
def keyPressed():
global mic_on
if key == ' ': # detect space key
mic_on = not mic_on # invert boolean
@tabreturn this is amazing thank you. Things are coming together despite the system difficulties - the windows comp I am using keeps crashing…
Where I’m at right now… I’m not sure what the best way of taking the information on the screen that is drawn when the mic is off, and using the variable taken from the amp.analyze and effecting the whole image.
I have been able to iterate over all of the pixels and change the colour of them (but not have them change back when the mic is off). And I figured that the translate() would have the screen moving around (When I used the translate with your code I have had the ellipse moving, but only towards the bottom right of the window). But I’m not sure how to combine the amp.analyze date with the translate() and apply it to the whole drawing…
Do I have to have a defined object to apply the translate() to or can I apply it to everything that is on the window?
The translate() function applies to everything beneath it. Note, however, that if translate() is called within draw(), the transformation is reset when the loop begins again.
I’m unclear on what you’re asking here. It sounds like you’re loading in an image and manipulating the pixel values using the mic. But I don’t know what the goal is. You say, “but [moving] only towards the bottom right of the window”. How do you want to move things? Up and down? In circles? Shrink and grow? …
Hmm maybe it won’t work as there isn’t necessarily an object beneath it. Unless there is a way of indicating for it to apply to the whole image?
The idea is to be able to draw on the screen with the mouse when the mic is off, then when the mic is turned on, translate would apply to everything that has been drawn on the window, with the degree of movement coming from the amp.analyze. I would like to have things move in all directions randomly with the degree of movement coming from the mic input. Does this make sense?
What is the mouse drawing? Circles, squares, lines, pixels? It sounds like each circle/square/line/pixel will move about independently? What algorithm will you use to guide them – a random walk, something that employs vectors? When you say degree of movement, is degree a reference to angle or quantity?
I have too many questions. I think you’ll need to provide some diagrams before I can answer any of this.
To combine what we have put together so far. This is the guts of what I am trying to achieve…
add_library('sound')
mic_on = False
def setup():
global mic, amp
size(800, 800)
background(250)
#sound input and analysis
mic = AudioIn(this, 0)
mic.start()
amp = Amplitude(this)
amp.input(mic)
def draw():
global mic_on
if mic_on:
# variable coming from the volume of the mic information
# which is applied to the transformation when the mic is ON
sound_variable = map(amp.analyze(), 0, 1, 10, 255)
noStroke() #EFX on indicator
fill('#00FF00')
circle(750, 750, 20)
fill("#183CC6")
textSize(20)
text("EFX", 680, 758)
else:
# drawing tool with the mouse
if mousePressed:
fill(random(0, height), random(0, width), 100)
ellipse(mouseX, mouseY, 15,15)
noStroke() #EFX off indicator
fill('#FF0000')
circle(750, 750, 20)
fill("#183CC6")
textSize(20)
text("EFX", 680, 758)
def keyPressed():
global mic_on
if key == ' ':
mic_on = not mic_on # invert the mic state
if mic_on == False and key == 'c': #clear the drawing surface
background(250)
And yes exactly random walk, the degree being quantity, or distance moved in conjunction with the amp sound_variable variable. I want to add a colour change with mouse position but that can come afterwards.
It’s probably best to store the circles you draw in a list. As you draw new circles, you append them to that list. Each frame, you loop through the list to render the circles.
Here’s a demo for you to riff off –
def setup():
size(800, 800)
circles = []
def draw():
global circles
background('#FFFFFF')
if mousePressed:
'''
create a new circle
(you could also use a list-in-a-list instead of a dictionary-in-a-list)
'''
circ = {
'x' : mouseX,
'y' : mouseY,
'fill' : color(random(255), random(255), random(255))
}
# add the new circle to the list
circles.append(circ)
# render the list of circles
for circ in circles:
fill(circ['fill'])
circle(circ['x'], circ['y'], 15)
if keyPressed:
# press any key to randomly move the circles
for circ in circles:
circ['x'] += random(-5, 5)
circ['y'] += random(-5, 5)
Amazing. I’ve managed to get it all together and working, Colour input from the keyboard and the circle movement hooked up to the mic, with the on/off switch making things happen! It works!
It was so close! I had everything working then tried to add a couple more keyboard commands and something changed. I want to be able to clear the welcome info and change the colour of the circles in the dict to the background colour with ‘c’ but now it seems that these actions are taking place when ever a key is pressed, regardless of if the button was ‘c’ or not. This is what I have in the key board functions. Any idea why the screen is clearing and the circles turning white every time I press any of the allocated keys?
def brush_colour():
global pen_colour
if keyPressed and key == 'r': # pen colour key input
pen_colour = "#FF3131"
if keyPressed and key == 'g':
pen_colour = "#33C945"
if keyPressed and key == 'b':
pen_colour = "#318CFF"
if keyPressed and key == 's':
pen_colour = color(random(255), random(255), random(255))
def keyPressed():
global mic_on
if key == ' ': # detect space key
mic_on = not mic_on # invert mic state
if key == ENTER or RETURN: # clears the welcome information
background(255)
if mic_on == False and key == 'c' or 'C': # sets the circle fill to white and clears the drawing
for circ in circles:
circ['fill'] = color(255)