From e10005d5e6d772ebd9b1b1831a440088d01ef52e Mon Sep 17 00:00:00 2001 From: olpc Date: Fri, 24 Sep 2010 21:56:12 +0000 Subject: Initial commit --- diff --git a/FileMix.csd b/FileMix.csd new file mode 100755 index 0000000..0103a3d --- /dev/null +++ b/FileMix.csd @@ -0,0 +1,148 @@ +; FileMix (2010) for realtime Csound5 - by Arthur B. Hunkins +; requires MIDI device with 1-16(17) knobs/sliders; 1-4 files +; 1-4 controls per file (amp, band-pass peak freq, peak gain, speed/freq) +; Quantity of knobs/sliders needed = number of files * number of parameters. +; An additional controller is optional Master volume. +; Files may be mono or stereo; can have different sample rates, may be a variety of +; uncompressed types including WAV and AIFF; also Ogg/Vorbis (with Sugar 0.86/ +; Blueberry or later) but not MP3. +; They must be named soundin.1 (through soundin.4), and in the same folder as this file. + + + + + +-odac -+rtaudio=alsa -+rtmidi=alsa -M hw:1,0 -m0d --expression-opt -b128 -B2048 -+raw_controller_mode=1 + + + + +sr = 44100 +; change sample rate to 48000 if 44100 gives no audio. (Necessary for Intel Classmate PC.) +ksmps = 100 +nchnls = 2 + +gichan chnexport "chan", 1 +gictrl1 chnexport "ctrl1", 1 +gictrl2 chnexport "ctrl2", 1 +gimast chnexport "mast", 1 +gifile chnexport "files", 1 +gistrt chnexport "random", 1 +gidel chnexport "delay", 1 +gifade chnexport "fade", 1 +giloop chnexport "loop", 1 +giparm chnexport "parms", 1 +gkasc chnexport "ascii", 1 + + massign 0, 0 + seed 0 +ga1 init 0 +ga2 init 0 +gktrig init 0 +gkasc init 0 + +gitemp ftgen 2, 0, 512, -5, 200, 512, sr / 13.2 + + instr 1, 2, 3, 4 + + if p1 > 1 igoto skip +gimast = ((gichan == 0) && (gifile == 4) && (giparm == 4)? -1: gimast) + if gifile == 1 igoto skip + event_i "i", 2, 0, 3600 + if gifile == 2 igoto skip + event_i "i", 3, 0, 3600 + if gifile == 3 igoto skip + event_i "i", 4, 0, 3600 +skip: + if (gidel == 0) || (gktrig == 1) goto skip2 +kstat,kchan,kdata1,kdata2 midiin +; line below allows default STOP key on the Korg nanoKontrol to terminate delay + if (kstat == 176) && (kdata1 == 44) && (kdata2 == 127) goto skip3 + if (kstat != 144) && (gkasc == 0) goto skip2 +skip3: +gktrig = 1 +skip2: +kamp ctrl7 (gichan == 0? p1: gichan), (gichan == 0? 7: gictrl1 + (p1 - 1)), 0, 1 +kamp2 table kamp * 512, 1 +kamp2 port kamp2, .01 +ichans filenchnls p1 +ilen filelen p1 +ipeak filepeak p1 +imult = 32760 / gifile / ipeak +kamp2 = kamp2 * imult +irand unirand ilen * .75 +istart = (gistrt == 0? irand: 0) +; physically set these controllers (speed/freq) to .5 after start +iplace4 = p1 + (gifile * 3) - 1 +ictrl4 = (iplace4 > 7? gictrl2 + iplace4 - 8: gictrl1 + iplace4) +kbase ctrl7 (gichan == 0? iplace4 + 1: gichan), (gichan == 0? 7: ictrl4), .9, 1.1 +kbase port kbase, .01 +kbase = (giparm == 4? kbase: 1) + if (gidel == 1) && (gktrig == 0) goto fin +iloop = (giloop == 1? 0: 1) + if ichans == 2 goto skip4 +a1 diskin2 p1, kbase, istart, iloop + if giparm > 1 goto skip5 + goto skip6 +skip4: +a1, a2 diskin2 p1, kbase, istart, iloop + if giparm > 1 goto skip5 + goto skip6 +skip5: +; physically set these controllers (band-pass peak freq) to .5 after start +ictrl2 = p1 + gifile - 1 +kfreq ctrl7 (gichan == 0? ictrl2 + 1: gichan), (gichan == 0? 7: gictrl1 + ictrl2), 0, 512 +kfreq table kfreq, 2 +kfreq port kfreq, .01 +iplace3 = p1 + (gifile * 2) - 1 +ictrl3 = (iplace3 > 7? gictrl2 + iplace3 - 8: gictrl1 + iplace3) +kres ctrl7 (gichan == 0? iplace3 + 1: gichan), (gichan == 0? 7: ictrl3), .25, .7 +kres port kres, .01 +kres = (giparm > 2? kres: .25) +a3,a4,a5 svfilter a1, kfreq, kres + if ichans == 1 goto skip6 +a6,a7,a8 svfilter a2, kfreq, kres +skip6: +ifade = gifade + if gifade > 0 goto skip7 +ifade tab_i gifade + 3, 3 +skip7: +kamp3 linseg 0, ifade, 1, (iloop == 0? ilen - (ifade * 2) - istart: .01), 1, (iloop == 0? ifade: .01), (iloop == 0? 0: 1) +kamp2 = kamp2 * kamp3 +ga1 = ga1 + ((giparm == 1? a1: a5) * kamp2) +ga2 = ga2 + ((giparm == 1? (ichans == 1? a1: a2): (ichans == 1? a5: a8)) * kamp2) +fin: + endin + + instr 5 + + if gifile == 1 goto skip + if (gichan > 0) && (gimast > -1) goto skip2 + if ((gifile < 4) || (giparm < 4)) && (gichan == 0) && (gimast > -1) goto skip2 +skip: +kamp2 = 1 + goto skip3 +skip2: +kamp ctrl7 (gichan == 0? gimast: gichan), (gichan == 0? 7: gimast), 0, 1 +kamp2 table kamp * 512, 1 +kamp2 port kamp2, .01 +skip3: + outs ga1 * kamp2, ga2 * kamp2 +ga1 = 0 +ga2 = 0 + + endin + + + + + +f 1 0 512 16 0 512 .8 1 +f 3 0 4 -2 .01 .1 .5 .0001 +i 1 0 3600 +i 5 0 3600 + +e + + + diff --git a/FileMix4.csd b/FileMix4.csd new file mode 100755 index 0000000..ee76b26 --- /dev/null +++ b/FileMix4.csd @@ -0,0 +1,107 @@ +; FileMix4 (2010) for realtime Csound5 - by Arthur B. Hunkins +; requires MIDI device with 4-16(17) knobs/sliders; 4 files only +; 1-4 controls/parameters per file (amp, band-pass peak freq, peak gain, speed/freq) +; 1 parameter requires 4(5) knobs/sliders; 2 parameters, 8(9); 3 parameters, 12(13); +; 4 parameters, 16(17). The additional controller is optional Master volume. +; Files must be stereo; can have different sample rates, may be a variety of +; uncompressed types including WAV and AIFF; also Ogg/Vorbis (with Sugar 0.86/ +; Blueberry or later) but not MP3. +; They must be named soundin.1 to soundin.4, and in the same folder as this file. + + + + +-odac -+rtaudio=alsa -+rtmidi=alsa -M hw:1,0 -m0d --expression-opt -b128 -B2048 -+raw_controller_mode=1 + + + + +sr = 44100 +; change sample rate to 48000 if 44100 gives no audio. (Necessary for Intel Classmate PC.) +ksmps = 100 +nchnls = 2 + +gichan chnexport "chan", 1 +gictrl1 chnexport "ctrl1", 1 +gictrl2 chnexport "ctrl2", 1 +gimast chnexport "mast", 1 +giparm chnexport "parms", 1 + + massign 0, 0 + seed 0 +ga1 init 0 +ga2 init 0 + +gitemp ftgen 2, 0, 512, -5, 200, 512, sr / 13.2 + + instr 1, 2, 3, 4 + + if p1 > 1 igoto skip +gimast = ((gichan == 0) && (giparm == 4)? -1: gimast) +skip: +kamp ctrl7 (gichan == 0? p1: gichan), (gichan == 0? 7: gictrl1 + (p1 - 1)), 0, 1 +kamp2 table kamp * 512, 1 +kamp2 port kamp2, .01 +ilen filelen p1 +ipeak filepeak p1 +imult = 8190 / ipeak +kamp2 = kamp2 * imult +irand unirand ilen * .75 +; physically set these controllers to .5 after start +kbase ctrl7 (gichan == 0? p1 + 12: gichan), (gichan == 0? 7: gictrl2 + (p1 + 3)), .9, 1.1 +kbase port kbase, .01 +kbase = (giparm == 4? kbase: 1) +a1, a2 diskin2 p1, kbase, irand, 1 + if giparm > 1 goto skip2 +ga1 = ga1 + (a1 * kamp2) +ga2 = ga2 + (a2 * kamp2) + goto end +skip2: +; physically set these controllers to .5 after start +kfreq ctrl7 (gichan == 0? p1 + 4: gichan), (gichan == 0? 7: gictrl1 + (p1 + 3)), 0, 512 +kfreq table kfreq, 2 +kfreq port kfreq, .01 +kres ctrl7 (gichan == 0? p1 + 8: gichan), (gichan == 0? 7: gictrl2 + (p1 - 1)), .25, .7 +kres port kres, .01 +kres = (giparm > 2? kres: .25) +a3,a4,a5 svfilter a1, kfreq, kres +a6,a7,a8 svfilter a2, kfreq, kres +ga1 = ga1 + (a5 * kamp2) +ga2 = ga2 + (a8 * kamp2) +end: + endin + + instr 5 + + if (gichan > 0) && (gimast > -1) goto skip + if (giparm < 4) && (gichan == 0) && (gimast > -1) goto skip +kamp2 = 1 + goto skip2 +skip: +kamp ctrl7 (gichan == 0? gimast: gichan), (gichan == 0? 7: gimast), 0, 1 +kamp2 table kamp * 512, 1 +kamp2 port kamp2, .01 + +skip2: + outs ga1 * kamp2, ga2 * kamp2 +ga1 = 0 +ga2 = 0 +end: + endin + + + + + +f 1 0 512 16 0 512 .8 1 +i 1 0 3600 +i 2 0 3600 +i 3 0 3600 +i 4 0 3600 +i 5 0 3600 + +e + + + + diff --git a/FileMix4ASC.csd b/FileMix4ASC.csd new file mode 100755 index 0000000..5460b39 --- /dev/null +++ b/FileMix4ASC.csd @@ -0,0 +1,323 @@ +; FileMix4ASC (2010) for realtime Csound5 - by Arthur B. Hunkins +; ASCII keyboard control (no MIDI); 4 files only +; 1-4 controls/parameters per file (amp, band-pass peak freq, peak gain, speed/freq) +; Files must be stereo; can have different sample rates, may be a variety of +; uncompressed types including WAV and AIFF; also Ogg/Vorbis (with Sugar 0.86/ +; Blueberry or later) but not MP3. +; They must be named soundin.1 through soundin.4, and in the same folder as this file. + + + + +-odac -+rtaudio=alsa -m0d --expression-opt -b128 -B2048 + + + + +sr = 44100 +; change sample rate to 48000 if 44100 gives no audio. (Necessary for Intel Classmate PC.) +ksmps = 100 +nchnls = 2 + +giparm chnexport "parms", 1 +gkasc chnexport "ascii", 1 + + seed 0 +gkasc init 0 +gktime init .1 +gkamp2 init 0 +gkamp3 init 0 +gkamp4 init 0 +gkamp5 init 0 +gkpfrq2 init 256 +gkpfrq3 init 256 +gkpfrq4 init 256 +gkpfrq5 init 256 +gkpgan2 init .25 +gkpgan3 init .25 +gkpgan4 init .25 +gkpgan5 init .25 +gksped2 init 1 +gksped3 init 1 +gksped4 init 1 +gksped5 init 1 + +gitemp ftgen 2, 0, 512, -5, 200, 512, sr / 13.2 + + instr 1 + + if (gkasc != 96) goto skip +gktime = .1 + kgoto end +skip: + if ((gkasc < 48) || (gkasc > 57)) goto skip2 +gktime = gkasc - 48 +gktime = (gkasc == 48? gktime + 10: gktime) + kgoto end +skip2: + if (gkasc != 103) && (gkasc != 104) goto skip3 +gkamp2 = 0 +gkamp3 = 0 +gkamp4 = 0 +gkamp5 = 0 + kgoto end +skip3: + if (gkasc != 118) && (gkasc != 98) && (gkasc != 110) goto skip4 +gktime = .1 +gkamp2 = 0 +gkamp3 = 0 +gkamp4 = 0 +gkamp5 = 0 +gkpfrq2 = 256 +gkpfrq3 = 256 +gkpfrq4 = 256 +gkpfrq5 = 256 +gkpgan2 = .25 +gkpgan3 = .25 +gkpgan4 = .25 +gkpgan5 = .25 +gksped2 = 1 +gksped3 = 1 +gksped4 = 1 +gksped5 = 1 + kgoto end +skip4: + if (gkasc != 97) goto skip5 +gkamp2 = gkamp2 + .5 +gkamp2 = (gkamp2 > 1? 1: gkamp2) + kgoto end +skip5: + if (gkasc != 115) goto skip6 +gkamp3 = gkamp3 + .5 +gkamp3 = (gkamp3 > 1? 1: gkamp3) + kgoto end +skip6: + if (gkasc != 100) goto skip7 +gkamp4 = gkamp4 + .5 +gkamp4 = (gkamp4 > 1? 1: gkamp4) + kgoto end +skip7: + if (gkasc != 102) goto skip8 +gkamp5 = gkamp5 + .5 +gkamp5 = (gkamp5 > 1? 1: gkamp5) + kgoto end +skip8: + if (gkasc != 65) goto skip9 +gkamp2 = gkamp2 - .5 +gkamp2 = (gkamp2 < 0? 0: gkamp2) + kgoto end +skip9: + if (gkasc != 83) goto skip10 +gkamp3 = gkamp3 - .5 +gkamp3 = (gkamp3 < 0? 0: gkamp3) + kgoto end +skip10: + if (gkasc != 68) goto skip11 +gkamp4 = gkamp4 - .5 +gkamp4 = (gkamp4 < 0? 0: gkamp4) + kgoto end +skip11: + if (gkasc != 70) goto skip12 +gkamp5 = gkamp5 - .5 +gkamp5 = (gkamp5 < 0? 0: gkamp5) + kgoto end +skip12: + if giparm == 1 goto end + if (gkasc != 113) goto skip13 +gkpfrq2 = gkpfrq2 + 128 +gkpfrq2 = (gkpfrq2 > 512? 512: gkpfrq2) + kgoto end +skip13: + if (gkasc != 119) goto skip14 +gkpfrq3 = gkpfrq3 + 128 +gkpfrq3 = (gkpfrq3 > 512? 512: gkpfrq3) + kgoto end +skip14: + if (gkasc != 101) goto skip15 +gkpfrq4 = gkpfrq4 + 128 +gkpfrq4 = (gkpfrq4 > 512? 512: gkpfrq4) + kgoto end +skip15: + if (gkasc != 114) goto skip16 +gkpfrq5 = gkpfrq5 + 128 +gkpfrq5 = (gkpfrq5 > 512? 512: gkpfrq5) + kgoto end +skip16: + if (gkasc != 81) goto skip17 +gkpfrq2 = gkpfrq2 - 128 +gkpfrq2 = (gkpfrq2 < 0? 0: gkpfrq2) + kgoto end +skip17: + if (gkasc != 87) goto skip18 +gkpfrq3 = gkpfrq3 - 128 +gkpfrq3 = (gkpfrq3 < 0? 0: gkpfrq3) + kgoto end +skip18: + if (gkasc != 69) goto skip19 +gkpfrq4 = gkpfrq4 - 128 +gkpfrq4 = (gkpfrq4 < 0? 0: gkpfrq4) + kgoto end +skip19: + if (gkasc != 82) goto skip20 +gkpfrq5 = gkpfrq5 - 128 +gkpfrq5 = (gkpfrq5 < 0? 0: gkpfrq5) + kgoto end +skip20: + if giparm == 2 goto end + if (gkasc != 106) goto skip21 +gkpgan2 = gkpgan2 + .225 +gkpgan2 = (gkpgan2 > .7? .7: gkpgan2) + kgoto end +skip21: + if (gkasc != 107) goto skip22 +gkpgan3 = gkpgan3 + .225 +gkpgan3 = (gkpgan3 > .7? .7: gkpgan3) + kgoto end +skip22: + if (gkasc != 108) goto skip23 +gkpgan4 = gkpgan4 + .225 +gkpgan4 = (gkpgan4 > .7? .7: gkpgan4) + kgoto end +skip23: + if (gkasc != 59) goto skip24 +gkpgan5 = gkpgan5 + .225 +gkpgan5 = (gkpgan5 > .7? .7: gkpgan5) + kgoto end +skip24: + if (gkasc != 74) goto skip25 +gkpgan2 = gkpgan2 - .225 +gkpgan2 = (gkpgan2 < .25? .25: gkpgan2) + kgoto end +skip25: + if (gkasc != 75) goto skip26 +gkpgan3 = gkpgan3 - .225 +gkpgan3 = (gkpgan3 < .25? .25: gkpgan3) + kgoto end +skip26: + if (gkasc != 76) goto skip27 +gkpgan4 = gkpgan4 - .225 +gkpgan4 = (gkpgan4 < .25? .25: gkpgan4) + kgoto end +skip27: + if (gkasc != 58) goto skip28 +gkpgan5 = gkpgan5 - .225 +gkpgan5 = (gkpgan5 < .25? .25: gkpgan5) + kgoto end +skip28: + if giparm == 3 goto end + if (gkasc != 117) goto skip29 +gksped2 = gksped2 + .05 +gksped2 = (gksped2 > 1.1? 1.1: gksped2) + goto end +skip29: + if (gkasc != 105) goto skip30 +gksped3 = gksped3 + .05 +gksped3 = (gksped3 > 1.1? 1.1: gksped3) + goto end +skip30: + if (gkasc != 111) goto skip31 +gksped4 = gksped4 + .05 +gksped4 = (gksped4 > 1.1? 1.1: gksped4) + goto end +skip31: + if (gkasc != 112) goto skip32 +gksped5 = gksped5 + .05 +gksped5 = (gksped5 > 1.1? 1.1: gksped5) + goto end +skip32: + if (gkasc != 85) goto skip33 +gksped2 = gksped2 - .05 +gksped2 = (gksped2 < .9? .9: gksped2) + goto end +skip33: + if (gkasc != 73) goto skip34 +gksped3 = gksped3 - .05 +gksped3 = (gksped3 < .9? .9: gksped3) + goto end +skip34: + if (gkasc != 79) goto skip35 +gksped4 = gksped4 - .05 +gksped4 = (gksped4 < .9? .9: gksped4) + goto end +skip35: + if (gkasc != 80) goto end +gksped5 = gksped5 - .05 +gksped5 = (gksped5 < .9? .9: gksped5) +end: + +gkasc = 0 + + endin + + instr 2, 3, 4, 5 + + if p1 > 2 goto skip +k1 = gkamp2 +k2 = gkpfrq2 +k3 = gkpgan2 +k4 = gksped2 + goto skip2 +skip: + if p1 > 3 goto skip3 +k1 = gkamp3 +k2 = gkpfrq3 +k3 = gkpgan3 +k4 = gksped3 + goto skip2 +skip3: + if p1 > 4 goto skip4 +k1 = gkamp4 +k2 = gkpfrq4 +k3 = gkpgan4 +k4 = gksped4 + goto skip2 +skip4: +k1 = gkamp5 +k2 = gkpfrq5 +k3 = gkpgan5 +k4 = gksped5 +skip2: +kamp lineto k1, gktime +kamp2 table kamp * 512, 1 +kamp2 port kamp2, .01 +ifile = p1 - 1 +ichans filenchnls ifile +ilen filelen ifile +ipeak filepeak ifile +imult = 8190 / ipeak +kamp2 = kamp2 * imult +irand unirand ilen * .75 +kbase lineto k4, gktime +kbase = (giparm == 4? kbase: 1) +a1, a2 diskin2 ifile, kbase, irand, 1 + if giparm > 1 goto skip5 + outs a1 * kamp2, a2 * kamp2 + goto end +skip5: +kfreq lineto k2, gktime +kfreq table kfreq, 2 +kfreq port kfreq, .01 +kres lineto k3, gktime +kres = (giparm > 2? kres: .25) +a3,a4,a5 svfilter a1, kfreq, kres +a6,a7,a8 svfilter a2, kfreq, kres + outs a5 * kamp2, a8 * kamp2 + +end: + endin + + + + + +f 1 0 512 16 0 512 .8 1 +i 1 0 3600 +i 2 0 3600 +i 3 0 3600 +i 4 0 3600 +i 5 0 3600 + +e + + + diff --git a/FileMixASC.csd b/FileMixASC.csd new file mode 100755 index 0000000..3578936 --- /dev/null +++ b/FileMixASC.csd @@ -0,0 +1,360 @@ +; FileMixASC (2010) for realtime Csound5 - by Arthur B. Hunkins +; ASCII keyboard control (no MIDI); 1-4 files +; 1-4 controls/parameters per file (amp, band-pass peak freq, peak gain, speed/freq) +; Files may be mono or stereo; can have different sample rates, may be a variety of +; uncompressed types including WAV and AIFF; also Ogg/Vorbis (with Sugar 0.86/ +; Blueberry or later) but not MP3. +; They must be named soundin.1 (through soundin.4), and in the same folder as this file. + + + + +-odac -+rtaudio=alsa -m0d --expression-opt -b128 -B2048 + + + + +sr = 44100 +; change sample rate to 48000 if 44100 gives no audio. (Necessary for Intel Classmate PC.) +ksmps = 100 +nchnls = 2 + +gifile chnexport "files", 1 +gistrt chnexport "random", 1 +gidel chnexport "delay", 1 +gifade chnexport "fade", 1 +giloop chnexport "loop", 1 +giparm chnexport "parms", 1 +gkasc chnexport "ascii", 1 + + seed 0 +gkasc init 0 +gktime init .1 +gkamp2 init 0 +gkamp3 init 0 +gkamp4 init 0 +gkamp5 init 0 +gkpfrq2 init 256 +gkpfrq3 init 256 +gkpfrq4 init 256 +gkpfrq5 init 256 +gkpgan2 init .25 +gkpgan3 init .25 +gkpgan4 init .25 +gkpgan5 init .25 +gksped2 init 1 +gksped3 init 1 +gksped4 init 1 +gksped5 init 1 +gktrig init 0 + +gitemp ftgen 2, 0, 512, -5, 200, 512, sr / 13.2 + + instr 1 + + if (gidel == 0) || ((gkasc != 116) && (gkasc != 121)) goto skip +gktrig = 1 + kgoto end +skip: + if (gkasc != 96) goto skip1 +gktime = .1 + kgoto end +skip1: + if ((gkasc < 48) || (gkasc > 57)) goto skip2 +gktime = gkasc - 48 +gktime = (gkasc == 48? gktime + 10: gktime) + kgoto end +skip2: + if (gkasc != 103) && (gkasc != 104) goto skip3 +gkamp2 = 0 +gkamp3 = 0 +gkamp4 = 0 +gkamp5 = 0 + kgoto end +skip3: + if (gkasc != 118) && (gkasc != 98) && (gkasc != 110) goto skip4 +gktime = .1 +gkamp2 = 0 +gkamp3 = 0 +gkamp4 = 0 +gkamp5 = 0 +gkpfrq2 = 256 +gkpfrq3 = 256 +gkpfrq4 = 256 +gkpfrq5 = 256 +gkpgan2 = .25 +gkpgan3 = .25 +gkpgan4 = .25 +gkpgan5 = .25 +gksped2 = 1 +gksped3 = 1 +gksped4 = 1 +gksped5 = 1 + kgoto end +skip4: + if (gkasc != 97) goto skip5 +gkamp2 = gkamp2 + .5 +gkamp2 = (gkamp2 > 1? 1: gkamp2) + kgoto end +skip5: + if (gkasc != 115) goto skip6 +gkamp3 = gkamp3 + .5 +gkamp3 = (gkamp3 > 1? 1: gkamp3) + kgoto end +skip6: + if (gkasc != 100) goto skip7 +gkamp4 = gkamp4 + .5 +gkamp4 = (gkamp4 > 1? 1: gkamp4) + kgoto end +skip7: + if (gkasc != 102) goto skip8 +gkamp5 = gkamp5 + .5 +gkamp5 = (gkamp5 > 1? 1: gkamp5) + kgoto end +skip8: + if (gkasc != 65) goto skip9 +gkamp2 = gkamp2 - .5 +gkamp2 = (gkamp2 < 0? 0: gkamp2) + kgoto end +skip9: + if (gkasc != 83) goto skip10 +gkamp3 = gkamp3 - .5 +gkamp3 = (gkamp3 < 0? 0: gkamp3) + kgoto end +skip10: + if (gkasc != 68) goto skip11 +gkamp4 = gkamp4 - .5 +gkamp4 = (gkamp4 < 0? 0: gkamp4) + kgoto end +skip11: + if (gkasc != 70) goto skip12 +gkamp5 = gkamp5 - .5 +gkamp5 = (gkamp5 < 0? 0: gkamp5) + kgoto end +skip12: + if giparm == 1 goto end + if (gkasc != 113) goto skip13 +gkpfrq2 = gkpfrq2 + 128 +gkpfrq2 = (gkpfrq2 > 512? 512: gkpfrq2) + kgoto end +skip13: + if (gkasc != 119) goto skip14 +gkpfrq3 = gkpfrq3 + 128 +gkpfrq3 = (gkpfrq3 > 512? 512: gkpfrq3) + kgoto end +skip14: + if (gkasc != 101) goto skip15 +gkpfrq4 = gkpfrq4 + 128 +gkpfrq4 = (gkpfrq4 > 512? 512: gkpfrq4) + kgoto end +skip15: + if (gkasc != 114) goto skip16 +gkpfrq5 = gkpfrq5 + 128 +gkpfrq5 = (gkpfrq5 > 512? 512: gkpfrq5) + kgoto end +skip16: + if (gkasc != 81) goto skip17 +gkpfrq2 = gkpfrq2 - 128 +gkpfrq2 = (gkpfrq2 < 0? 0: gkpfrq2) + kgoto end +skip17: + if (gkasc != 87) goto skip18 +gkpfrq3 = gkpfrq3 - 128 +gkpfrq3 = (gkpfrq3 < 0? 0: gkpfrq3) + kgoto end +skip18: + if (gkasc != 69) goto skip19 +gkpfrq4 = gkpfrq4 - 128 +gkpfrq4 = (gkpfrq4 < 0? 0: gkpfrq4) + kgoto end +skip19: + if (gkasc != 82) goto skip20 +gkpfrq5 = gkpfrq5 - 128 +gkpfrq5 = (gkpfrq5 < 0? 0: gkpfrq5) + kgoto end +skip20: + if giparm == 2 goto end + if (gkasc != 106) goto skip21 +gkpgan2 = gkpgan2 + .225 +gkpgan2 = (gkpgan2 > .7? .7: gkpgan2) + kgoto end +skip21: + if (gkasc != 107) goto skip22 +gkpgan3 = gkpgan3 + .225 +gkpgan3 = (gkpgan3 > .7? .7: gkpgan3) + kgoto end +skip22: + if (gkasc != 108) goto skip23 +gkpgan4 = gkpgan4 + .225 +gkpgan4 = (gkpgan4 > .7? .7: gkpgan4) + kgoto end +skip23: + if (gkasc != 59) goto skip24 +gkpgan5 = gkpgan5 + .225 +gkpgan5 = (gkpgan5 > .7? .7: gkpgan5) + kgoto end +skip24: + if (gkasc != 74) goto skip25 +gkpgan2 = gkpgan2 - .225 +gkpgan2 = (gkpgan2 < .25? .25: gkpgan2) + kgoto end +skip25: + if (gkasc != 75) goto skip26 +gkpgan3 = gkpgan3 - .225 +gkpgan3 = (gkpgan3 < .25? .25: gkpgan3) + kgoto end +skip26: + if (gkasc != 76) goto skip27 +gkpgan4 = gkpgan4 - .225 +gkpgan4 = (gkpgan4 < .25? .25: gkpgan4) + kgoto end +skip27: + if (gkasc != 58) goto skip28 +gkpgan5 = gkpgan5 - .225 +gkpgan5 = (gkpgan5 < .25? .25: gkpgan5) + kgoto end +skip28: + if giparm == 3 goto end + if (gkasc != 117) goto skip29 +gksped2 = gksped2 + .05 +gksped2 = (gksped2 > 1.1? 1.1: gksped2) + goto end +skip29: + if (gkasc != 105) goto skip30 +gksped3 = gksped3 + .05 +gksped3 = (gksped3 > 1.1? 1.1: gksped3) + goto end +skip30: + if (gkasc != 111) goto skip31 +gksped4 = gksped4 + .05 +gksped4 = (gksped4 > 1.1? 1.1: gksped4) + goto end +skip31: + if (gkasc != 112) goto skip32 +gksped5 = gksped5 + .05 +gksped5 = (gksped5 > 1.1? 1.1: gksped5) + goto end +skip32: + if (gkasc != 85) goto skip33 +gksped2 = gksped2 - .05 +gksped2 = (gksped2 < .9? .9: gksped2) + goto end +skip33: + if (gkasc != 73) goto skip34 +gksped3 = gksped3 - .05 +gksped3 = (gksped3 < .9? .9: gksped3) + goto end +skip34: + if (gkasc != 79) goto skip35 +gksped4 = gksped4 - .05 +gksped4 = (gksped4 < .9? .9: gksped4) + goto end +skip35: + if (gkasc != 80) goto end +gksped5 = gksped5 - .05 +gksped5 = (gksped5 < .9? .9: gksped5) +end: + +gkasc = 0 + + endin + + instr 2, 3, 4, 5 + + if p1 > 2 igoto skip + if gifile == 1 igoto skip + event_i "i", 3, 0, 3600 + if gifile == 2 igoto skip + event_i "i", 4, 0, 3600 + if gifile == 3 igoto skip + event_i "i", 5, 0, 3600 +skip: + if p1 > 2 goto skip1 +k1 = gkamp2 +k2 = gkpfrq2 +k3 = gkpgan2 +k4 = gksped2 + goto skip2 +skip1: + if p1 > 3 goto skip3 +k1 = gkamp3 +k2 = gkpfrq3 +k3 = gkpgan3 +k4 = gksped3 + goto skip2 +skip3: + if p1 > 4 goto skip4 +k1 = gkamp4 +k2 = gkpfrq4 +k3 = gkpgan4 +k4 = gksped4 + goto skip2 +skip4: +k1 = gkamp5 +k2 = gkpfrq5 +k3 = gkpgan5 +k4 = gksped5 +skip2: +kamp lineto k1, gktime +kamp2 table kamp * 512, 1 +kamp2 port kamp2, .01 +ifile = p1 - 1 +ichans filenchnls ifile +ilen filelen ifile +ipeak filepeak ifile +imult = 8190 / ipeak +kamp2 = kamp2 * imult +irand unirand ilen * .75 + +istart = (gistrt == 0? irand: 0) + +kbase lineto k4, gktime +kbase = (giparm == 4? kbase: 1) + if (gidel == 1) && (gktrig == 0) goto end + +iloop = (giloop == 1? 0: 1) + + if ichans == 2 goto skip5 +a1 diskin2 ifile, kbase, istart, iloop + if giparm == 1 goto skip7 + goto skip6 +skip5: +a1, a2 diskin2 ifile, kbase, istart, iloop + if giparm == 1 goto skip7 +skip6: +kfreq lineto k2, gktime +kfreq table kfreq, 2 +kfreq port kfreq, .01 +kres lineto k3, gktime +kres = (giparm > 2? kres: .25) +a3,a4,a5 svfilter a1, kfreq, kres + if ichans == 1 goto skip7 +a6,a7,a8 svfilter a2, kfreq, kres +skip7: +ifade = gifade + if gifade > 0 goto skip8 +ifade tab_i gifade + 3, 3 +skip8: +kamp3 linseg (gidel == 0? 1: 0), ifade, 1, (iloop == 0? ilen - (ifade * 2) - istart: .01), 1, (iloop == 0? ifade: .01), (iloop == 0? 0: 1) +kamp2 = kamp2 * kamp3 + if giparm > 1 goto skip9 + outs a1 * kamp2, (ichans == 1? a1: a2) * kamp2 + goto end +skip9: + outs a5 * kamp2, (ichans == 1? a5: a8) * kamp2 +end: + endin + + + + + +f 1 0 512 16 0 512 .8 1 +f 3 0 4 -2 .01 .1 .5 .0001 +i 1 0 3600 +i 2 0 3600 + +e + + + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..96c9d90 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,14 @@ +MANIFEST +filemix.py +soundin.1 +soundin.2 +soundin.3 +soundin.4 +setup.py +csndsugui.py +FileMixASC.csd +FileMix4ASC.csd +FileMix.csd +FileMix4.csd +activity/activity.info +activity/activity-filemix.svg diff --git a/activity/activity-filemix.svg b/activity/activity-filemix.svg new file mode 100755 index 0000000..4dea519 --- /dev/null +++ b/activity/activity-filemix.svg @@ -0,0 +1,36 @@ + + + + +]> + + + + + + + + + diff --git a/activity/activity.info b/activity/activity.info new file mode 100755 index 0000000..8bdd416 --- /dev/null +++ b/activity/activity.info @@ -0,0 +1,14 @@ +[Activity] + +name = FileMix + +bundle_id = org.laptop.FileMix +icon = activity-filemix + +activity_version = 1 + +host_version = 1 + +show_launcher = yes +exec = sugar-activity filemix.FileMix +license = CC-by-SA 3.0 diff --git a/csndsugui.py b/csndsugui.py new file mode 100755 index 0000000..c8a404d --- /dev/null +++ b/csndsugui.py @@ -0,0 +1,813 @@ +# sugar-aware GUI classes +# with boxes, sliders, spinbuttons, buttons, etc +# +# (c) Victor Lazzarini, 2006-08 +# +# This library is free software; you can redistribute it +# and/or modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# csndsugui is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with csndsugui; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +# 02111-1307 USA +# +# As a special exception, if other files instantiate templates or +# use macros or inline functions from this file, this file does not +# by itself cause the resulting executable or library to be covered +# by the GNU Lesser General Public License. This exception does not +# however invalidate any other reasons why the library or executable +# file might be covered by the GNU Lesser General Public License. +# +# +# version 0.1.3 06/08/08 + +import pygtk +pygtk.require('2.0') +from sugar.activity import activity +import gtk, gobject +import sys +import csnd +import math +import locale +import os +import sugar.logger +import time + +class BasicGUI: + """Basic GUI with boxes, sliders, spins, buttons etc + using pygtk/sugar, from which GUI classes + can be derived for Csound use.""" + + def scale_font(self, widget): + font = widget.get_pango_context().get_font_description() + +# The FONT DISPLAY in this activity can be resized (smaller or larger) +# by changing the value of "resize" below. "Resize" can be positive +# or negative, and is not limited to integers. A value of 1 equals a +# point in font size. + resize = 0 + + font_size = font.get_size() + (resize * 1024) + width = gtk.gdk.screen_width() + mult = width * .00076 + if os.path.exists("/etc/olpc-release") or os.path.exists("/etc/power/olpc-pm"): + mult = width * .00082 + elif os.path.exists("/etc/fedora-release"): + release = open("/etc/fedora-release").read() + if release.find("SoaS release 1 ") != -1: + mult = width * .00132 + elif release.find("SoaS release 2 ") != -1: + mult = width * .00085 + elif release.find("Fedora release ") != -1: + mult = width * .00119 + font.set_size(int(font_size * mult)) + widget.modify_font(font) + + def set_channel(self,name, val): + """basic bus channel setting method, + should be overriden for full-functionality.""" + self.logger.debug("channel:%s, value:%.1f" % (name,val)) + + def set_filechannel(self,chan,name): + """basic filename channel setting method + should be overriden for full-functionality.""" + self.logger.debug("channel:%s, filename:%s" % (chan,name)) + + def set_message(self, mess): + """basic message setting method + should be overriden for full-functionality.""" + self.logger.debug(mess) + + def get_slider_value(self,name): + """returns the slider value + name: slider name (which should also be the attached bus channel name""" + for i in self.sliders: + if i[1] == name: + return i[2] + return 0 + + def get_button_value(self,name): + """returns the button value (0 or 1) + name: button name (which should also be the attached bus channel name)""" + for i in self.buttons: + if i[1] == name: + return i[2] + return 0 + + def get_slider(self,name): + """returns the slider widget instance + name: slider name""" + for i in self.sliders: + if i[1] == name: + return i[0] + return 0 + + def get_button(self,name): + """returns the button widget instance + name: button name""" + for i in self.sliders: + if i[1] == name: + return i[0] + return 0 + + def set_focus(self): + """ called whenever the focus changes """ + self.logger.debug(self.focus) + + def focus_out(self, widget, event): + if(self.focus): + self.focus = False + self.set_focus() + + def focus_in(self, widget, event): + if(not self.focus): + self.focus = True + self.set_focus() + + def focus_back(self, widget, event): + self.window.disconnect(self.fback) + self.focus_connect() + + def buttcallback(self, widget, data=None): + for i in self.buttons: + if i[0] == widget: + if i[2]: + i[2] = 0 + i[0].modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0x8000,0x8000,0x8000, 2)) + i[0].modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0x8000,0x8000,0x8000, 2)) + else: + i[2] = 1 + i[0].modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0xFFFF,0,0, 1)) + i[0].modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0,0, 2)) + self.set_channel(i[1], i[2]) + + def button_setvalue(self, widget, value): + if not value: + widget.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0x0FFF,0,0x00FF, 2)) + widget.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0,0xFFFF, 2)) + else: + widget.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0xFFFF,0,0, 1)) + widget.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0,0, 2)) + + def mbuttcallback(self, widget, data=None): + for i in self.mbuttons: + if i[0] == widget: + self.set_message(i[2]) + + def slidcallback(self,adj,widget): + for i in self.sliders: + if i[0] == widget: + i[2] = adj.value + if i[4]: + self.set_channel(i[1],i[2]) + i[3].set_text("%f" % i[2]) + pass + else: + value = i[5]*pow(i[6]/i[5], i[2]/i[6]) + self.set_channel(i[1], value) + i[3].set_text("%.3f" % value) + pass + + def spincallback(self,adj,widget): + for i in self.spins: + if i[0] == widget: + i[2] = adj.value + self.set_channel(i[1],i[2]) + + def filecallback(self,widget): + name = self.curfile[0].get_filename() + self.set_filechannel(self.curfile[2], name) + for i in self.buttons: + if i[0] == self.curfile[1]: + i[2] = name + self.filenames.update({self.curfile[2] : name}) + self.curfile[0].destroy() + self.fback = self.window.connect('focus_out_event', self.focus_back) + + def destroy_chooser(self,widget): + self.curfile[0].destroy() + + def fbuttcallback(self, widget, data=None): + self.focus_disconnect() + for i in self.buttons: + if i[0] == widget: + chooser = gtk.FileSelection(i[1]) + self.curfile = (chooser, i[0], i[1]) + chooser.set_filename(self.data_path) + chooser.ok_button.connect("clicked", self.filecallback) + chooser.cancel_button.connect("clicked", self.destroy_chooser) + chooser.show() + + def cbbutton(self,box,callback,title=""): + """Creates a callbackbutton + box: parent box + callback: click callback + title: if given, the button name + returns the widget instance""" + self.cbbutts = self.cbbutts + 1 + butt = gtk.Button(title) + self.scale_font(butt.child) + box.pack_start(butt, False, False, 2) + self.cbbuttons.append([butt,title,0]) + butt.connect("clicked", callback) + butt.show() + return butt + + def button(self,box, title="",label=""): + """Creates a button (on/off) + box: parent box + title: if given, the button name, + which will also be the bus channel + name. Otherwise a default name is + given, BN, where N is button number + in order of creation. + label: if given, an alternative button name, + which will be displayed instead of title + returns the widget instance""" + self.butts = self.butts + 1 + if title == "": + title = "B%d" % self.butts + if label == "": name = title + else: name = label + butt = gtk.Button(" %s " % name) + self.scale_font(butt.child) + butt.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0x8000,0x8000,0x8000, 2)) + box.pack_start(butt, False, False, 1) + self.buttons.append([butt,title,0]) + butt.connect("clicked", self.buttcallback) + butt.show() + return butt + + def mbutton(self,box,mess,title=""): + """Creates a mbutton (for sending a message) + box: parent box + title: if given, the button name, otherwise a default name is + given, BN, where N is button number + in order of creation. + mess: message to be sent when button is clicked + returns the widget instance""" + self.mbutts = self.mbutts + 1 + if title == "": + title = "B%d" % self.mbutts + butt = gtk.Button(title) + butt.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0x0FFF,0,0x00FF, 1)) + butt.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0xFFFF,0x0000, 2)) + box.pack_start(butt, False, False, 5) + self.mbuttons.append([butt,title,mess]) + butt.connect("clicked", self.mbuttcallback) + butt.show() + return butt + + def box(self,vert=True, parent=None, padding=3): + """creates a box + vert: True, creates a vertical box; horiz. + otherwise + parent: parent box, None if this is a toplevel box + padding: box padding + returns the widget instance""" + if vert: + box = gtk.VBox() + else: + box = gtk.HBox() + if parent: + parent.pack_start(box, False, False, padding) + else: + self.outbox.pack_start(box, False, False, padding) + self.boxes.append(box) + box.show() + return box + + def filechooser(self,box,title,label=""): + """Creates a filechooser button + title: button name, also file bus channel name + box: parent box + label: if given, alternative name, for display purposes only + otherwise button will display its title.""" + if label == "": name = title + else: name = label + butt = gtk.Button(name) + box.pack_start(butt, False, False, 5) + self.buttons.append([butt,title,"0"]) + butt.connect("clicked", self.fbuttcallback) + self.set_filechannel(title,"0") + self.filenames.update({title:"0"}) + butt.show() + return butt + + def slider(self,init, start, end, x, y, box, title="",vert=True,linear=True,dwid=100,label=""): + """Creates a slider + init: initial value + start, end: start and end of slider range + x, y: x and y sizes of slider + box: parent box + title: if given, the slider name, + which will also be the bus channel + name. Otherwise a default name is + given, SN, where N is slider number + in order of creation. + vert: vertical slider (True), else horiz. + linear: linear response (True), else exponential (zero or negative + ranges are not allowed) + dwid: display width in pixels + label: if given, the alternative slider name, for display only + returns the widget instance""" + self.slids = self.slids + 1 + if title == "": + title = "S%d" % self.slids + a = end - start + if vert: + step = a/y + adj = gtk.Adjustment(init,start,end,step,step,0) + slider = gtk.VScale(adj) + slider.set_inverted(True) + else: + step = a/x + adj = gtk.Adjustment(init,start,end,step,step,0) + slider = gtk.HScale(adj) + slider.set_draw_value(False) + if step < 1.0: + slider.set_digits(3) + elif step < 10: + slider.set_digits(2) + elif step < 100: + slider.set_digits(1) + else: + slider.set_digits(0) + entry = gtk.Entry(5) + if vert: entry.set_size_request(dwid,50) + else: entry.set_size_request(dwid,50) + entry.set_editable(False) + if not linear: + if (init <= 0) or (start <= 0) or (end <= 0): + linear = True + if not linear: + pos = end*math.log(1,end/start) + slider.set_range(pos, end) + pos = end*math.log(init/start,end/start) + slider.set_value(pos) + if label == "": name = title + else: name = label + entry.set_text("%f" % init) + label = gtk.Label(name) + slider.set_size_request(x,y) + box.pack_start(slider, False, False, 5) + box.pack_start(entry, False, False, 2) + box.pack_start(label, False, False, 2) + self.sliders.append([slider,title,init,entry,linear,start,end]) + adj.connect("value_changed", self.slidcallback, slider) + slider.show() + entry.show() + label.show() + self.set_channel(title, init) + return slider + + def numdisplay(self,box,title="",init=0.0,label=""): + self.ndispwids = self.ndispwids + 1 + entry = gtk.Entry() + if label == "": name = title + else: name = label + entry.set_text("%f" % init) + label = gtk.Label(name) + box.pack_start(entry, False, False, 2) + box.pack_start(label, False, False, 2) + self.ndisps.append([entry,title,init]) + entry.show() + label.show() + self.set_channel(title,init) + return entry + + def setnumdisp(self,title,val): + for i in self.ndisps: + if i[1] == title: + i[2] = val + i[0].set_text("%f" % val) + self.set_channel(title, val) + + def spin(self,init, start, end, step, page, box, accel=0,title="",label=""): + """Creates a spin button + init: initial value + start, end: start and end of slider range + step, page: small and large step sizes + box: parent box + accel: acceleration or 'climb rate' (0.0-1.0) + title: if given, the spin button name, + which will also be the bus channel + name. Otherwise a default name is + given, SPN, where N is spin number + in order of creation. + label: if given, the alternative name for the widget, for display only. + returns the widget instance""" + self.spinbs = self.spinbs + 1 + if title == "": + title = "SP%d" % self.spinbs + adj = gtk.Adjustment(init,start,end,step,page,0) + spin = gtk.SpinButton(adj,accel) + self.scale_font(spin) + spin.set_alignment(.5) + if label == "": name = title + else: name = label + label = gtk.Label(name) + self.scale_font(label) + box.pack_start(spin, False, False, 3) + box.pack_start(label, False, False, 0) + self.spins.append([spin,title,init]) + adj.connect("value_changed", self.spincallback, spin) + spin.show() + label.show() + self.set_channel(title, init) + return spin + + def text(self, name, box=None,colour=(0,0,0)): + """Creates a static text label + name: text label + box: parent box, None if text is to be placed toplevel + colour: RGB values in a tuple (R,G,B) + returns the widget instance""" + label = gtk.Label(name) + self.scale_font(label) + label.set_use_markup(True) + label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0)) + if box: + box.pack_start(label, False, False, 3) + else: + self.outbox.pack_start(label, False, False, 3) + label.show() + return label + + def framebox(self, name, vert=True, parent=None, colour=(0,0,0), padding=5): + """Creates a frame box + name: text label + vert: vertical (True) box, else horiz. + parent: parent box, if None, this is a toplevel box + colour: RGB values in a tuple (R,G,B) + padding: padding space + returns the box widget instance""" + frame = gtk.Frame(name) + self.scale_font(frame.get_label_widget()) + frame.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0)) + frame.get_label_widget().modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0)) + frame.get_label_widget().set_use_markup(True) + if parent: + parent.pack_start(frame, False, False, padding) + else: + self.outbox.pack_start(frame, False, False, padding) + if vert: + box = gtk.VBox() + else: + box = gtk.HBox() + frame.add(box) + frame.show() + box.show() + return box + + def vsliderbank(self,items,init, start, end, x, y, box): + """Creates a vertical slider bank + items: number of sliders + init: initial value + start, end: start and end of slider range + x, y: x and y sizes of slider + box: parent box""" + slid = self.slids + for i in range(slid, slid+items): + cbox = self.box(parent=box) + self.slider(init,start,end,x,y,cbox) + + def hsliderbank(self,items,init, start, end, x, y, box): + """Creates a horizontal slider bank + items: number of sliders + init: initial value + start, end: start and end of slider range + x, y: x and y sizes of slider + box: parent box""" + slid = self.slids + for i in range(slid, slid+items): + cbox = self.box(False,box) + self.slider(init,start,end,x,y,cbox,"",False) + + def buttonbank(self,items, box): + """Creates a button bank + items: number of sliders + box: parent box.""" + start = self.butts + for i in range(start, start+items): + self.button(box) + + def delete_event(self, widget, event, data=None): + return False + + def get_toolbox(self): + """Returns the Activity toolbox""" + return self.toolbox + + def channels_reinit(self): + """ resets channel to current widget values""" + for j in self.buttons: + if(j[1] != "pause"): + if(j[1] != "play"): + if(j[1] != "reset"): + self.set_channel(j[1],j[2]) + for j in self.sliders: + if j[4]: + self.set_channel(j[1],j[2]) + pass + else: + value = j[5]*pow(j[6]/j[5], j[2]/j[6]) + self.set_channel(j[1], value) + for j in self.spins: + self.set_channel(j[1],j[2]) + + def widgets_reset(self): + """ resets widget to channel values""" + for j in self.buttons: + self.button_setvalue(j[0], j[2]) + self.set_channel(j[1],j[2]) + for j in self.sliders: + j[0].set_value(j[2]) + j[0].emit("value_changed") + for j in self.spins: + j[0].set_value(j[2]) + j[0].emit("value_changed") + + def channels_save(self): + """ Saves a list with channel names and current values. + Returns a list of tuples (channel_name, channel_value)""" + chan_list = [] + for i in self.channel_widgets: + for j in i: + if(j[1] != "pause"): + if(j[1] != "play"): + if(j[1] != "reset"): + chan_list.append((j[1],j[2])); + return chan_list + + def channels_load(self, chan_list): + """ Loads a list with channel names and values into the + current channel list """ + for i in self.channnel_widgets: + for j in i: + cnt = 0 + while(j[1] == chan_list[cnt][0]): + j[1] = chann_list[cnt][0] + j[2] = chan_list[cnt][1] + cnt = cnt+1 + self.widgets_reset() + + def set_channel_metadata(self): + """ Saves channel data as metadata. Can be called in + write_file() to save channel/widget data """ + mdata = self.channels_save() + for i in mdata: + self.window.metadata['channel-'+i[0]] = str(i[1]) + + def get_channel_metadata(self): + """ Retrieves channel data from metadata. Can be called after + widgets have been created to retrieve channel data and + reset widgets """ + for i in self.channel_widgets: + for j in i: + mdata = self.window.metadata.get('channel-'+j[1],'0') + if mdata is None: continue + else: + try: j[2] = float(mdata) + except: j[2] = mdata + self.widgets_reset() + + + def nofocus(self): + pass + + def focus_connect(self): + if not self.connected: + self.focus = True + self.in_id = self.window.connect('focus_in_event', self.focus_in) + self.out_id = self.window.connect('focus_out_event', self.focus_out) + self.connected = True + + def focus_disconnect(self): + if self.connected: + self.window.disconnect(self.in_id) + self.window.disconnect(self.out_id) + self.connected = False + + def __init__(self,act,colour=(-1,-1,-1),vert=True,toolbox=None): + """Constructor + act: activity object + colour: bg colour RGB tuple (R,G, B) + vert: True for vertical topmost arrangement, horiz. otherwise + toolbox: activity toolbox object, if None (default) a + standard toolbox will be supplied""" + self.sliders = [] + self.slids = 0 + self.spins = [] + self.spinbs = 0 + self.buttons = [] + self.butts = 0 + self.cbbuttons = [] + self.cbbutts = 0 + self.mbuttons = [] + self.mbutts = 0 + self.boxes = [] + self.ndisps = [] + self.ndispwids = 0 + self.connected = False + self.channel_widgets = [self.sliders, self.spins, self.buttons] + self.filenames = dict() + self.window = act + if toolbox == None: + self.toolbox = activity.ActivityToolbox(self.window) + else: self.toolbox = toolbox + self.window.set_toolbox(self.toolbox) + self.toolbox.show() + if colour[0] >= 0: + self.window.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0)) + if vert: self.outbox = gtk.VBox() + else: self.outbox = gtk.HBox() + self.window.set_canvas(self.outbox) + self.data_path = os.path.join(act.get_activity_root(),"data/") + self.outbox.show() + self.logger = sugar.logger.logging.getLogger('csndsugui') + + +class CsoundGUI(BasicGUI): + """A class inheriting from BasicGUI containing a Csound instance and a performance + thread instance.""" + + def set_channel(self,name,val): + """overrides the base method. + sets the bus channel value, called by the widget callbacks + channel names 'play', 'pause' and + 'reset' are reserved for these respective uses""" + if not self.ready: + if name == "play": + self.play() + elif name == "pause": + self.pause() + elif name == "reset": + self.reset() + self.csound.SetChannel(name,val) + else: + BasicGUI.set_channel(self,name,val) + + def set_filechannel(self,chan,name): + """overrides the base method, setting the channel string""" + if not self.ready: + self.csound.SetChannel(chan,name) + else: + BasicGUI.set_filechannel(self,chan,name) + + def set_message(self, mess): + """overrides the base method, sends a score message""" + self.perf.InputMessage(mess) + + def set_focus(self): + """overrides the base class method, resetting/recompiling Csound""" + if self.focus: + self.compile() + self.channels_reinit() + if self.replay and not self.on: + self.play() + self.logger.debug("focus_off and playing") + else: + self.replay = self.on + self.logger.debug("focus_out and stopping") + self.reset() + return 1 + + def play(self): + """Starts a performance. """ + if not self.on: + if self.paused: return + self.on = True + self.perf.Play() + else: + self.on = False + self.perf.Pause() + + def pause(self): + """Pauses a performance. """ + if self.on: + self.on = False + self.paused = True + self.perf.Pause() + elif self.paused: + self.on = True + self.paused = False + self.perf.Play() + + def csd(self, name): + """Sets the source CSD and compiles it. + name: CSD filename + returns zero if successful""" + path = activity.get_bundle_path() + if self.ready: + res = self.csound.Compile("%s/%s" % (path,name)) + if not res: + self.ready = False + self.focus_connect() + self.path = path + self.name = name + return res + + def recompile(self): + """Recompiles the set CSD. + returns zero if successful""" + if not self.ready and self.name != "0": + self.perf.Stop() + self.perf.Join() + self.on = False + self.paused = False + self.perf = csnd.CsoundPerformanceThread(self.csound) + if self.arglist != None: + res = self.csound.Compile(self.arglist.argc(),self.arglist.argv()) + else: + res = self.csound.Compile("%s/%s" % (self.path,self.name)) + if(res): self.ready = True + return res + + def compile(self,name=None,args=[]): + """Compiles Csound code. + name: CSD filename if given + args: list of arguments (as strings) + returns 0 if successful , non-zero if not.""" + if self.ready: + if args != []: + self.arglist = csnd.CsoundArgVList() + self.path = activity.get_bundle_path() + if name != None: self.name = name + elif self.name == "0": return -1 + if self.arglist != None: + if name != None: + self.arglist.Append("csound") + self.arglist.Append("%s/%s" % (self.path,self.name)) + for i in args: + self.arglist.Append(i) + res = self.csound.Compile(self.arglist.argc(),self.arglist.argv()) + else: res = self.csound.Compile("%s/%s" % (self.path,self.name)) + if not res: + self.ready = False + self.focus_connect() + else: + self.arglist = None + return res + + def reset(self): + """Resets Csound, ready for a new CSD""" + if not self.ready: + self.perf.Stop() + self.perf.Join() + self.on = False + self.paused = False + self.perf = csnd.CsoundPerformanceThread(self.csound) + self.ready = True + + def close(self, event): + self.reset() + sys.exit(0) + + def tcallback(self,cbdata): + if self.stopcb: return False + if self.on and self.sync: + self.tcb(cbdata) + return True + + def set_timer(self,time,cb,cbdata,sync=True): + """Sets a timer callback, called at time intervals. + Sync=True makes it start/stop with Csound performance""" + if(self.stopcb == True): + self.sync = sync + self.tcb = cb + self.stopcb = False + gobject.timeout_add(time,self.tcallback,cbdata) + + def stop_timer(self): + """Stops the timer""" + self.stopcb = True + + def score_time(self): + """Returns the current score time""" + return self.csound.GetScoreTime() + + def __init__(self,act,colour=(-1,-1,-1),vert=True): + """constructor + act: activity object + colour: bg colour RGB tuple (R,G, B) + vert: True for vertical topmost arrangement, horiz. otherwise.""" + locale.setlocale(locale.LC_NUMERIC, 'C') + self.csound = csnd.Csound() + self.perf = csnd.CsoundPerformanceThread(self.csound) + BasicGUI.__init__(self,act,colour,vert) + self.ready = True + self.on = False + self.paused = False + self.name = "0" + self.arglist = None + self.replay = False + self.stopcb = True + diff --git a/filemix.py b/filemix.py new file mode 100755 index 0000000..a4e683f --- /dev/null +++ b/filemix.py @@ -0,0 +1,334 @@ +# FILEMIX - Audio File Player/Mixer/Processor Utilities for Children (2010) +# Art Hunkins (www.arthunkins.com) +# +# FileMix is licensed under the Creative Commons Attribution-Share +# Alike 3.0 Unported License. To view a copy of this license, visit +# http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to +# Creative Commons, 171 Second Street, Suite 300, San Francisco, +# California, 94105, USA. +# +# It is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# version 1 +# +# Notes: +# +# The four versions that comprise the FileMix utility series are: +# FileMix4, FileMix4ASC, FileMix and FileMixASC. FileMix4 and +# FileMix4ASC require 4 stereo soundfiles, while FileMix and +# FileMixASC can handle 1-4 mono or stereo soundfiles. The files +# can be of any sample rate and a variety of uncompressed formats +# including WAV and AIFF; also Ogg/Vorbis, but not MP3. The Ogg/ +# Vorbis format is only possible when the Sugar version is later +# than 0.84, which excludes the XO-1 and SoaS Strawberry. The XO-1.5 +# works fine with Ogg. +# +# Actually, the ogg vorbis format (which is written by the Record +# activity) can be used by SoaS Strawberry (0.84) if libsndfile is +# updated. This can be done while connected to the internet by +# issuing the following commands in the Terminal: +# su +# yum update libsndfile +# +# Students are encouraged to create their own soundfiles, especially +# to make their own nature soundscapes. (This is the primary intent +# behind these utilities. The four short "nature" files included here +# are abbreviated versions of those from the author's DUSK AT ST. +# FRANCIS SPRINGS [www.arthunkins.com].) +# +# The natural vehicle for soundfile creation is the Record activity. +# This activity is fairly simple and straightforward; the only problem +# is that certain versions of it work poorly or not at all. The +# following versions of Record seem to work well or fairly well: v59 +# (well) with the XO-1; v67 or v85/86 (fairly well) with XO-1.5; v64 +# (well) with SoaS Strawberry; v66 (fairly well) with SoaS Blueberry, +# Mirabelle and later. (This is as of 9/2010.) +# +# Soundfiles must be moved into the folder where this file resides, +# and be renamed soundin.1 through soundin.4. +# +# Important: The controller must be attached AFTER boot, and BEFORE +# the version is selected. It is assumed that the controller is a USB +# device. The inexpensive Korg nanoKontrol is one appropriate +# controller choice; it can nicely handle either 8- or 9-slider +# renditions (but not those requiring more than 9 sliders). Choose +# Scene 4 on the Korg, and Channel "0" in the performance window. +# +# It is also important, with all versions, to wait 3 to 5 seconds +# after pressing START, before moving any controls or pressing more +# buttons/keys. The utilities will not respond to these actions until +# after this time. +# +# To facilitate performance of FileMix on the Korg nanoKontrol, its STOP +# button has been programmed as a Delay Start option (buttons on the +# device, by default, are not set to MIDI notes). It is conceivable +# that this feature could interfere with MIDI controller selection +# (Continuous Controller numbers). Solutions to this possible issue +# are discussed in the FileMix.txt document on the author's website. +# Other relevent items of interest may also be found in this document. +# +# On a few systems, e.g. the Intel Classmate PC, the specified sr +# (sample rate) of 44100 may not produce audio. Substitute a rate of +# 48000 toward the beginning of each .csd file, using a text editor. +# +# If you get audio glitching, open Sugar's Control Panel, and turn off +# Extreme power management (under Power) or Wireless radio (under +# Network). Stereo headphones (an inexpensive set will work fine) or +# external amplifier/speaker system are highly recommended. +# +# The font display of this activity can be resized in csndsugui.py, +# using any text editor. Further instructions are found toward the +# beginning of csndsugui.py. + +import csndsugui +from sugar.activity import activity +import gtk +import os + +class FileMix(activity.Activity): + + def __init__(self, handle): + + activity.Activity.__init__(self, handle) + + red = (0xDDDD, 0, 0) + brown = (0x6600, 0, 0) + green = (0, 0x5500, 0) + + win = csndsugui.CsoundGUI(self) + width = gtk.gdk.screen_width() + height = gtk.gdk.screen_height() + if os.path.exists("/etc/olpc-release") or os.path.exists("/sys/power/olpc-pm"): + tall = 1 + adjust = 78 + else: + adjust = 57 + screen = win.box() + screen.set_size_request(width, height - adjust) + scrolled = gtk.ScrolledWindow() + scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + screen.pack_start(scrolled) + all = gtk.VBox() + all.show() + scrolled.add_with_viewport(all) + scrolled.show() + + win.text("FILEMIX - Audio File Player/Mixer/Processor \ +Utilities for Children (2010)\n\ +\t\t\t\t Art Hunkins (www.arthunkins.com)", all) + + win.text("\ +FileMix4 and FileMix4ASC play 4 stereo files; any format except mp3 \ +(and no ogg on XO-1 and Sugar 0.84/Strawberry).\n\ +FileMix and FileMixASC play 1-4 mono and/or stereo files; \ +any format as above.\n\ + Files must be named soundin.1 to soundin.4 \ +and be located in this folder.\n\ + The default files are abbreviated versions of those from the author's \ +DUSK AT ST. FRANCIS SPRINGS.\n\ + You are urged to make your own, perhaps with the Record activity \ +(in ogg format) - especially nature soundscapes.", all, brown) + win.text("FileMix4 and FileMix require MIDI controllers; \ +the # of knobs/sliders depends on the # of files/parameters you control. \n\ + All knobs/sliders are adjoining, and like parameters are grouped: \ +volume, then peak freq, peak gain, lastly speed/freq.\n\ + A Master volume control (all files are affected) is optional, and may \ +be separated from the other controls.", all, green) + win.text("FileMix4ASC and FileMIXASC don't use MIDI; \ +control is via 1 or more ASCII keyboards.\n\ + ASCII keys used: (glide time in seconds) 1-0(10); ` (to left of 1) \ += 0(.1) seconds (takes effect with next keypress) - \n\ + (volume) A,S,D,F - (band-pass freq peak) Q,W,E,R - (peak gain) J,K,L,; - \ +(speed/freq) U,I,O,P\n\ + Unshifted=up by .5 (1 max); shifted=down by .5 (0 min); \ +top alphabetic rows go negative as well as positive.\n\ + G,H = all files off; V,B,N = all files off and reset to \ +defaults. Note: SPACE bar and ENTER only START and STOP.", all, brown) + win.text("FileMix(ASC) offers delayed start - for single play, sync/\ +'play from head' options. Hit ASCII key/MIDI note to begin play. ", all, +green) + + win.text("\ +\t1 - FileMix4 Simple; MIDI controller with 4-16(17) knobs/sliders \ +(#17 = optional Master volume)\n\ +\t2 - FileMix4ASC Simple; 1 or more ASCII keyboards\n\ +\t3 - FileMix \ +Advanced; MIDI controller with 1-16(17) knobs/sliders (#17 = optional \ +Master volume)\n\ +\t4 - FileMixASC Advanced; 1 or more ASCII keyboards\n\ +MIDI: plug in controller after boot & before selecting. \ +Zero controls before start; reset peak freq & speed/freqs \ +to .5 after.\nALL VERSIONS: IMPORTANT! \ +Key presses & controller motion prior to 3-5 seconds after hitting START \ +are ignored. ", all, brown) + nbox = win.box(False, all) + win.text("", nbox) + but1 = win.cbbutton(nbox, self.version1, " 1 FileMix4 ") + but1.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0)) + but1.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0)) + but2 = win.cbbutton(nbox, self.version2, "2 FileMix4ASC") + but2.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0)) + but2.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0)) + but3 = win.cbbutton(nbox, self.version3, " 3 FileMix ") + but3.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0)) + but3.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0)) + but4 = win.cbbutton(nbox, self.version4, " 4 FileMixASC ") + but4.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0)) + but4.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0)) + win.text(" MIDI DEVICE REQUIRED for 1 & 3", nbox, brown) + bbox = win.box(False, all) + self.bb = bbox + self.w = win + self.r = red + self.g = green + self.br = brown + self.ver = 0 + + def onKeyPress(self, widget, event): + if self.p: + if self.ver > 1: + self.w.set_channel("ascii", event.keyval) + + def playcsd(self, widget): + if self.p == False: + self.p = True + self.w.play() + self.but.child.set_label("STOP !") + self.but.child.set_use_markup(True) + self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0xFFFF, 0, 0)) + self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF, 0, 0)) + if self.ver > 1: + self.connect("key-press-event", self.onKeyPress) + else: + self.p = False + self.w.recompile() + self.w.channels_reinit() + self.but.child.set_label("START !") + self.but.child.set_use_markup(True) + self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0)) + self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0)) + + def version1(self, widget): + if self.ver != 0: + self.box1.destroy() + self.box2.destroy() + self.ver = 1 + self.box1 = self.w.box(True, self.bb) + self.w.text("", self.box1) + self.box2 = self.w.box(True, self.bb) + self.f = self.w.framebox(" 1 - FileMix4 ", False, self.box2, self.r) + self.b1 = self.w.box(True, self.f) + self.b2 = self.w.box(True, self.f) + self.b3 = self.w.box(True, self.f) + self.b4 = self.w.box(True, self.f) + self.w.reset() + self.w.csd("FileMix4.csd") + self.w.spin(0, 0, 16, 1, 1, self.b1, 0, "chan", "Channel # [0=CC7,\n \ +channels 1-16]") + self.w.spin(20, 0, 120, 1, 1, self.b1, 0, "ctrl1", "1st Control Bank1") + self.w.spin(28, 0, 120, 1, 1, self.b2, 0, "ctrl2", "1st Control Bank2") + self.w.spin(9, -1, 127, 1, 1, self.b2, 0, "mast", "Master Controller\n\ + [-1=no Master]") + self.w.spin(4, 1, 4, 1, 1, self.b3, 0, "parms", " # of Parameters\n\ + [1=amp 2=band-\n pass peak freq\n 3=peak gain\n 4=speed/freq]") + self.p = False + self.w.text("\nSelect options first ", self.b4, self.g) + self.but = self.w.cbbutton(self.b4, self.playcsd, "START !") + self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0)) + self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0)) + + def version2(self, widget): + if self.ver != 0: + self.box1.destroy() + self.box2.destroy() + self.ver = 2 + self.box1 = self.w.box(True, self.bb) + self.w.text("\t\t\t ", self.box1) + self.box2 = self.w.box(True, self.bb) + self.f = self.w.framebox(" 2 - FileMix4ASC ", False, self.box2, self.r) + self.b1 = self.w.box(True, self.f) + self.b2 = self.w.box(True, self.f) + self.w.reset() + self.w.csd("FileMix4ASC.csd") + self.w.spin(4, 1, 4, 1, 1, self.b1, 0, "parms", " # of Parameters\n\ + [1=amp 2=band-\n pass peak freq\n 3=peak gain\n 4=speed/freq]") + self.p = False + self.w.text("\nSelect option first ", self.b2, self.g) + self.but = self.w.cbbutton(self.b2, self.playcsd, "START !") + self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0)) + self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0)) + + def version3(self, widget): + if self.ver != 0: + self.box1.destroy() + self.box2.destroy() + self.ver = 3 + self.box1 = self.w.box(True, self.bb) + self.w.text(" ", self.box1) + self.box2 = self.w.box(True, self.bb) + self.f = self.w.framebox(" 3 - FileMix ", False, self.box2, self.r) + self.b1 = self.w.box(True, self.f) + self.b2 = self.w.box(True, self.f) + self.b3 = self.w.box(True, self.f) + self.b4 = self.w.box(True, self.f) + self.b5 = self.w.box(True, self.f) + self.b6 = self.w.box(True, self.f) + self.w.reset() + self.w.csd("FileMix.csd") + self.w.spin(0, 0, 16, 1, 1, self.b1, 0, "chan", "Channel # [0=CC7,\n \ +channels 1-16]") + self.w.spin(20, 0, 120, 1, 1, self.b1, 0, "ctrl1", "1st Control Bank1") + self.w.spin(28, 0, 120, 1, 1, self.b2, 0, "ctrl2", "1st Control Bank2") + self.w.spin(9, -1, 127, 1, 1, self.b2, 0, "mast", "Master Controller\n\ + [-1=no Master]") + self.w.spin(4, 1, 4, 1, 1, self.b3, 0, "parms", " # of Parameters\n\ + [1=amp 2=band-\n pass peak freq\n 3=peak gain\n 4=speed/freq]") + self.w.spin(4, 1, 4, 1, 1, self.b4, 0, "files", "# of Files") + self.w.button(self.b4, "random", "Start at Head?") + self.w.button(self.b4, "loop", "Single Play ?") + self.w.button(self.b5, "delay", "Delay Start ?") + self.w.text("If delay, hit any key/\nMIDI note to begin.\n\ + [Volumes up first,\n & set fadein/out.]", self.b5, self.g) + self.w.spin(-2, -3, 30, 1, 1, self.b6, 0, "fade", " FadeIn/Out Seconds\n\ +[-3=.01/-2=.1/-1=.5]") + self.p = False + self.w.text("Select options first ", self.b6, self.g) + self.but = self.w.cbbutton(self.b6, self.playcsd, "START !") + self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0)) + self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0)) + + def version4(self, widget): + if self.ver != 0: + self.box1.destroy() + self.box2.destroy() + self.ver = 4 + self.box1 = self.w.box(True, self.bb) + self.w.text("\t\t\t\t\t\t\t\t ", self.box1) + self.box2 = self.w.box(True, self.bb) + self.f = self.w.framebox(" 4 - FileMixASC ", False, self.box2, \ +self.r) + self.b1 = self.w.box(True, self.f) + self.b2 = self.w.box(True, self.f) + self.b3 = self.w.box(True, self.f) + self.b4 = self.w.box(True, self.f) + self.w.reset() + self.w.csd("FileMixASC.csd") + self.w.spin(4, 1, 4, 1, 1, self.b1, 0, "parms", " # of Parameters\n\ + [1=amp 2=band-\n pass peak freq\n 3=peak gain\n 4=speed/freq]") + self.w.spin(4, 1, 4, 1, 1, self.b2, 0, "files", "# of Files") + self.w.button(self.b2, "random", "Start at Head?") + self.w.button(self.b2, "loop", "Single Play ?") + self.w.button(self.b3, "delay", "Delay Start ?") + self.w.text(" If delay, press T\n or Y to begin.\n\ +[Volumes up first,\n& set fadein/out.]", self.b3, self.g) + self.w.spin(-2, -3, 30, 1, 1, self.b4, 0, "fade", " FadeIn/Out Seconds\n\ +[-3=.01/-2=.1/-1=.5]") + self.p = False + self.w.text("Select options first ", self.b4, self.g) + self.but = self.w.cbbutton(self.b4, self.playcsd, "START !") + self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0)) + self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0)) + + diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..77fda74 --- /dev/null +++ b/setup.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +from sugar.activity import bundlebuilder +if __name__ == "__main__": + bundlebuilder.start() diff --git a/soundin.1 b/soundin.1 new file mode 100755 index 0000000..11d9695 --- /dev/null +++ b/soundin.1 Binary files differ diff --git a/soundin.2 b/soundin.2 new file mode 100755 index 0000000..94abfe5 --- /dev/null +++ b/soundin.2 Binary files differ diff --git a/soundin.3 b/soundin.3 new file mode 100755 index 0000000..35a6398 --- /dev/null +++ b/soundin.3 Binary files differ diff --git a/soundin.4 b/soundin.4 new file mode 100755 index 0000000..9b981c0 --- /dev/null +++ b/soundin.4 Binary files differ -- cgit v0.9.1