how to make music21 play a particular music instrument? - python

I have trained a neural network that generates music using LSTM. But it always return music from piano only.. I've tried to use instrument.Guitar() method also. It doesn't work. I get piano music only. Why this happens? Any suggestions would be helpful..
This is my code.
def convert_to_midi(prediction_output):
offset = 0
output_notes =[]
# create note and chord objects based on the values generated by the model
for pattern in prediction_output:
notes=[]
# pattern is a chord
if ('.' in pattern) or pattern.isdigit():
notes_in_chord = pattern.split('.')
for current_note in notes_in_chord:
cn=int(current_note)
new_note = note.Note(cn)
#new_note.storedInstrument = instrument.Guitar()
notes.append(new_note)
new_chord = chord.Chord(notes)
new_chord.offset = offset
output_notes.append(instrument.Violin())
output_notes.append(new_chord)
# pattern is a note
else:
new_note = note.Note(pattern)
new_note.offset = offset
#new_note.storedInstrument = instrument.Guitar()
output_notes.append(instrument.Violin())
output_notes.append(new_note)
# increase offset each iteration so that notes do not stack
offset += 1
#midi_stream1=stream.Score()
#midi_stream1.insert(output_notes)
#midi_stream = stream.Stream(output_notes)
#midi_stream.write('midi', fp='music11.mid')
#midi_stream1.write("midi", fp="music15.mid")
midi_stream = stream.Stream(output_notes)
midi_stream.write('midi', fp='final_music2.midi')

The storedInstrument property has not been promoted to Note objects yet, but might happen in future versions of music21. For now, try simply inserting an instrument.Guitar instance into the Stream object at whatever point you need the MIDI program change.

Related

How to create an escape path for my micropython code?

I’m working on a project in micropython using an openMV camera and blob detection to determine the orientation of an object. My problem is when the check is executed, I get an error “ArilY is not defined”, because the object isn’t in the camera view yet (moving on conveyer). How can I implement a path in my code to not execute the check and just print that there is no object instead, then begin the loop again and check for the object? I have tried to implement a break with if else but can't seem to get the code right.
'''
import sensor, image, time, math
from pyb import UART
sensor.reset() # Reset and initialize the sensor.
sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240)
sensor.skip_frames(time = 2000) # Wait for settings take effect.
#sensor.set_auto_gain(False) # must be turned off for color tracking
#sensor.set_auto_whitebal(False) # must be turned off for color tracking
threshold_seed = (7,24,-8,4,-3,9)
threshold_aril = (33,76,-14,6,17,69)
threshold_raphe = (36,45,28,43,17,34)
thresholds = [threshold_seed,threshold_aril,threshold_raphe]
clock = time.clock() # Create a clock object to track the FPS.
uart = UART(3, 9600)
arilY = None
seedY = None
def func_pass():
result = "Pass"
print(result)
print("%d\n"%aril.cx(), end='')
uart.write(result)
uart.write("%d\n"%aril.cx())
#these two functions print info to serial monitor and send
def func_fail():
result = "Fail"
print(result)
print("%d\n"%aril.cx(), end='')
uart.write(result)
uart.write("%d\n"%aril.cx())
def func_orientation(seedY, arilY):
if (seedY and arilY):
check = 0
check = (seedY - arilY)
if
func_pass()
else:
func_fail()
while(True): #draw 3 blobs for each fruit
clock.tick()
img = sensor.snapshot()
for seed in img.find_blobs([threshold_seed], pixels_threshold=200, area_threshold=200, merge=True):
img.draw_rectangle(seed[0:4])
img.draw_cross(seed.cx(), seed.cy())
img.draw_string(seed.x()+2,seed.y()+2,"seed")
seedY = seed.cy()
for aril in img.find_blobs([threshold_aril],pixels_threshold=300,area_threshold=300, merge=True):
img.draw_rectangle(aril[0:4])
img.draw_cross(aril.cx(),aril.cy())
img.draw_string(aril.x()+2,aril.y()+2,"aril")
arilY = aril.cy()
for raphe in img.find_blobs([threshold_raphe],pixels_threshold=300,area_threshold=300, merge=True):
img.draw_rectangle(raphe[0:4])
img.draw_cross(raphe.cx(),raphe.cy())
img.draw_string(raphe.x()+2,raphe.y()+2,"raphe")
rapheY = raphe.cy()
func_orientation(seedY, arilY);
Something you could do is preemptively define arilY and SeedY as None before the while loop, then enclose the check in a if(arilY and seedY):
if you want to avoid using None, you could have an additional boolean that you set to true when arilY is detected, then enclose the check in a test for this boolean
But the bigger question here, is why your allocations are in the inner loop? You always redefine seedY and arilY for each iteration of the loop, which mean it will always be equal to seed.y of the last seed in the list, meaning all allocations prior to the last one were useless.
If you move the allocations outside the loop, there shouldn't be a problem.

Catia select a feature from a specific instance in an assembly

Lets say I have an assembly like this:
MainProduct:
-Product1 (Instance of Part1)
-Product2 (Instance of Part2)
-Product3 (Instance of Part2)
-Product4 (Instance of Part3)
...
Now, I want to copy/paste a feature from Product3 into another one.
But I run into problems when selecting the feature programmatically, because there are 2 instances of the part of that feature.
I can't control which feature will be selected by CATIA.ActiveDocument.Selection.Add(myExtractReference)
Catia always selects the feature from Product2 instead of the feature from Product3. So the position of the pasted feature will be wrong!
Does anybody know this problem and has a solution to it?
Edit:
The feature reference which I want to copy already exists as a variable because it was newly created (an extract of selected geometry)
I could get help else where. Still want to share my solution. It's written in Python but in VBA its almost the same.
The clue is to access CATIA.Selection.Item(1).LeafProduct in order to know where the initial selection was made.
import win32com.client
import pycatia
CATIA = win32com.client.dynamic.DumbDispatch('CATIA.Application')
c_doc = CATIA.ActiveDocument
c_sel = c_doc.Selection
c_prod = c_doc.Product
# New part where the feature should be pasted
new_prod = c_prod.Products.AddNewComponent("Part", "")
new_part_doc = new_prod.ReferenceProduct.Parent
# from user selection
sel_obj = c_sel.Item(1).Value
sel_prod_by_user = c_sel.Item(1).LeafProduct # reference to the actual product where the selection was made
doc_from_sel = sel_prod_by_user.ReferenceProduct.Parent # part doc from selection
hb = doc_from_sel.Part.HybridBodies.Add() # new hybrid body for the extract. will be deleted later on
extract = doc_from_sel.Part.HybridShapeFactory.AddNewExtract(sel_obj)
hb.AppendHybridShape(extract)
doc_from_sel.Part.Update()
# Add the extract to the selection and copy it
c_sel.Clear()
c_sel.Add(extract)
sel_prod_by_catia = c_sel.Item(1).LeafProduct # reference to the product where Catia makes the selection
c_sel_copy() # will call Selection.Copy from VBA. Buggy in Python.
# Paste the extract into the new part in a new hybrid body
c_sel.Clear()
new_hb = new_part_doc.Part.HybridBodies.Item(1)
c_sel.Add(new_hb)
c_sel.PasteSpecial("CATPrtResultWithOutLink")
new_part_doc.Part.Update()
new_extract = new_hb.HybridShapes.Item(new_hb.HybridShapes.Count)
# Redo changes in the part, where the selection was made
c_sel.Clear()
c_sel.Add(hb)
c_sel.Delete()
# Create axis systems from Position object of sel_prd_by_user and sel_prd_by_catia
prod_list = [sel_prod_by_user, sel_prod_by_catia]
axs_list = []
for prod in prod_list:
pc_pos = pycatia.in_interfaces.position.Position(prod.Position) # conversion to pycata's Position object, necessary
# in order to use Position.GetComponents
ax_comp = pc_pos.get_components()
axs = new_part_doc.Part.AxisSystems.Add()
axs.PutOrigin(ax_comp[9:12])
axs.PutXAxis(ax_comp[0:3])
axs.PutYAxis(ax_comp[3:6])
axs.PutZAxis(ax_comp[6:9])
axs_list.append(axs)
new_part_doc.Part.Update()
# Translate the extract from axis system derived from sel_prd_by_catia to sel_prd_by_user
extract_ref = new_part_doc.Part.CreateReferenceFromObject(new_extract)
tgt_ax_ref = new_part_doc.Part.CreateReferenceFromObject(axs_list[0])
ref_ax_ref = new_part_doc.Part.CreateReferenceFromObject(axs_list[1])
new_extract_translated = new_part_doc.Part.HybridShapeFactory.AddNewAxisToAxis(extract_ref, ref_ax_ref, tgt_ax_ref)
new_hb.AppendHybridShape(new_extract_translated)
new_part_doc.Part.Update()
I would suggest a differed approach. Instead of adding references you get from somewhere (by name probably) add the actual instance of part to selection while iterating trough all the products. Or use instance Names to get the correct part.
Here is a simple VBA example of iterating one lvl tree and select copy paste scenario.
If you want to copy features, you have to dive deeper on the Instance objects.
Public Sub CatMain()
Dim ActiveDoc As ProductDocument
Dim ActiveSel As Selection
If TypeOf CATIA.ActiveDocument Is ProductDocument Then 'of all the checks that people are using I think this one is most elegant and reliable
Set ActiveDoc = CATIA.ActiveDocument
Set ActiveSel = ActiveDoc.Selection
Else
Exit Sub
End If
Dim Instance As Product
For Each Instance In ActiveDoc.Product.Products 'object oriented for ideal for us in this scenario
If Instance.Products.Count = 0 Then 'beware that products without parts have also 0 items and are therefore mistaken for parts
Call ActiveSel.Add(Instance)
End If
Next
Call ActiveSel.Copy
Call ActiveSel.Clear
Dim NewDoc As ProductDocument
Set NewDoc = CATIA.Documents.Add("CATProduct")
Set ActiveSel = NewDoc.Selection
Call ActiveSel.Add(NewDoc.Product)
Call ActiveSel.Paste
Call ActiveSel.Clear
End Sub

Maya python connect to multiple input

I’m really sorry if I’m asking a question that’s been already answered but I couldn’t find an answer.
I’m writing a code that would allow me to connect a translate of several controllers into a blendWeighted node input channels. The amount of the controllers may vary depending on the selection. I’m struggling with the part where they need to connect to a single blendWeighted node input. Could someone tell me how I could connect every new controller to the next input channel of the blendWeighted node?
I’m sorry if my code is a bit childlike, I’m still learning ^^;
sel = mc.ls(sl=True, fl=True)
drvConnect = []
for i in sel:
name = i.split('_Crv')[0]
dGP = mc.createNode('transform', n='%s_Drv'%name, p=i)
drvConnect.append(dGP)
sh = mc.listRelatives(i, shapes=True)[0]
blendX = mc.createNode('blendWeighted', n='%s_X'%name)
blendY = mc.createNode('blendWeighted', n='%s_Y'%name)
blendZ = mc.createNode('blendWeighted', n='%s_Z'%name)
mc.connectAttr(dGP + '.translateX', blendX +'.input')
mc.connectAttr(dGP + '.translateY', blendY +'.input')
mc.connectAttr(dGP + '.translateZ', blendZ +'.input')
I assume you only want to create a single blendWeighted node. If that's the case, consider that the blendWeighted node's input attribute is an array attribute, so if you want to connect multiple items to it you would need to specify the target index.
For example, to connect the three translate outputs of a node to the first three inputs of the blend node you would use something like this:
mc.connectAttr('ctrl.translateX', 'blend.input[0]')
mc.connectAttr('ctrl.translateY', 'blend.input[1]')
mc.connectAttr('ctrl.translateZ', 'blend.input[2]')
(Maya will take care of creating the items in the array)
In our case you could simply keep a counter of the added items while you loop through the selection and the transform components (just a guide - not tested):
sel = mc.ls(sl=True, fl=True)
drvConnect = []
blendNode = mc.createNode('blendWeighted', n='blend_main')
for i in sel:
name = i.split('_Crv')[0]
dGP = mc.createNode('transform', n='%s_Drv'%name, p=i)
drvConnect.append(dGP)
for comp in ('X', 'Y', 'Z'):
mc.connectAttr(
'{}.translate{}'.format(dGP, comp),
'{}.input[{}]'.format(blendNode, blendIndex))
blendIndex += 1

Inverse Dynamics Controller Drake

I currently have an array of desired position vs. time of an object in my plant. I am using an inverse dynamics controller in order to drive the object to this desired position but I'm experiencing some difficulties. Here is how I am doing this:
I created the controller system
ID_cont = InverseDynamicsController(robot=controller_plant, kp=np.array([0.5]), ki=np.array([0.3]), kd=np.array([0.4]), has_reference_acceleration=False)
ID_controller = builder.AddSystem(ID_cont)
I got the controller input and output ports
control_estimated_state_input_port = ID_controller.get_input_port(0)
control_desired_state_input_port = ID_controller.get_input_port(1)
control_output_port = ID_controller.get_output_port(0)
I added a constant state source (likely wrong to do) and a state interpolator
constant_state_source = ConstantVectorSource(np.array([0.0]))
builder.AddSystem(constant_state_source)
position_to_state = StateInterpolatorWithDiscreteDerivative(controller_plant.num_positions(),
controller_plant.time_step())
builder.AddSystem(position_to_state)
I wired the controller to the plant
builder.Connect(constant_state_source.get_output_port(), position_to_state.get_input_port())
builder.Connect(position_to_state.get_output_port(), control_desired_state_input_port)
builder.Connect(plant.get_state_output_port(model_instance_1), control_estimated_state_input_port)
builder.Connect(control_output_port, plant.get_actuation_input_port(model_instance_1))
Next, I am trying to create a while loop that advances the simulation and changes the 'constant vector source' so I can feed in my position vs. time values but I'm unsure if the reason this isn't working out is because this is the complete wrong approach or if this is the right approach but I just have a few things wrong
diagram_context = diagram.CreateDefaultContext()
sim_time_temp = diagram_context.get_time()
time_step = 0.1
while sim_time_temp < duration:
ID_controller_context = diagram.GetMutableSubsystemContext(ID_controller, diagram_context)
simulator.AdvanceTo(sim_time_temp)
sim_time_temp = sim_time_temp + time_step
I added a constant state source (likely wrong to do) and a state interpolator
As you suspected, this is not the best way to go if you already have a desired sequence of positions and times that you want the system to track. Instead, you should use a TrajectorySource. Since you have a set of positions samples, positions (num_times x num_positions array), that you'd like the system to hit at specified times (num_times x 1 array), PiecewisePolynomial.CubicShapePreserving is a reasonable choice for building the trajectory.
desired_position_trajectory = PiecewisePolynomial.CubicShapePreserving(times, positions)
desired_state_source = TrajectorySource(desired_position_trajectory,
output_derivative_order=1)
builder.AddSystem(desired_state_source)
The output_derivative_order=1 argument makes desired_state_source output a [position, velocity] vector rather than just a position vector. You can connect desired_state_source directly to the controller, without an interpolator.
With this setup, you can advance the simulation all the way to duration without the need for a while loop.

How can I produce real-time audio output from music made with Music21?

How can I produce real-time audio output from music made with Music21. Failing that, how can i produce ANY audio output from music made with Music21 via open-source software? Thanks for the help.
As you've seen, music21 isn't designed to be a music playback system, but it IS designed to be embedded within other playback systems or to call them from within the system. We're not planning on putting too much work into playback systems (because of the hardware support, our being a tiny research lab, the work still needing to be done on musical analysis, etc.), but your solution is so elegant that it is now included in all versions of music21 (post v1.1) as the music21.midi.realtime module. Here's an example that takes music21's ability to dynamically allocate midi channels with different pitch-bend objects in order to simulate microtonal playback (a major problem for most midi playback):
# Set up a detuned piano
# (where each key has a random
# but consistent detuning from 30 cents flat to sharp)
# and play a Bach Chorale on it in real time.
from music21 import *
import random
keyDetune = []
for i in range(0, 127):
keyDetune.append(random.randint(-30, 30))
b = corpus.parse('bach/bwv66.6')
for n in b.flat.notes:
n.microtone = keyDetune[n.pitch.midi]
sp = midi.realtime.StreamPlayer(b)
sp.play()
The StreamPlayer's .play() function can also take busyFunction and busyArgs and busyWaitMilliseconds arguments which specify a function to call with arguments at most every busyWaitMilliseconds (could be more if your system is slower). There is also an endFunction and endArgs that will be called at the end, in case you want to set up some sort of threaded playback. -- Myke Cuthbert (Music21 creator)
So here's what I found out. Here's a python script that works on Windows XP. It needs pygame in addition to music21.
# genPlayM21Score.py Generates and Plays 2 Music21 Scores "on the fly".
#
# see way below for source notes
from music21 import *
# we create the music21 Bottom Part, and do this explicitly, one object at a time.
n1 = note.Note('e4')
n1.duration.type = 'whole'
n2 = note.Note('d4')
n2.duration.type = 'whole'
m1 = stream.Measure()
m2 = stream.Measure()
m1.append(n1)
m2.append(n2)
partLower = stream.Part()
partLower.append(m1)
partLower.append(m2)
# For the music21 Upper Part, we automate the note creation procedure
data1 = [('g4', 'quarter'), ('a4', 'quarter'), ('b4', 'quarter'), ('c#5', 'quarter')]
data2 = [('d5', 'whole')]
data = [data1, data2]
partUpper = stream.Part()
def makeUpperPart(data):
for mData in data:
m = stream.Measure()
for pitchName, durType in mData:
n = note.Note(pitchName)
n.duration.type = durType
m.append(n)
partUpper.append(m)
makeUpperPart(data)
# Now, we can add both Part objects into a music21 Score object.
sCadence = stream.Score()
sCadence.insert(0, partUpper)
sCadence.insert(0, partLower)
# Now, let's play the MIDI of the sCadence Score [from memory, ie no file write necessary] using pygame
import cStringIO
# for music21 <= v.1.2:
if hasattr(sCadence, 'midiFile'):
sCadence_mf = sCadence.midiFile
else: # for >= v.1.3:
sCadence_mf = midi.translate.streamToMidiFile(sCadence)
sCadence_mStr = sCadence_mf.writestr()
sCadence_mStrFile = cStringIO.StringIO(sCadence_mStr)
import pygame
freq = 44100 # audio CD quality
bitsize = -16 # unsigned 16 bit
channels = 2 # 1 is mono, 2 is stereo
buffer = 1024 # number of samples
pygame.mixer.init(freq, bitsize, channels, buffer)
# optional volume 0 to 1.0
pygame.mixer.music.set_volume(0.8)
def play_music(music_file):
"""
stream music with mixer.music module in blocking manner
this will stream the sound from disk while playing
"""
clock = pygame.time.Clock()
try:
pygame.mixer.music.load(music_file)
print "Music file %s loaded!" % music_file
except pygame.error:
print "File %s not found! (%s)" % (music_file, pygame.get_error())
return
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
# check if playback has finished
clock.tick(30)
# play the midi file we just saved
play_music(sCadence_mStrFile)
#============================
# now let's make a new music21 Score by reversing the upperPart notes
data1.reverse()
data2 = [('d5', 'whole')]
data = [data1, data2]
partUpper = stream.Part()
makeUpperPart(data)
sCadence2 = stream.Score()
sCadence2.insert(0, partUpper)
sCadence2.insert(0, partLower)
# now let's play the new Score
sCadence2_mf = sCadence2.midiFile
sCadence2_mStr = sCadence2_mf.writestr()
sCadence2_mStrFile = cStringIO.StringIO(sCadence2_mStr)
play_music(sCadence2_mStrFile)
## SOURCE NOTES
## There are 3 sources for this mashup:
# 1. Source for the Music21 Score Creation http://web.mit.edu/music21/doc/html/quickStart.html#creating-notes-measures-parts-and-scores
# 2. Source for the Music21 MidiFile Class Behaviour http://mit.edu/music21/doc/html/moduleMidiBase.html?highlight=midifile#music21.midi.base.MidiFile
# 3. Source for the pygame player: http://www.daniweb.com/software-development/python/code/216979/embed-and-play-midi-music-in-your-code-python

Categories

Resources