I have a couple of files one is rough and hastily thrown together. But it pulls together a few ideas from various people and tries to implement a VOSS algorithm to randomly generate music in a fractal pattern. It will also generate MusicXML so you can load it it into a musical score application.
Tom McGuire
NB. Script withj02.ijs for creating wave files from notes. NB. Sample fractal music "smoke puffs" is created fractal music NB. Associated with "With J: Musical Smoke Puffs", APL Quote Quad NB. Cliff Reiter, Last Modified 1998; 12-15 NB. NB. Running the script creates 'sp.wav' which may be listened to using sound recorder. NB. NB. requires 'files' require 'format/printf' ic=: 3!:4 j2l=:2&ic j2i=: 1&ic cnotes =: 'CcDeEFgGaAbB' waveheader=:3 : 0 NB. y is input data size 1 22050 22050 1 8 waveheader y : 'chan sampr Bpsec Bpsamp bpchan'=.x 'RIFF',(j2l 36+y),'WAVEfmt ',(16 0 0 0 1 0{a.),(j2i chan),(j2l sampr,Bpsec),(j2i Bpsamp,bpchan),'data',j2l y ) L2f=:{&(440*2^1r12*_9+i.12)@('CcDeEFgGaAbB'&i.) NB. right now this is set to create frequencies from NB. relative note numbers from the voss function NB. right now it is simulated with 4 dice giving a range NB. of 32 notes. Since we are using A4 as the starting NB. frequency I will try to center notes around A4 NB. N2f=: 13 : '{&(440*2^1r12*_16+i.32)@(_4&+) y' note=:3 : 0 "0 NB. x is duration, y is freq 1r8 note y : <a.{~<.127.999*>:1 o. (2p1*<.0.5+y*x)*(i.%])<.0.5+22050*x ) nmono=:;@:note wwavemono=:(waveheader@#,])@[ fwrite ] nstereo=:;@:(,@|:@,:&.>/"1)@:note NB. stero wwavestereo=:(2 22050 44100 1 8&waveheader@#,])@[ fwrite ] cile=: $@] $ ((/:@/:@] <.@:* (% #)),) f19cile=:{&(110*2^1r6*i.19)@(19&cile) sin=:1&o. cos=:2&o. four=:1: ,. cos ,. cos@+: ,. sin ,. sin@+: mx=:+/ . * CMM=:1 : '2p1&|@(+({.mx m"_ mx{:)@:four) f.' dat=:_0.62 0.33 0.93 _0.59 0.05 _0.48 ind=:0 1 4;1 1 3;2 1 4;3 0 1;4 0 0;4 0 2 spp=:dat ind}5 2 5$0 f=:spp CMM f^:(i.4) 0.3 0.4 fsp=:f19cile f^:(1000+i.200) 0.3 0.4 s=:1r6 nstereo fsp NB. create stereo notes s wwavestereo '~temp/sp.wav' NB. write sound to wave file NB. wd' winexec "C:\WINNT\system32\mplay32.exe sp.wav";' NB. Sample syntax for starting a media window to play the wave file from J NB. on mac use: NB. 2!:0 'afplay ',jpath '~temp/sp.wav' NB. create 2 notes wav data NB. $s=:1r2 1r4 nmono 110 440 NB. NB. create a wav file around the notes NB. s wwavemono '~temp/temp.wav' NB. NB. Mary had a little lamb, create note data NB. $s =: 1r3 nmono L2f mhall NB. place in wav file NB. s wwavemono '~temp/mhall.wav' NB. play the file NB. 2!:0 'afplay ',jpath '~temp/mhall.wav' NB. NB. Add spaces between the same note played contiguously NB. s =: (, |:1r6,:26$1r3) nmono ,|:0,:L2f mhall NB. create wav file NB. s wwavemono '~temp/mhall.wav' NB. play it NB. 2!:0 'afplay ',jpath '~temp/mhall.wav' noteno =: 13 : '_45 + y + 12*x-1' nmonosp =: 4 : 0 'spc mnote' =. x (, |: spc,:(#y)$mnote) nmono ,|:0,:N2f y ) xor =: ((+.)*.(-.@:*.)) NB. voss - voss algorithm for creating fractal music NB. NB. References NB. Martin Gardner. Mathematical games-white and brown music, fractal curves and one-over-f fluctuations. Scientific American, 238(4):16â32, 1978. NB. Pachet F et al Generating 1/f Noise Sequences as Constraint Satisfaction: The Voss Constraint Proceedings of the Twenty-Fourth International Joint Conference on Artificial Intelligence NB. parameters: x - number of notes to create NB. y - number of dice to use NB. voss =: 4 : 0 N =. x nDice =. y NB. dVal tracks the current dice values dVal =. 1+?nDice$6 NB. Loop set up. previous dice roll bits will be all 1s NB. and the first time into the loop will roll all dice therefore z=. 0$0 prevbits =. nDice$1 for_i. i.N do. ibits =. (nDice$2) #: i NB. ip1bits =. (nDice$2) #: i+1 dchg =. ibits xor prevbits prevbits =. ibits NB. dchg is the vector of which dice to replace. NB. Roll all dice and use dchg as mask to select the dice NB. add that to the inverse mask on dVal and we should NB. mimick the Voss method for 1/f noise dVal =. ((-.dchg)*dVal) + dchg* 1+ ?nDice$6 z =. z, +/dVal end. z ) NB. voss use: NB. notes =: 30 voss 3 NB. s =: (, |:1r6,:(#notes)$1r3) nmono ,|:0,:N2f notes NB. s wwavemono '~temp/temp8.wav' NB. 2!:0 'afplay ',jpath '~temp/temp8.wav' NB. create a musicML file with the notes NB. shfl =: 'cegab' alt =: 1 _1 1 1 _1 NB. notes2 mk_score '~temp/temp10.xml' mk_score =: 4 : 0 hdr =. freads '~temp/mxmlhdr.txt' end =. freads '~temp/mxmlend.txt' attr =. freads '~temp/mxmlattr.txt' me =. '</measure>',LF NB. first measure anotes =. 12| _3+ x aoct =. 4 + x >: 12 hdr fwrites y for_i. anotes,.aoct do. 'nt oct' =. i if. 0 = 4|i_index do. if. i_index = 0 do. m1 =. '<measure number="1">',LF,attr else. m1 =. (me,'<measure number="%d">',LF) sprintf < 1+<.i_index%4 end. m1 fappends y end. if. (nt{cnotes) e. shfl do. idx =. shfl i. nt{cnotes nt1 =. ('<note>',LF,'<pitch>',LF,'<step>','%s','</step>',LF,'<alter>%d</alter>',LF,'<octave>','%d','</octave>',LF,'</pitch>',LF,'<duration>','1','</duration>',LF,'<type>','quarter','</type>',LF,'</note>',LF) sprintf (toupper ({.nt){cnotes);(idx{alt);{.oct else. nt1 =. ('<note>',LF,'<pitch>',LF,'<step>','%s','</step>',LF,'<octave>','%d','</octave>',LF,'</pitch>',LF,'<duration>','1','</duration>',LF,'<type>','quarter','</type>',LF,'</note>',LF) sprintf (({.nt){cnotes);{.oct end. nt1 fappends y end. (me,end) fappends y ) cscale =: 'CDEFGABC' mk_scoreC =: 4 : 0 hdr =. freads '~temp/mxmlhdr.txt' end =. freads '~temp/mxmlend.txt' attr =. freads '~temp/mxmlattr.txt' me =. '</measure>',LF NB. first measure anotes =. 8| _3+ x aoct =. 3 + <. x % 8 hdr fwrites y for_i. anotes,.aoct do. 'nt oct' =. i if. 0 = 4|i_index do. if. i_index = 0 do. m1 =. '<measure number="1">',LF,attr else. m1 =. (me,'<measure number="%d">',LF) sprintf < 1+<.i_index%4 end. m1 fappends y end. nt1 =. ('<note>',LF,'<pitch>',LF,'<step>','%s','</step>',LF,'<octave>','%d','</octave>',LF,'</pitch>',LF,'<duration>','1','</duration>',LF,'<type>','quarter','</type>',LF,'</note>',LF) sprintf (nt{cscale);{.oct nt1 fappends y end. (me,end) fappends y )
<attributes> <divisions>1</divisions> <key> <fifths>0</fifths> </key> <time> <beats>4</beats> <beat-type>4</beat-type> </time> <clef> <sign>G</sign> <line>2</line> </clef> </attributes>
</part> </score-partwise>
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd"> <score-partwise version="3.0"> <part-list> <score-part id="P1"> <part-name>Music</part-name> </score-part> </part-list> <part id="P1">
> On Mar 28, 2020, at 5:27 PM, Devon McCormick <devon...@gmail.com> wrote: > > Hi - > has anyone done work with generating music or musical phrases in J? I'm > helping someone develop a music training game that starts by generating > sounds with a particular key, tempo, and phrase length. The idea is to > help students to train their ears by testing them on their ability to play > back a randomly-generated musical phrase. > > I've told my collaborator that I think the generation part should be > relatively straightforward but I am not schooled in music, so I'm not sure > how to start. > I'm guessing that the second part of comparing the user's response to the > generated phrase will be more difficult but I'd like to get any kind of > start I can. > > Does anyone have any ideas about this? > > Thanks, > > Devon > > -- > > Devon McCormick, CFA > > Quantitative Consultant > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm
---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm