def __init__(self, maxSizeInSeconds = 30, pitch = A4, volume = 127, channels = 2): # SampleLength in milliseconds print "Max recording time:", maxSizeInSeconds, "secs" self.SampleSize = maxSizeInSeconds * 1000 # convert seconds into milliseconds self.MAX_LOOP_TIME = self.__msToFrames__(self.SampleSize) self.LOOP_CHANNELS = channels # holds recorded audio self.sample = FloatSample(self.MAX_LOOP_TIME, self.LOOP_CHANNELS) # create units self.lineIn = LineIn() # create input line (stereo) self.lineOut = LineOut() # create output line (stereo)(mixes output to computer's audio (DAC) card) self.panning = 63 # ranges from 0 (left) to 127 (right) - 63 is center self.panLeft = Pan() # Pan control for the left channel self.panRight = Pan() # Pan control for the right channel self.setPanning(self.panning) # initialize panning to center (63) # create sample player (mono or stereo, as needed) and connect to lineOut mixer if self.LOOP_CHANNELS == 1: # mono audio? # handle input self.writer = FixedRateMonoWriter() # captures incoming audio (mono) self.lineIn.output.connect(0, self.writer.input, 0) # connect line input to the sample writer (recorder) # handle output self.player = VariableRateMonoReader() # create mono sample player self.player.output.connect( 0, self.panLeft.input, 0) # connect single channel to pan control self.player.output.connect( 0, self.panRight.input, 0) elif self.LOOP_CHANNELS == 2: # stereo audio? # handle input self.writer = FixedRateStereoWriter() # captures incoming audio self.lineIn.output.connect(0, self.writer.input, 0) # connect line input to the sample writer (recorder) self.lineIn.output.connect(0, self.writer.input, 1) # handle output self.player = VariableRateStereoReader() # create stereo sample player self.player.output.connect( 0, self.panLeft.input, 0) # connect both channels to pan control self.player.output.connect( 1, self.panRight.input, 0) else: raise TypeError( "Can only record mono (1) or stereo (2 channels)." ) # now that we have a player, set the default and current pitches self.defaultPitch = pitch # default pitch of the live sample self.pitch = pitch # playback pitch (may be different from default pitch) self.frequency = self.__convertPitchToFrequency__(pitch) # and corresponding frequency # smooth out (linearly ramp) changes in player amplitude (without this, we get clicks) self.amplitudeSmoother = LinearRamp() self.amplitudeSmoother.output.connect( self.player.amplitude ) # connect to player's amplitude self.amplitudeSmoother.input.setup( 0.0, 0.5, 1.0 ) # set minimum, current, and maximum settings for control self.amplitudeSmoother.time.set( 0.0002 ) # and how many seconds to take for smoothing amplitude changes self.player.rate.set(jSyn.FRAMERATE) self.volume = volume # holds current volume (0-127) self.setVolume(self.volume) # sets the desired volume # connect panned sample to line output self.panLeft.output.connect (0, self.lineOut.input, 0) self.panRight.output.connect (1, self.lineOut.input, 1) # remember is sample is paused or not - needed for function isPaused() self.hasPaused = False # create time stamp variables self.beginRecordingTimeStamp = None # holds timestamp of when we start recording into the sample self.endRecordingTimeStamp = None # holds timestamp of when we stop recording into the sample self.recordedSampleSize = None # holds overall length of time of the sample rounded to nearest int self.recordingFlag = False # boolean flag that is only true when the sample is being written to self.monitoringFlag = False # boolean flag that is only true when monitor is turned on jSyn.addLive(self) # connect sample unit to the jSyn synthesizer # remember that this LiveSample has been created and is active (so that it can be stopped by JEM, if desired) __ActiveAudioSamples__.append(self)
def __init__(self, filename, pitch=A4, volume=127): # ensure the file exists (jSyn will NOT complain on its own) if not os.path.isfile(filename): raise ValueError("File '" + str(filename) + "' does not exist.") # file exists, so continue self.filename = filename # remember is sample is paused or not - needed for function isPaused() self.hasPaused = False # load and create the audio sample SampleLoader.setJavaSoundPreferred( False ) # use internal jSyn sound processes datafile = File(self.filename) # get sound file self.sample = SampleLoader.loadFloatSample( datafile ) # load it as a a jSyn sample self.channels = self.sample.getChannelsPerFrame() # get number of channels in sample # create lineOut unit (it mixes output to computer's audio (DAC) card) self.lineOut = LineOut() # create panning control (we simulate this using two pan controls, one for the left channel and # another for the right channel) - to pan we adjust their respective pan self.panLeft = Pan() self.panRight = Pan() # NOTE: The two pan controls have only one of their outputs (as their names indicate) # connected to LineOut. This way, we can set their pan value as we would normally, and not worry # about clipping (i.e., doubling the output amplitude). Also, this works for both mono and # stereo samples. # create sample player (mono or stereo, as needed) and connect to lineOut mixer if self.channels == 1: # mono audio? self.player = VariableRateMonoReader() # create mono sample player self.player.output.connect( 0, self.panLeft.input, 0) # connect single channel to pan control self.player.output.connect( 0, self.panRight.input, 0) elif self.channels == 2: # stereo audio? self.player = VariableRateStereoReader() # create stereo sample player self.player.output.connect( 0, self.panLeft.input, 0) # connect both channels to pan control self.player.output.connect( 1, self.panRight.input, 0) else: raise TypeError( "Can only play mono or stereo samples." ) # now that we have a player, set the default and current pitches self.defaultPitch = pitch # the default pitch of the audio sample self.pitch = pitch # remember playback pitch (may be different from default pitch) self.frequency = self.__convertPitchToFrequency__(pitch) # and corresponding frequency # now, connect pan control to mixer self.panLeft.output.connect( 0, self.lineOut.input, 0 ) self.panRight.output.connect( 1, self.lineOut.input, 1 ) # now, that panning is set up, initialize it to center self.panning = 63 # ranges from 0 (left) to 127 (right) - 63 is center self.setPanning( self.panning ) # and initialize # smooth out (linearly ramp) changes in player amplitude (without this, we get clicks) self.amplitudeSmoother = LinearRamp() self.amplitudeSmoother.output.connect( self.player.amplitude ) # connect to player's amplitude self.amplitudeSmoother.input.setup( 0.0, 0.5, 1.0 ) # set minimum, current, and maximum settings for control self.amplitudeSmoother.time.set( 0.0002 ) # and how many seconds to take for smoothing amplitude changes # play at original pitch self.player.rate.set( self.sample.getFrameRate() ) self.volume = volume # holds current volume (0 - 127) self.setVolume( self.volume ) # set the desired volume # NOTE: Adding to global jSyn synthesizer jSyn.add(self) # connect sample unit to the jSyn synthesizer # remember that this AudioSample has been created and is active (so that it can be stopped by JEM, if desired) __ActiveAudioSamples__.append(self)