From c0eed84e4d0dfec58d485b97f8ee96ea3467894a Mon Sep 17 00:00:00 2001 From: David Runge Date: Mon, 30 Mar 2015 19:33:40 +0200 Subject: SNPAudio.sc: Moving/Renaming SNPSonificator.sc to SNPAudio.sc --- SNPAudio.sc | 399 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ SNPSonificator.sc | 399 ------------------------------------------------------ 2 files changed, 399 insertions(+), 399 deletions(-) create mode 100644 SNPAudio.sc delete mode 100644 SNPSonificator.sc diff --git a/SNPAudio.sc b/SNPAudio.sc new file mode 100644 index 0000000..a86a750 --- /dev/null +++ b/SNPAudio.sc @@ -0,0 +1,399 @@ +SNPSonificator { + var <>numChannels;//number of channels to use + var snpDict;//the SNPDict to use + var <>playTime;//calculated play time of a single SNP, defined by playTime setup on init + var <>includeUnknown;//wether to include SNPs with unknown resolvers (aka. SNPS with only bases set) + var <>ignoreSNPs = #[];//Array of Symbols of chromosomes to ignore (1-22,X,Y,MT) + var compression + var recording/out + var recPath;//String representing directory to use for recording + var \base_pair".postln; + SynthDef(\base_pair, {|out=0, freq=#[0.0,0.0,0.0] ,amplitude=0.6, attackTime = 0.01, releaseTime = 0.3, curve = -4| + var env = EnvGen.kr( + Env.perc(attackTime,releaseTime,amplitude,curve),doneAction:2//free the enclosing Synth when done + ); + Out.ar( + sonBus.index+out,//speaker to play on + SinOsc.ar(//sine tone for the base pair + freq[0],0,env, + SinOsc.ar(//sine tone for the first (lower) resolver + freq[1],0,env*0.5 + )+ + SinOsc.ar(//sine tone for the second (upper) resolver + freq[2],0,env * 0.5 + ) + ) + );}, variants: (//variants for 23 first chromosomes + 1: [amplitude: 0.10, attackTime:0.01, releaseTime:0.7, curve:-4],//0.125 + 2: [amplitude: 0.10, attackTime:0.01, releaseTime:0.7, curve:-4],//0.125 + 3: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 + 4: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 + 5: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 + 6: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 + 7: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 + 8: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 + 9: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 + 10: [amplitude: 0.06, attackTime:0.01, releaseTime:0.5, curve:-2],//0.375 + 11: [amplitude: 0.06, attackTime:0.01, releaseTime:0.5, curve:-2],//0.375 + 12: [amplitude: 0.06, attackTime:0.01, releaseTime:0.5, curve:-2],//0.375 + 13: [amplitude: 0.06, attackTime:0.01, releaseTime:0.5, curve:-2],//0.375 + 14: [amplitude: 0.06, attackTime:0.01, releaseTime:0.5, curve:-2],//0.375 + 15: [amplitude: 0.06, attackTime:0.01, releaseTime:0.5, curve:-2],//0.375 + 16: [amplitude: 0.04, attackTime:0.01, releaseTime:0.5, curve:-2],//0.500 + 17: [amplitude: 0.04, attackTime:0.01, releaseTime:0.5, curve:-2],//0.500 + 18: [amplitude: 0.04, attackTime:0.01, releaseTime:0.5, curve:-2],//0.500 + 19: [amplitude: 0.04, attackTime:0.01, releaseTime:0.5, curve:-2],//0.750 + 20: [amplitude: 0.05, attackTime:0.01, releaseTime:0.5, curve:-2],//0.625 + 21: [amplitude: 0.05, attackTime:0.01, releaseTime:0.5, curve:-2],//0.875 + 22: [amplitude: 0.05, attackTime:0.01, releaseTime:0.5, curve:-2],//0.875 + 23: [amplitude: 0.05, attackTime:0.01, releaseTime:0.5, curve:-2]//0.875 + )).add; + "Adding SynthDef for single bases -> \base_single".postln; + SynthDef(\base_single, {|out=0, freq=#[0.0,0.0] ,amplitude=0.6, attackTime = 0.01, releaseTime = 0.3, curve = -4| + var env = EnvGen.kr( + Env.perc(attackTime,releaseTime,amplitude,curve),doneAction:2//free the enclosing Synth when done + ); + Out.ar( + sonBus.index+out, + Saw.ar(//sine tone for the base + freq[0],env,SinOsc.ar(//sine tone for the resolver + freq[1],0,env*0.5 + ) + ) + );},variants: (//variants for X and Y chromosomes + 23:[amplitude: 0.07, attackTime: 0.01, releaseTime: 0.5, curve: -4],//0.250 -> X + 24:[amplitude: 0.10, attackTime: 0.01, releaseTime: 0.7, curve: -4]//0.75 ->Y + )).add; + "Adding SynthDef for MT bases -> \base_mt".postln; + SynthDef(\base_mt, {|startPosition = 0, freq = #[0.0,0.0], attackTime = 0.01, releaseTime = 1.5, amplitude = 0.4, curve = -4 | + var mtSynth, panAround; + var env = EnvGen.kr( + Env.perc(attackTime,releaseTime,amplitude,curve),doneAction:2//free the enclosing Synth when done + ); + mtSynth = Saw.ar(//sine tone for the base + freq[0],env,SinOsc.ar(//sine tone for the resolver + freq[1],0,env*0.5 + ) + ); + panAround = PanAz.ar( + numChannels,//span the whole number of channels available + mtSynth,//use the MT Synth as input + LFSaw.kr(2,0),//pan around TODO: + startPosition + 0.5,//control level + 2,//width of sound + startPosition//random starting point + ); + Out.ar(sonBus, panAround); + }).add; + } + + addCompressionSynths{ + "Adding SynthDef for compression -> \compressor".postln; + SynthDef(\compressor, {|inBus| + var in,compressed; + in = In.ar(inBus,numChannels); + compressed = Compander.ar( + in,//signal in + in,//control signal + 0.5,//threshold + 1,//slopeBelow + 0.3,//slopeAbove + 0.002,//clampTime + 0.01//relaxTime + ); + ReplaceOut.ar(0, compressed*0.1); + Out.ar(recBus, compressed*0.1); + }).add; + } + + startDSPSynths{//start compression and possibly recording Synths + ("Starting compression Synth.").postln; + Synth(\compressor, [inBus:sonBus], compressionGroup);//play compression Synth + compressionGroup.run(true);//explicitely turn on compressionGroup (needed for pause/play) + if(record,{//if recording, play recording Synth + ("Starting recording Synth for recording to file.").postln; + Synth(\recordSNP, [buffer: this.recordingBuffer], recordingGroup); + },{//FIXME: Do we have to explicitely deactivate recordingGroup when not used? + recordingGroup.run(false); + }); + } + + stopDSPSynths{//stop compression and possibly recording Synths + Routine{ + 2.wait; + if(record,{ + ("Stopping recording to file.").postln; + recordingBuffer.close; + recordingBuffer.free; + if(recordingGroup.isRunning,{ + recordingGroup.run(false); + }); + }); + 1.wait; + if(compressionGroup.isRunning,{ + ("Stopping compressor Synth.").postln; + compressionGroup.run(false); + }); + }.play; + } + + playFromTo{//start from a position (if none set, start from the beginning), play to a position (or end, if none set) + arg fromPosition = 0.0, toPosition = snpDict.positions;//start from position, play to position + var startTime=0.0;//time to first position (if not playing from the beginning, this stays the same) + this.startDSPSynths;//start Synths for compression and recording + isPlaying = true; //set play parameter + if((fromPosition == 0.0) || (snpDict.positionssnpDict.positions) || (toPosition < fromPosition) || (toPosition.isNil),{//if to position is out of bounds or smaller then from, set to total length + lastStep = snpDict.positions; + },{//else play up to that position + lastStep = toPosition; + }); + ("Starting to play positions: "++currentStep++" - "++lastStep).postln; + SystemClock.sched(startTime,{//start a SystemClock immediately or with calculated startTime to read from the SNPDict + arg time; + var resched = 0.0; + if((isPlaying) && (snpDict.positions>currentStep) && (currentStep <= lastStep),{//if playing and positions are left, play the position and reschedule SystemClock to the next SNP +// ("Playing SNP #"++currentStep++" of "++snpDict.positions++".").postln; + resched = lengthOfSNP*this.playPosition(snpDict.snpAtPosition(snpDict.snpArr[currentStep]), snpDict.snpArr[currentStep]); + currentStep = currentStep+1.0; +// ("Rescheduling in "++resched++"s for step #"++currentStep++" of "++snpDict.positions).postln; + resched; + },{//end the SystemClock and print out last position + ("Done playing. Last position: "++(currentStep-1).asString).postln; + this.stopDSPSynths; + nil; + }); + }); + } + + pausePlay{//pause the sonification + isPlaying = false; + } + + resumePlay{//resume the sonification from last position played + isPlaying = true; + ("current: "++currentStep++" - last: "++lastStep).postln; + this.playFromTo(currentStep, lastStep); + } + + playPosition{//play the SNP(s) at a position and return the distance to the next + arg posDict, position; + posDict.keysValuesDo{ + arg key, value; + if(ignoreSNPs.includes(key).not,{//ignore chromosomes if that is set up + if(includeUnknown,{//if SNPs without resolvers should be ignored, do that + this.playBase(value); + },{ + if(value.hasResolver,{ + this.playBase(value); + }); + }); + }); + }; + ^snpDict.distanceToNextPosition(position); + } + + playBase{//play the actual base/base pair + arg snp; + var baseKey = keyToFrq.at(keys[snp.vecChromosome-1]); + if(SNPInfo.isBasePair(snp.base),{//play base pairs + Synth('base_pair.'++snp.vecChromosome.asSymbol, [out: this.findSpeaker(snp.vecChromosome), freq: [baseKey.at(snp.vecBase), baseKey.at(snp.vecResolver[0]), baseKey.at(snp.vecResolver[1])]], synthGroup); + },{ + if(SNPInfo.isBase(snp.base), {//play single bases + if(snp.chromosome==\MT, {//play the MT chromosome + Synth('base_mt', [startPosition: rrand(numChannels,0), freq: [baseKey.at(snp.vecBase), baseKey.at(snp.vecResolver[0])]], synthGroup); + },{//play parts of the X and the Y chromosome + Synth('base_single.'++snp.vecChromosome.asSymbol, [out: this.findSpeaker(snp.vecChromosome), freq: [baseKey.at(snp.vecBase), baseKey.at(snp.vecResolver[0])]], synthGroup); + }); + }); + }); + //update the currently playing base of the chromosome in gui, if it has been spawned + if(gui.notNil,{ + gui.setIntermediateText(snp.vecChromosome, snp.base); + }); + baseKey.free; + } + + findSpeaker{//find the speaker for the chromosome (defined in speakerSetup) + arg chromosome; + var speaker = 0; + speakerSetup.do({ + arg item, i; + if(item.includes(chromosome),{ + speaker = i; + }); + }); + ^speaker; + } + + calcSNPTime{//calculate the clock time for a single SNP + arg playTime; + var snpTime; + snpTime = ((1/SNPInfo.lengthAtOneMs)*playTime)/1000; + ^snpTime; + } + + queryTimeAndPosition{//query current time and position + ("Positions: "++currentStep.asString++" - "++lastStep.asString++".").postln; + ("Play time: "++(currentStep*lengthOfSNP*1000).asString++"s - "++(lastStep*lengthOfSNP*1000).asString++"s.").postln; + } + + // create a new SNPGUI instance + spawnView{ + gui = SNPGUI.new(speakerSetup); + } +} diff --git a/SNPSonificator.sc b/SNPSonificator.sc deleted file mode 100644 index a86a750..0000000 --- a/SNPSonificator.sc +++ /dev/null @@ -1,399 +0,0 @@ -SNPSonificator { - var <>numChannels;//number of channels to use - var snpDict;//the SNPDict to use - var <>playTime;//calculated play time of a single SNP, defined by playTime setup on init - var <>includeUnknown;//wether to include SNPs with unknown resolvers (aka. SNPS with only bases set) - var <>ignoreSNPs = #[];//Array of Symbols of chromosomes to ignore (1-22,X,Y,MT) - var compression - var recording/out - var recPath;//String representing directory to use for recording - var \base_pair".postln; - SynthDef(\base_pair, {|out=0, freq=#[0.0,0.0,0.0] ,amplitude=0.6, attackTime = 0.01, releaseTime = 0.3, curve = -4| - var env = EnvGen.kr( - Env.perc(attackTime,releaseTime,amplitude,curve),doneAction:2//free the enclosing Synth when done - ); - Out.ar( - sonBus.index+out,//speaker to play on - SinOsc.ar(//sine tone for the base pair - freq[0],0,env, - SinOsc.ar(//sine tone for the first (lower) resolver - freq[1],0,env*0.5 - )+ - SinOsc.ar(//sine tone for the second (upper) resolver - freq[2],0,env * 0.5 - ) - ) - );}, variants: (//variants for 23 first chromosomes - 1: [amplitude: 0.10, attackTime:0.01, releaseTime:0.7, curve:-4],//0.125 - 2: [amplitude: 0.10, attackTime:0.01, releaseTime:0.7, curve:-4],//0.125 - 3: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 - 4: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 - 5: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 - 6: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 - 7: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 - 8: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 - 9: [amplitude: 0.08, attackTime:0.01, releaseTime:0.6, curve:-4],//0.250 - 10: [amplitude: 0.06, attackTime:0.01, releaseTime:0.5, curve:-2],//0.375 - 11: [amplitude: 0.06, attackTime:0.01, releaseTime:0.5, curve:-2],//0.375 - 12: [amplitude: 0.06, attackTime:0.01, releaseTime:0.5, curve:-2],//0.375 - 13: [amplitude: 0.06, attackTime:0.01, releaseTime:0.5, curve:-2],//0.375 - 14: [amplitude: 0.06, attackTime:0.01, releaseTime:0.5, curve:-2],//0.375 - 15: [amplitude: 0.06, attackTime:0.01, releaseTime:0.5, curve:-2],//0.375 - 16: [amplitude: 0.04, attackTime:0.01, releaseTime:0.5, curve:-2],//0.500 - 17: [amplitude: 0.04, attackTime:0.01, releaseTime:0.5, curve:-2],//0.500 - 18: [amplitude: 0.04, attackTime:0.01, releaseTime:0.5, curve:-2],//0.500 - 19: [amplitude: 0.04, attackTime:0.01, releaseTime:0.5, curve:-2],//0.750 - 20: [amplitude: 0.05, attackTime:0.01, releaseTime:0.5, curve:-2],//0.625 - 21: [amplitude: 0.05, attackTime:0.01, releaseTime:0.5, curve:-2],//0.875 - 22: [amplitude: 0.05, attackTime:0.01, releaseTime:0.5, curve:-2],//0.875 - 23: [amplitude: 0.05, attackTime:0.01, releaseTime:0.5, curve:-2]//0.875 - )).add; - "Adding SynthDef for single bases -> \base_single".postln; - SynthDef(\base_single, {|out=0, freq=#[0.0,0.0] ,amplitude=0.6, attackTime = 0.01, releaseTime = 0.3, curve = -4| - var env = EnvGen.kr( - Env.perc(attackTime,releaseTime,amplitude,curve),doneAction:2//free the enclosing Synth when done - ); - Out.ar( - sonBus.index+out, - Saw.ar(//sine tone for the base - freq[0],env,SinOsc.ar(//sine tone for the resolver - freq[1],0,env*0.5 - ) - ) - );},variants: (//variants for X and Y chromosomes - 23:[amplitude: 0.07, attackTime: 0.01, releaseTime: 0.5, curve: -4],//0.250 -> X - 24:[amplitude: 0.10, attackTime: 0.01, releaseTime: 0.7, curve: -4]//0.75 ->Y - )).add; - "Adding SynthDef for MT bases -> \base_mt".postln; - SynthDef(\base_mt, {|startPosition = 0, freq = #[0.0,0.0], attackTime = 0.01, releaseTime = 1.5, amplitude = 0.4, curve = -4 | - var mtSynth, panAround; - var env = EnvGen.kr( - Env.perc(attackTime,releaseTime,amplitude,curve),doneAction:2//free the enclosing Synth when done - ); - mtSynth = Saw.ar(//sine tone for the base - freq[0],env,SinOsc.ar(//sine tone for the resolver - freq[1],0,env*0.5 - ) - ); - panAround = PanAz.ar( - numChannels,//span the whole number of channels available - mtSynth,//use the MT Synth as input - LFSaw.kr(2,0),//pan around TODO: + startPosition - 0.5,//control level - 2,//width of sound - startPosition//random starting point - ); - Out.ar(sonBus, panAround); - }).add; - } - - addCompressionSynths{ - "Adding SynthDef for compression -> \compressor".postln; - SynthDef(\compressor, {|inBus| - var in,compressed; - in = In.ar(inBus,numChannels); - compressed = Compander.ar( - in,//signal in - in,//control signal - 0.5,//threshold - 1,//slopeBelow - 0.3,//slopeAbove - 0.002,//clampTime - 0.01//relaxTime - ); - ReplaceOut.ar(0, compressed*0.1); - Out.ar(recBus, compressed*0.1); - }).add; - } - - startDSPSynths{//start compression and possibly recording Synths - ("Starting compression Synth.").postln; - Synth(\compressor, [inBus:sonBus], compressionGroup);//play compression Synth - compressionGroup.run(true);//explicitely turn on compressionGroup (needed for pause/play) - if(record,{//if recording, play recording Synth - ("Starting recording Synth for recording to file.").postln; - Synth(\recordSNP, [buffer: this.recordingBuffer], recordingGroup); - },{//FIXME: Do we have to explicitely deactivate recordingGroup when not used? - recordingGroup.run(false); - }); - } - - stopDSPSynths{//stop compression and possibly recording Synths - Routine{ - 2.wait; - if(record,{ - ("Stopping recording to file.").postln; - recordingBuffer.close; - recordingBuffer.free; - if(recordingGroup.isRunning,{ - recordingGroup.run(false); - }); - }); - 1.wait; - if(compressionGroup.isRunning,{ - ("Stopping compressor Synth.").postln; - compressionGroup.run(false); - }); - }.play; - } - - playFromTo{//start from a position (if none set, start from the beginning), play to a position (or end, if none set) - arg fromPosition = 0.0, toPosition = snpDict.positions;//start from position, play to position - var startTime=0.0;//time to first position (if not playing from the beginning, this stays the same) - this.startDSPSynths;//start Synths for compression and recording - isPlaying = true; //set play parameter - if((fromPosition == 0.0) || (snpDict.positionssnpDict.positions) || (toPosition < fromPosition) || (toPosition.isNil),{//if to position is out of bounds or smaller then from, set to total length - lastStep = snpDict.positions; - },{//else play up to that position - lastStep = toPosition; - }); - ("Starting to play positions: "++currentStep++" - "++lastStep).postln; - SystemClock.sched(startTime,{//start a SystemClock immediately or with calculated startTime to read from the SNPDict - arg time; - var resched = 0.0; - if((isPlaying) && (snpDict.positions>currentStep) && (currentStep <= lastStep),{//if playing and positions are left, play the position and reschedule SystemClock to the next SNP -// ("Playing SNP #"++currentStep++" of "++snpDict.positions++".").postln; - resched = lengthOfSNP*this.playPosition(snpDict.snpAtPosition(snpDict.snpArr[currentStep]), snpDict.snpArr[currentStep]); - currentStep = currentStep+1.0; -// ("Rescheduling in "++resched++"s for step #"++currentStep++" of "++snpDict.positions).postln; - resched; - },{//end the SystemClock and print out last position - ("Done playing. Last position: "++(currentStep-1).asString).postln; - this.stopDSPSynths; - nil; - }); - }); - } - - pausePlay{//pause the sonification - isPlaying = false; - } - - resumePlay{//resume the sonification from last position played - isPlaying = true; - ("current: "++currentStep++" - last: "++lastStep).postln; - this.playFromTo(currentStep, lastStep); - } - - playPosition{//play the SNP(s) at a position and return the distance to the next - arg posDict, position; - posDict.keysValuesDo{ - arg key, value; - if(ignoreSNPs.includes(key).not,{//ignore chromosomes if that is set up - if(includeUnknown,{//if SNPs without resolvers should be ignored, do that - this.playBase(value); - },{ - if(value.hasResolver,{ - this.playBase(value); - }); - }); - }); - }; - ^snpDict.distanceToNextPosition(position); - } - - playBase{//play the actual base/base pair - arg snp; - var baseKey = keyToFrq.at(keys[snp.vecChromosome-1]); - if(SNPInfo.isBasePair(snp.base),{//play base pairs - Synth('base_pair.'++snp.vecChromosome.asSymbol, [out: this.findSpeaker(snp.vecChromosome), freq: [baseKey.at(snp.vecBase), baseKey.at(snp.vecResolver[0]), baseKey.at(snp.vecResolver[1])]], synthGroup); - },{ - if(SNPInfo.isBase(snp.base), {//play single bases - if(snp.chromosome==\MT, {//play the MT chromosome - Synth('base_mt', [startPosition: rrand(numChannels,0), freq: [baseKey.at(snp.vecBase), baseKey.at(snp.vecResolver[0])]], synthGroup); - },{//play parts of the X and the Y chromosome - Synth('base_single.'++snp.vecChromosome.asSymbol, [out: this.findSpeaker(snp.vecChromosome), freq: [baseKey.at(snp.vecBase), baseKey.at(snp.vecResolver[0])]], synthGroup); - }); - }); - }); - //update the currently playing base of the chromosome in gui, if it has been spawned - if(gui.notNil,{ - gui.setIntermediateText(snp.vecChromosome, snp.base); - }); - baseKey.free; - } - - findSpeaker{//find the speaker for the chromosome (defined in speakerSetup) - arg chromosome; - var speaker = 0; - speakerSetup.do({ - arg item, i; - if(item.includes(chromosome),{ - speaker = i; - }); - }); - ^speaker; - } - - calcSNPTime{//calculate the clock time for a single SNP - arg playTime; - var snpTime; - snpTime = ((1/SNPInfo.lengthAtOneMs)*playTime)/1000; - ^snpTime; - } - - queryTimeAndPosition{//query current time and position - ("Positions: "++currentStep.asString++" - "++lastStep.asString++".").postln; - ("Play time: "++(currentStep*lengthOfSNP*1000).asString++"s - "++(lastStep*lengthOfSNP*1000).asString++"s.").postln; - } - - // create a new SNPGUI instance - spawnView{ - gui = SNPGUI.new(speakerSetup); - } -} -- cgit v1.2.3-70-g09d2