def add(*args): c = pyext.Buffer(args[0]) a = pyext.Buffer(args[1]) b = pyext.Buffer(args[2]) commonlen = min(len(a), len(b), len(c)) # explicit casting to arrays is also possible c[:commonlen] = N.array(a[:commonlen], dtype=N.float32) + N.array( b[:commonlen], dtype=N.float32)
def update_buffer_1(self, main_buff_name, tmp_buff_name, event, tb_pos, t_length): sr = 44100. / 1000. # sample rate mb_pos = self.bob.s_l.mm_data['data'][event]['time'][0] main_buff = pyext.Buffer(main_buff_name) tmp_buff = pyext.Buffer(tmp_buff_name) ind_mb_1 = int(np.floor(sr * mb_pos)) len_tmp = len(tmp_buff) s_length = int(np.round(sr * t_length)) #in samples # print s_length, sr, t_length ind_tb_1 = int(np.floor(sr * tb_pos)) to_be_copied = np.array(main_buff[ind_mb_1:ind_mb_1 + s_length]) s_crossfade = int(np.round(self.crossfade * sr)) if ind_tb_1 + s_crossfade <= len_tmp: ind_tb_2 = ind_tb_1 + s_length #print to_be_copied[0:s_crossfade].shape, tmp_buff[ind_tb_1:ind_tb_1+s_crossfade].shape to_be_copied[0:s_crossfade] = ( np.linspace(0.0, 1.0, s_crossfade) * to_be_copied[0:s_crossfade] + np.linspace(1.0, 0.0, s_crossfade) * tmp_buff[ind_tb_1:ind_tb_1 + s_crossfade]) else: # > ind_c = len_tmp - ind_tb_1 to_be_copied[0:ind_c] = ( np.linspace(0.0, 1.0, s_crossfade)[0:ind_c] * to_be_copied[0:ind_c] + np.linspace(1.0, 0.0, s_crossfade)[0:ind_c] * tmp_buff[ind_tb_1:ind_tb_1 + ind_c]) to_be_copied[ind_c:s_crossfade] = ( np.linspace(0.0, 1.0, s_crossfade)[ind_c:s_crossfade] * to_be_copied[ind_c:s_crossfade] + np.linspace(1.0, 0.0, s_crossfade)[ind_c:s_crossfade] * tmp_buff[ind_tb_1 + ind_c:ind_tb_1 + s_crossfade]) if ind_tb_1 + s_length <= len_tmp: ind_tb_2 = ind_tb_1 + s_length #ind_mb_2 = ind_mb_1+ind_tb_2-ind_tb_1 tmp_buff[ind_tb_1:ind_tb_2] = to_be_copied[:] else: # > ind_tb_2 = len_tmp ind_mb_2 = ind_tb_2 - ind_tb_1 tmp_buff[ind_tb_1:ind_tb_2] = to_be_copied[:ind_mb_2] ind_tb_3 = 0 ind_tb_4 = s_length - len_tmp + ind_tb_1 tmp_buff[ind_tb_3:ind_tb_4] = to_be_copied[ind_mb_2:s_length]
def mul(*args): # create buffer objects # as long as these variables live the underlying buffers are locked c = pyext.Buffer(args[0]) a = pyext.Buffer(args[1]) b = pyext.Buffer(args[2]) commonlen = min(len(a),len(b),len(c)) # slicing causes Python arrays (mapped to buffers) to be created # note the c[:] - to assign contents you must assign to a slice of the buffer c[:commonlen] = a[:commonlen]*b[:commonlen]
def synthesize_1(self, *args): if not self._proc: raise Exception("can't synthesize - no gansynth_worker process is running") arg_count = len(args) if arg_count == 0 or arg_count % 3 != 0: raise ValueError("invalid number of arguments ({}), should be a multiple of 3: synthesize z1 audio1 pitch1 [z2 audio2 pitch2 ...]".format(arg_count)) gen_audio_msgs = [] audio_buf_names = [] for i in range(0, arg_count, 3): z_buf_name, audio_buf_name, pitch = args[i:i+3] z32_buf = pyext.Buffer(z_buf_name) z = np.array(z32_buf, dtype=np.float64) gen_audio_msgs.append(protocol.to_gen_audio_msg(pitch, z)) audio_buf_names.append(audio_buf_name) in_count = len(gen_audio_msgs) in_count_msg = protocol.to_count_msg(in_count) self._write_msg(protocol.IN_TAG_GEN_AUDIO, in_count_msg, *gen_audio_msgs) self._read_tag(protocol.OUT_TAG_AUDIO) out_count_msg = self._proc.stdout.read(protocol.count_struct.size) out_count = protocol.from_count_msg(out_count_msg) if out_count == 0: return assert out_count == in_count for audio_buf_name in audio_buf_names: audio_size_msg = self._proc.stdout.read(protocol.audio_size_struct.size) audio_size = protocol.from_audio_size_msg(audio_size_msg) audio_msg = self._proc.stdout.read(audio_size) audio_note = protocol.from_audio_msg(audio_msg) audio_buf = pyext.Buffer(audio_buf_name) if len(audio_buf) != len(audio_note): audio_buf.resize(len(audio_note)) audio_buf[:] = audio_note audio_buf.dirty() self._outlet(1, "synthesized")
def _write_edits(self): if not self._steps: return buf = pyext.Buffer(self._edits_buf_name) buf[:] = self._steps[self._step_ix]["edits"] buf.dirty()
def randomize_z_1(self, *buf_names): if not self._proc: raise Exception("can't randomize z - no gansynth_worker process is running") in_count = len(buf_names) if in_count == 0: raise ValueError("no buffer name(s) specified") in_count_msg = protocol.to_count_msg(in_count) self._write_msg(protocol.IN_TAG_RAND_Z, in_count_msg) self._read_tag(protocol.OUT_TAG_Z) out_count_msg = self._proc.stdout.read(protocol.count_struct.size) out_count = protocol.from_count_msg(out_count_msg) assert out_count == in_count for buf_name in buf_names: z_msg = self._proc.stdout.read(protocol.z_struct.size) z = protocol.from_z_msg(z_msg) z32 = z.astype(np.float32) buf = pyext.Buffer(buf_name) if len(buf) != len(z32): buf.resize(len(z32)) buf[:] = z32 buf.dirty() self._outlet(1, "randomized")
def ResizeGarrays(self, f): """ receives seq. loop length in samples/frames; calcs 16th note lenght in samples/frames, and resizes backbuffer garray/tables/lists/buffers accordingly """ self.seqLoopLenSmps = f self.seqLoopLenSmpsI = int(self.seqLoopLenSmps) self.seq16thLenSmps = self.seqLoopLenSmps / 16.0 self.seq16thLenSmpsI = int(self.seq16thLenSmps) #~ print(" SAR:float_2: got into second (actually, third) inlet: seqLoopLenSmps {0} seq16thLenSmps {1} /{2}".format(self.seqLoopLenSmps, self.seq16thLenSmpsI, self.curbuf)) # bbufs[deck][track][chL/R+2*curbuf] # getting segfaults - try limit resizes only to otherbufs? otherbuf = 1 if (self.curbuf == 0) else 0 # ternary #~ tvL = pyext.Buffer(self.bbufs[self.deckid0][track][2*otherbuf]) #~ tvR = pyext.Buffer(self.bbufs[self.deckid0][track][2*otherbuf+1]) procnames = "" oldszs = "" newszs = "" for trackbufnms in self.bbufs[self.deckid0]: #~ for ibname in (trackbufnms[2*otherbuf], trackbufnms[2*otherbuf+1]): # only others, separate for ibname in trackbufnms: # all #~ print(ibname, trackbufnms) a = pyext.Buffer(ibname) #print(ibname, a, len(a)) # len works here oldlen = len(a) if (oldlen != self.seqLoopLenSmpsI): #~ print("Oldsize of {0}: {1} samples".format(ibname, oldlen)) procnames += ibname + ", " oldszs += str(oldlen) + ", " # resize in buffer-2.pd: [py pyext.Buffer @py 1] -> [pym 2 resize @py 1] # readme.txt: Buffer.resize(frames,keep=1,zero=1) method a.resize(self.seqLoopLenSmpsI) #; a.dirty() #~ while(a.getdirty()): time.sleep(0.001) # was hack #~ print(" Newsize of {0}: {1} samples".format(ibname, len(a))) newszs += str(len(a)) + ", " print("Resized garrays (%s): oldsize (%s) -> newsize (%s)" % (procnames, oldszs, newszs))
def neg(target): a = pyext.Buffer(target) # in place transformation (see Python array ufuncs) N.negative(a[:],a[:]) # must mark buffer content as dirty to update graph # (no explicit assignment occurred) a.dirty()
def add_step_1(self): self._steps.append({ "edits": np.zeros(len(pyext.Buffer(self._edits_buf_name)), dtype=np.float32) }) self._step_ix += 1 self._read_edits() self._write_edits() self.updated()
def save_z_buf(z_name, path): z_buf = pyext.Buffer(z_name) z = from_z32(z_buf) base, ext = os.path.splitext(path) if not ext: ext = ".npy" path_fixed = base + ext print_err("save: " + path_fixed)
def ClearGarrays(self): # out here, we should clear the other backbuffers only, and then # like processSequenceList, set curbuf to otherbuf otherbuf = 1 if (self.curbuf == 0) else 0 # ternary tvbs = ((pyext.Buffer(self.bbufs[self.deckid0][0][2 * otherbuf]), pyext.Buffer(self.bbufs[self.deckid0][0][2 * otherbuf + 1])), (pyext.Buffer(self.bbufs[self.deckid0][1][2 * otherbuf]), pyext.Buffer(self.bbufs[self.deckid0][1][2 * otherbuf + 1]))) if ((tvbs[0][0]) and (tvbs[0][1]) and (tvbs[1][0]) and (tvbs[1][1])): for itrbufs in tvbs: for itbuf in itrbufs: itbuf[:] = np.zeros(self.seqLoopLenSmpsI, dtype=np.float32) self.curbuf = otherbuf # set other buf as current self._outlet(1, self.curbuf) else: # couldn't get tvL, tvR - now (tvbs[0][0]) .. print(" SAR:ClearGarrays: Couldn't get garrays {0}, {1}, {2}, {3}". format(self.bbufs[self.deckid0][0][2 * otherbuf], self.bbufs[self.deckid0][0][2 * otherbuf + 1], self.bbufs[self.deckid0][1][2 * otherbuf], self.bbufs[self.deckid0][1][2 * otherbuf + 1]))
def hallucinate_noz_1(self, audio_buf_name): if not self._proc: raise Exception("can't hallucinate - load a checkpoint first") if not self._steps: raise Exception("can't hallucinate - no steps added") self._read_edits() step_count = len(self._steps) print_err("step_count =", step_count) print_err("steps =", self._steps) edit_count = len(self._steps[0]["edits"]) edit_list = [] for step in self._steps: for edit in step["edits"]: edit_list.append(edit) print_err("len(edit_list) =", len(edit_list)) self._write_msg( protocol.IN_TAG_HALLUCINATE_NOZ, protocol.to_hallucinate_msg( step_count, self._interp_steps, self._sample_spacing, self._start_trim, self._attack, self._sustain, self._release ), protocol.to_count_msg(edit_count), *map(protocol.to_f64_msg, edit_list) ) self._read_tag(protocol.OUT_TAG_AUDIO) audio_size_msg = self._proc.stdout.read(protocol.audio_size_struct.size) audio_size = protocol.from_audio_size_msg(audio_size_msg) audio_msg = self._proc.stdout.read(audio_size) audio = protocol.from_audio_msg(audio_msg) audio_buf = pyext.Buffer(audio_buf_name) if len(audio_buf) != len(audio): audio_buf.resize(len(audio)) audio_buf[:] = audio audio_buf.dirty() self._outlet(1, ["hallucinated", len(audio)])
def load_1(self, audio_path, settings_path, buf_name): settings_path1 = os.path.join(script_dir, str(settings_path)) audio_path1 = os.path.join(script_dir, str(audio_path)) settings = load_settings(settings_path1) audio = load_audio(audio_path1) audio_f32 = audio.astype(np.float32) / 2**15 buf = pyext.Buffer(buf_name) if len(buf) != len(audio_f32): buf.resize(len(audio_f32)) buf[:] = audio_f32 buf.dirty() rows = settings["nsynth"]["resolution"] cols = rows length = settings["nsynth"]["length"] sample_rate = settings["nsynth"]["sampleRate"] pitches = settings["nsynth"]["pitches"] self._outlet(1, "loaded", [rows, cols, length, sample_rate] + pitches)
def load_ganspace_components_1(self, ganspace_components_file): ganspace_components_file = os.path.join( self._canvas_dir, str(ganspace_components_file) ) print("Loading GANSpace components...", file=sys.stderr) size_msg = protocol.to_int_msg(len(ganspace_components_file)) components_msg = ganspace_components_file.encode('utf-8') self._write_msg(protocol.IN_TAG_LOAD_COMPONENTS, size_msg, components_msg) self._read_tag(protocol.OUT_TAG_LOAD_COMPONENTS) count_msg = self._proc.stdout.read(protocol.count_struct.size) self._component_count = protocol.from_count_msg(count_msg) print_err("_component_count =", self._component_count) buf = pyext.Buffer(self._edits_buf_name) #buf.resize(component_count) #buf.dirty() print_err("GANSpace components loaded!")
def hallucinate_1(self, *args): if not self._proc: raise Exception("can't synthesize - load a checkpoint first") arg_count = len(args) if arg_count < 3 or arg_count > 8: raise ValueError( "invalid number of arguments ({}), should be one: hallucinate buffer_name note_count interpolation_steps" .format(arg_count)) audio_buf_name = args[0] note_count = int(args[1]) interpolation_steps = int(args[2]) rest = list(map(float, args[3:len(args)])) self._write_msg( protocol.IN_TAG_HALLUCINATE, protocol.to_hallucinate_msg(note_count, interpolation_steps, *rest)) self._read_tag(protocol.OUT_TAG_AUDIO) audio_size_msg = self._proc.stdout.read( protocol.audio_size_struct.size) audio_size = protocol.from_audio_size_msg(audio_size_msg) audio_msg = self._proc.stdout.read(audio_size) audio_note = protocol.from_audio_msg(audio_msg) audio_buf = pyext.Buffer(audio_buf_name) if len(audio_buf) != len(audio_note): audio_buf.resize(len(audio_note)) audio_buf[:] = audio_note audio_buf.dirty() self._outlet(1, ["hallucinated", audio_size])
def normalize_1(self, buf_name, target=0.9): buf = pyext.Buffer(buf_name) buf[:] = normalize(np.array(buf), target) buf.dirty() self._outlet(1, "normalized")
def fadein(target): a = pyext.Buffer(target) # in place operations are ok a *= N.arange(len(a),dtype=N.float32)/len(a)
def synthesize_noz_1(self, *args): if not self._proc: raise Exception("can't synthesize - no gansynth_worker process is running") arg_count = len(args) if arg_count == 0 or arg_count % 2 != 0: raise ValueError("invalid number of arguments ({}), should be a multiple of 2: synthesize_noz audio1 pitch1 [audio2 pitch2 ...]".format(arg_count)) component_buff = pyext.Buffer(self._edits_buf_name) components = np.array(component_buff, dtype=np.float64) component_msgs = [] for value in components: component_msgs.append(protocol.to_float_msg(value)) for i in range(self._component_count - len(components)): component_msgs.append(protocol.to_float_msg(0.0)) self._write_msg(protocol.IN_TAG_SET_COMPONENT_AMPLITUDES, *component_msgs) gen_msgs = [] audio_buf_names = [] for i in range(0, arg_count, 2): audio_buf_name, pitch = args[i:i+2] gen_msgs.append(protocol.to_synthesize_noz_msg(pitch)) audio_buf_names.append(audio_buf_name) in_count = len(gen_msgs) in_count_msg = protocol.to_count_msg(in_count) self._write_msg(protocol.IN_TAG_SYNTHESIZE_NOZ, in_count_msg, *gen_msgs) self._read_tag(protocol.OUT_TAG_AUDIO) out_count_msg = self._proc.stdout.read(protocol.count_struct.size) out_count = protocol.from_count_msg(out_count_msg) print_err("out_count =", out_count) if out_count == 0: print_err("no audio was synthesized!") return assert out_count == in_count for audio_buf_name in audio_buf_names: audio_size_msg = self._proc.stdout.read(protocol.audio_size_struct.size) audio_size = protocol.from_audio_size_msg(audio_size_msg) audio_msg = self._proc.stdout.read(audio_size) audio_note = protocol.from_audio_msg(audio_msg) audio_buf = pyext.Buffer(audio_buf_name) if len(audio_buf) != len(audio_note): audio_buf.resize(len(audio_note)) audio_buf[:] = audio_note audio_buf.dirty() self._outlet(1, "synthesized")
def processSequenceList(self): #,*args): #sys.stderr.write(" SAR:processSequenceList: Some other message into first (actually, second) inlet: {0}\n".format(args)) """ on "anything" in leftmost inlet 1: expecting sequence string for each track: if track 1: set track from track fader volume (eventually) for each lane: for each step: if velo > 2, start mixing 16th note into the other buf (from curbuf) elif 0 < velo <= 1, continue mixing 16th note into other buf else (velo == 0), stop/skip mixing if track 2: (will need pitching here too). possibly (initiate) save newly mixed buffer to file (for screenshot) swith curbuf to newly rendered buf - and output message ... or... for faster: for each step: for each lane: add samples accordingly, write into mix """ # check first if lastSequence has been set; if not, do not perform and exit early - this definitely happens once at start, where first the arrays are sized, and only after does the first sequence come in if self.lastSequence is None: print("Have no sequence; bailing out") return #print(type(args[0]), type(args[0])==pyext.Symbol, isinstance(args[0], pyext.Symbol)) # ok # clean args: make Symbol into strings first - now above #cargs = map(lambda x: str(x) if (isinstance(x, pyext.Symbol)) else x, args) cargs = self.lastSequence #song = 1 # for now - no more, now have self.deckid0/1 otherbuf = 1 if (self.curbuf == 0) else 0 # ternary # bbufs[deck][track][chL/R+2*curbuf] #~ itrack = 0 # for now # if the two bufs exist for track 0, presumably the ones for the other track also exist in the PD patch? #~ tvL = pyext.Buffer(self.bbufs[self.deckid0][itrack][2*otherbuf]) #~ tvR = pyext.Buffer(self.bbufs[self.deckid0][itrack][2*otherbuf+1]) # now going with all - make track "v?" buffers array, per-track: tvbs = ((pyext.Buffer(self.bbufs[self.deckid0][0][2 * otherbuf]), pyext.Buffer(self.bbufs[self.deckid0][0][2 * otherbuf + 1])), (pyext.Buffer(self.bbufs[self.deckid0][1][2 * otherbuf]), pyext.Buffer(self.bbufs[self.deckid0][1][2 * otherbuf + 1]))) #~ if ( (tvL) and (tvR) ): if ((tvbs[0][0]) and (tvbs[0][1]) and (tvbs[1][0]) and (tvbs[1][1])): # much less clicks if we off-render into ctvL, ctvR first - and then assing tvL, tvR in one go ctvL = np.zeros(self.seqLoopLenSmpsI, dtype=np.float32) ctvR = np.zeros(self.seqLoopLenSmpsI, dtype=np.float32) #, dtype=np.float32 totarglen = len(cargs) alllaneslist = [] last_delim = 0 for key, value in enumerate(cargs): if (value == "|"): # split off part here - use Python list splicing: if 2nd val is 4, then last included index is 3 lanepart = cargs[last_delim: key] #{unpack(atoms, last_delim, key-1)} alllaneslist.append(lanepart) last_delim = key + 1 # this condition should always be satisfied due to the way Python .joins, but still: if (last_delim < totarglen): alllaneslist.append(cargs[last_delim:totarglen]) #self.wprint(alllaneslist) # [(<Symbol 00v>, 0, 0, 0, 0, ... # now loop through alllaneslist, separate per tracks (since different algos) pertracklist = [[], []] for key, tlanelist in enumerate(alllaneslist): tlabel = tlanelist[0] tlchars = list(tlabel) # split string to chars foundsndbufs = 0 #self.wprint((tlabel, tlchars)) trckind = int(tlchars[0]) # make 0-based, no +1 here tlind = int(tlchars[1]) if trckind == 0: sndtabnameL = "snd%d-%d-%dL" % ( self.deckid1, trckind + 1, tlind + 1 ) # names are 1-based sndtabnameR = "snd%d-%d-%dR" % (self.deckid1, trckind + 1, tlind + 1) else: # trckind==1 (track 2): all same samples, but pitched sndtabnameL = "snd%d-2-1L" % (self.deckid1) sndtabnameR = "snd%d-2-1R" % (self.deckid1) sbL = pyext.Buffer(sndtabnameL) # note: if(sbL) check passes always, and has the right ('symbol', <Symbol snd1-2-1L>) property # only check for existence is len(sbL): 0; PD will allow you to set a table to len 0, but it will auto re-set it to 1 - so "real" len 0 is impossible if (len(sbL) == 0): sbL = None else: foundsndbufs = foundsndbufs + 1 # sbR = pyext.Buffer(sndtabnameR) if (len(sbR) == 0): sbR = None else: foundsndbufs = foundsndbufs + 1 #if key == len(alllaneslist)-1: # #self.wprint(inspect.getmembers(sbL)) # nothing much # self.wprint("sbl len: {0}".format(len(sbL))) # nothing much # throw in tlchars, so we don't have to parse again; also find the sample buffers and add them pertracklist[trckind].append( (tlchars, tlanelist, foundsndbufs, (sbL, sbR))) #self.wprint(pprint.pformat(pertracklist)) # do render: track 1 (itrack = 0) for itrack in (0, 1): laststeplanevelos = [] # reference for track 2 "pitched"-resized buffers of the sample (create on demand); unused for track 1 tr2pbs = [None] * self.nNotes # [None, None, None, None, None] for i in xrange(0, self.nSteps): # 0-15 lanevelos = [] for tnote, tlanearr in enumerate( pertracklist[itrack]): # track 1 if (tlanearr[2] == 2): # foundsndbufs ovel = tlanearr[1][ 2 + i] # origvelo at this step; skip label and zero w [2+i] trig = 1 if (ovel >= 2) else 0 # working ternary nvel = ovel - 2 * trig # if trig==1, start copying from sample buffer at 0; else continue from previous! soffs = -1 if (trig == 1): soffs = 0 # note started elif ((nvel > 0)): # note continues if len( laststeplanevelos ) > 0 and laststeplanevelos[tnote][1][2] > -1: soffs = laststeplanevelos[tnote][1][ 2] + self.seq16thLenSmpsI # 0-based offset! if (soffs > (len(tlanearr[3][0]) - 1)): soffs = -1 # offset bigger than sample length # end # if trig # NOTE: python .insert does NOT insert empty elements in list if they don't exist: z=[]; z.insert(3, -2) is [-2]! (so we might as well use append here) #~ lanevelos.insert( tnote, (trig, nvel, soffs)) # at position tnote lanevelos.append( (tnote, (trig, nvel, soffs))) # save position tnote #end # if foundsndbufs #end # for tnote, tlanearr # now do this snippet's sample mixing # (none of this sample by sample: ... """ outind = -1 for j in xrange(0,self.seq16thLenSmpsI): mixvalL, mixvalR = 0, 0 for tnote, tinfarr in enumerate(lanevelos): if tinfarr[2]>-1: # soffs smpind = tinfarr[2]+j if smpind < len(pertracklist[0][tnote][3][0]): # one (sbL) check only: sbL and sbR should have same lengths # note: vectorize this operation; leaving as reminder only mixvalL = mixvalL + tinfarr[1]*pertracklist[0][tnote][3][0][smpind] # sbL mixvalR = mixvalR + tinfarr[1]*pertracklist[0][tnote][3][1][smpind] # sbR #end # if smpind< #end # if tinfarr[3]>-1 # soffs #end # for tnote, tinfarr outind = i*self.seq16thLenSmpsI+j # ****** #tvL:set(outind, mixvalL) #tvR:set(outind, mixvalR) #end # for j = 1,self.seq16thLenSmpsI """ # ... vectorize instead for sample mixing): tmpbL = np.zeros( self.seq16thLenSmpsI) # length of self.seq16thLenSmpsI tmpbR = np.zeros(self.seq16thLenSmpsI) # NB: i is still numstep here; for tind, tinfarrfull in enumerate(lanevelos): #~ print(tinfarrfull) # tnote = tinfarrfull[0] tinfarr = tinfarrfull[1] if tinfarr[2] > -1: # soffs sbL = pertracklist[itrack][tnote][3][0] sbR = pertracklist[itrack][tnote][3][ 1] # should work for both itrack 0 and 1, in terms of direct sample buffers """ if itrack == 1: # actually, don't pre-shift; some samples may be "insanely" long, pointless for them to wait to be pitched; instead, just find the right indexes for the stretched slice - and then stretch only the slice!? if (tr2pbs[tnote] is None): # do "pitching" - resize with linear interpolation stretch # tuck into tuple directly - a bit difficult to read: tr2pbs[tnote] = ( \ np.interp(np.linspace(0,(len(sbL)-1)*self.pifs[tnote],len(sbL)*self.pifs[tnote])*(1.0/self.pifs[tnote]), np.linspace(0,len(sbL)-1,len(sbL)), sbL, left=0, right=0), \ np.interp(np.linspace(0,(len(sbR)-1)*self.pifs[tnote],len(sbR)*self.pifs[tnote])*(1.0/self.pifs[tnote]), np.linspace(0,len(sbR)-1,len(sbR)), sbR, left=0, right=0) \ ) sbL = tr2pbs[tnote][0]; sbR = tr2pbs[tnote][1] # end # if itrack == 1: """ sbLc = sbL sbRc = sbR # without fade in/out #~ sbLc = np.hstack((sbL[:self.sFdIn.size]*self.sFdIn, sbL[self.sFdIn.size:-self.sFdOut.size], sbL[-self.sFdOut.size:]*self.sFdOut)) ; sbRc = np.hstack((sbR[:self.sFdIn.size]*self.sFdIn, sbR[self.sFdIn.size:-self.sFdOut.size], sbR[-self.sFdOut.size:]*self.sFdOut)) # with fade in/out - but for the entire sample buffer; while we need these when the sequence is cut! sbLsz = len(sbLc) sbRsz = len(sbRc) # was len(sbL), len(sbR) sampind1 = tinfarr[2] sampind2 = tinfarr[2] + self.seq16thLenSmpsI # here sz because the slicing will do -1 sampind2L = sbLsz if ( sampind2 > sbLsz) else sampind2 sampind2R = sbRsz if ( sampind2 > sbRsz) else sampind2 #self.wprint(" tL {0} tR {0} sL {1} sR {2}".format(len(tmpbL), len(tmpbR), sampind2L-sampind1, sampind2R-sampind1)) # older numpy (1.5.1) doesn't have .pad ; so to avoid messing: # reinstantiate new zero temps, and slice the existing into them: slcL = np.zeros(self.seq16thLenSmpsI) slcR = np.zeros(self.seq16thLenSmpsI) tsbLc = sbLc[sampind1:sampind2L] tsbRc = sbRc[sampind1:sampind2R] if itrack == 1: # 16th slice-wise pitching: pf = self.pifs[tnote] si1p, si2Lp, si2Rp, s16p = int( sampind1 / pf), int(sampind2L / pf), int( sampind2R / pf), int( self.seq16thLenSmpsI / pf) # these take still too much time (more than with previous approach with pitched prerender)? (plus pitch was opposite when mult *pf); even if it should interpolate a slice only, it looks like it walks/stretches the entire source array, thereby consuming time? #~ tsbLc = np.interp( np.linspace(si1p, si2Lp, sampind2L-sampind1), np.linspace(0,len(sbLc)-1,len(sbLc)), sbLc, left=0, right=0 ) ; tsbRc = np.interp( np.linspace(si1p, si2Rp, sampind2R-sampind1), np.linspace(0,len(sbRc)-1,len(sbRc)), sbRc, left=0, right=0 ) # try here to slice before interpolating - but using pitched indexes for the extracted ranges: """ # later - more accurate? ttLc = np.zeros(s16p) ; ttRc = np.zeros(s16p) print(ttLc.shape, si1p, si2Lp, si2Lp-si1p, s16p) # buffer has no shape (sbLc.shape); shape mismatch if si2Lp-si1p=7535, and s16p=7534 ttLc[0:(si2Lp-si1p)] = sbLc[si1p:si2Lp] #; ttRc[0:(si2Rp-si1p)] = sbRc[si1p:si2Rp] # indices auto cast to integer? but gives "TypeError: sequence index must be integer, not 'slice'" -- which is fixed by int(); so must be explicitly int """ # this "simple slice-only interpolation" also works (for some reason - can't see now how the indexes match) - generally well actually (except for bass, can hear some chops at 16th notes when its long) - but eventually probably better to make something like above, to also better handle edge cases ttLc = sbLc[si1p:si2Lp] ttRc = sbRc[si1p:si2Rp] LttLc = len(ttLc) LttRc = len(ttRc) # also sbLsz, sbRsz tsbLc = np.interp( np.linspace(0, si2Lp - si1p, sampind2L - sampind1), np.linspace(0, LttLc - 1, LttLc), ttLc, left=0, right=0) tsbRc = np.interp( np.linspace(0, si2Rp - si1p, sampind2R - sampind1), np.linspace(0, LttRc - 1, LttRc), ttRc, left=0, right=0) # end # if itrack == 1: slcL[0:(sampind2L - sampind1)] = tsbLc slcR[0:(sampind2R - sampind1)] = tsbRc # was: sbL[], sbR[] # check fade out: nextvelo = pertracklist[0][tnote][1][i + 1] if ( i < self.nSteps - 1) else 0 if nextvelo == 0: slcL = np.hstack( (slcL[:-self.sFdOut.size], slcL[-self.sFdOut.size:] * self.sFdOut)) slcR = np.hstack( (slcR[:-self.sFdOut.size], slcR[-self.sFdOut.size:] * self.sFdOut)) # final mix with fader factor: tmpbL += tinfarr[1] * slcL tmpbR += tinfarr[1] * slcR # end for tnote #self.wprint(" pre") tvind1 = i * self.seq16thLenSmpsI tvind2 = (i + 1) * self.seq16thLenSmpsI # MUST cast explicitly to dtype=N.float32 when going to pyext.Buffer; else segfault! ctvL[tvind1: tvind2] = tmpbL[:] #np.array(tmpbL, dtype=np.float32) ctvR[tvind1: tvind2] = tmpbR[:] #np.array(tmpbR, dtype=np.float32) #self.wprint(" tvL,R {0} {1} {2}".format(tvind1, tvind2, tvind2-tvind1)) laststeplanevelos = lanevelos # ends: [(0, 0, -1), (0, 0, -1)] 106680 113791 (same as lua) #self.wprint("{0} {1}".format(laststeplanevelos, i*self.seq16thLenSmpsI) )# , outind) ) #end # for i = 1,self.nSteps # if "(no explicit assignment occurred); # must mark buffer content as dirty to update graph" # but here we do have explicit assignment - so dirty are not needed #tvL.dirty() ; tvR.dirty() tvL = tvbs[itrack][0] tvR = tvbs[itrack][1] tvL[:] = np.array(ctvL, dtype=np.float32) tvR[:] = np.array(ctvR, dtype=np.float32) #end # for itrack in (0,): # just before finishing, prepare messages for wav saving; # command for [soundfiler] - to which the send symbol # (rimage00, rimage10) for the rwav in Gripd is added #~ thisdir = os.path.dirname(os.path.realpath(__file__)) + os.sep # full path thisdir = "" # this works too, current dir # NOTE: -bytes 4 will use 32-bit float (it is not specifically for stereo)! # use -bytes 2 for 16-bit wav! (which can be correctly rendered by `wav2png` used by Gripd's image) msg1 = "write -wave -bytes 2 %sd%d-t1-bb%d.wav %s %s rimage0%d" % ( thisdir, self.deckid0, otherbuf, self.bbufs[self.deckid0][0][2 * otherbuf], self.bbufs[self.deckid0][0][2 * otherbuf + 1], self.deckid0) msg2 = "write -wave -bytes 2 %sd%d-t2-bb%d.wav %s %s rimage1%d" % ( thisdir, self.deckid0, otherbuf, self.bbufs[self.deckid0][1][2 * otherbuf], self.bbufs[self.deckid0][1][2 * otherbuf + 1], self.deckid0) sendname = "rwavsvc%d" % (self.deckid0) self._send( sendname, msg1 ) # like this it is symbol, use [fromsymbol] to work w unpack/[soundfiler]! self._send(sendname, msg2) # self.curbuf = otherbuf # set other buf as current self._outlet(1, self.curbuf) else: # couldn't get tvL, tvR - now (tvbs[0][0]) .. print( " SAR:processSequenceList: Couldn't get garrays {0}, {1}, {2}, {3}" .format(self.bbufs[self.deckid0][0][2 * otherbuf], self.bbufs[self.deckid0][0][2 * otherbuf + 1], self.bbufs[self.deckid0][1][2 * otherbuf], self.bbufs[self.deckid0][1][2 * otherbuf + 1]))
def run_1(self, gin_file, in_arr, out_arr, f0_octave_shift=0, f0_confidence_threshold=0.0, loudness_db_shift=0.0, in_sample_rate=44100, out_sample_rate=16000, adjust=True, quiet=20.0, autotune=0.0): if not self._proc: raise Exception("no ddsp_worker process is running") # get buffers in_buf = pyext.Buffer(in_arr) out_buf = pyext.Buffer(out_arr) in_audio = np.array(in_buf, dtype=np.float32) print_err("in_audio.size =", in_audio.size) print_err("in_audio.itemsize =", in_audio.itemsize) # make timbre transfer message gin_path = os.path.join(script_dir, str(gin_file)) ckpt_dir = os.path.dirname(gin_path) ckpt_msg = protocol.to_str_msg(ckpt_dir) print_err("len(ckpt_msg) = ", len(ckpt_msg)) transfer_msg = protocol.to_timbre_transfer_msg( in_sample_rate, out_sample_rate, f0_octave_shift, f0_confidence_threshold, loudness_db_shift, bool(adjust), quiet, autotune, len(ckpt_msg), in_audio.size * in_audio.itemsize) print_err("len(transfer_msg) = ", len(transfer_msg)) in_audio_msg = protocol.to_audio_msg(in_audio) print_err("len(in_audio_msg) = ", len(in_audio_msg)) # write timbre transfer message self._write_msg(protocol.IN_TAG_TIMBRE_TRANSFER, transfer_msg, ckpt_msg, in_audio_msg) print_err("wrote") # read timbre transferred message self._read_tag(protocol.OUT_TAG_TIMBRE_TRANSFERRED) print_err("read") transferred_msg = self._proc.stdout.read( protocol.timbre_transferred_struct.size) print_err("len(transferred_msg) =", len(transferred_msg)) out_audio_len = protocol.from_timbre_transferred_msg(transferred_msg) print_err("out_audio_len =", out_audio_len) out_audio_msg = self._proc.stdout.read(out_audio_len) print_err("len(out_audio_msg)", len(out_audio_msg)) out_audio = protocol.from_audio_msg(out_audio_msg) # resize output buffer if needed if len(out_audio) != len(out_buf): print_err("resizing") out_buf.resize(len(out_audio)) print_err("resized") else: print_err("no resize") # write output out_buf[:] = normalize(out_audio) print_err("wrote out_audio") out_buf.dirty() self._outlet(1, ["transferred", len(out_audio)])
def generate_1(self, *raw_args): if not self._proc: raise Exception("no samplernn_worker process is running") args = self._generate_parser.parse_args(map(str, raw_args)) print_err("args =", args) outs = args.out if args.out != None else [] temps = args.temp if args.temp != None else [] num_outs = len(outs) if num_outs < 1: print_err("no outputs specified") while len(temps) < num_outs: temps.append(temps[-1]) if args.seed != None: seed_buf = pyext.Buffer(args.seed) seed_audio = np.array(seed_buf, dtype=np.float32) else: seed_audio = np.array([], dtype=np.float32) print_err("seed_audio size*itemsize =", seed_audio.size * seed_audio.itemsize) seed_len = seed_audio.size * seed_audio.itemsize generate_msg = protocol.to_generate_msg(args.seed_sr, args.out_sr, num_outs, args.dur, seed_len) seed_audio_msg = protocol.to_audio_msg(seed_audio) temp_msgs = map(protocol.to_str_msg, temps) temp_msgs = map(lambda bs: (protocol.to_size_msg(len(bs)), bs), temp_msgs) temp_msgs = (x for pair in temp_msgs for x in pair) self._write_msg(protocol.IN_TAG_GENERATE, generate_msg, seed_audio_msg, *temp_msgs) print_err("wrote") self._read_tag(protocol.OUT_TAG_GENERATED) generated_msg = self._proc.stdout.read(protocol.generated_struct.size) g_out_sr, g_num_outs, g_out_len = protocol.from_generated_msg(generated_msg) print_err("g_out_sr =", g_out_sr) print_err("g_num_outs =", g_num_outs) print_err("g_out_len =", g_out_len) out_audios = [] for i in range(g_num_outs): out_audio_msg = self._proc.stdout.read(g_out_len * protocol.f32_struct.size) out_audios.append(protocol.from_audio_msg(out_audio_msg)) print_err("len(out_audios) =", len(out_audios)) assert len(outs) == len(out_audios) for buf_name, audio in zip(outs, out_audios): buf = pyext.Buffer(buf_name) if len(buf) != len(audio): buf.resize(len(audio)) buf[:] = audio buf.dirty() self._outlet(1, ["generated", buf_name, g_out_sr, g_out_len])
def _read_edits(self): if not self._steps: return self._steps[self._step_ix]["edits"][:] = pyext.Buffer(self._edits_buf_name)