From: jweigele Date: Sun, 2 Oct 2022 20:22:43 +0000 (-0700) Subject: Revamp the sample mix to allow for postprocessing on the sample buffer X-Git-Url: http://git.hexthepla.net/?a=commitdiff_plain;ds=sidebyside;p=grahbot Revamp the sample mix to allow for postprocessing on the sample buffer --- diff --git a/ffmpegfile.py b/ffmpegfile.py index cbe2724..2e5db49 100644 --- a/ffmpegfile.py +++ b/ffmpegfile.py @@ -127,6 +127,71 @@ class AudioBuffer(discord.AudioSource): retval = AudioChunk(b'') return retval + + def get_sample_chunks(self, buffer_samples): + index = 0 + + next_samples = buffer_samples[:,index:index+MAX_SAMPLES] + while next_samples.size > 0: + chunk = AudioChunk(init_samples=next_samples) + yield chunk + #log.debug(chunk, chunk.samples) + # get next chunk + index += MAX_SAMPLES + next_samples = buffer_samples[:,index:index+MAX_SAMPLES] + + def mix_new_data(self, new_data): + try: + locked = False + buffer_index = 0 + # init the buffer + buffer_array = numpy.zeros(shape=(2,0), dtype='float32') + # breaks out when we have a buffer array that's >= the data we want to mix + log.debug('Constructing buffer_array') + while buffer_array.size < new_data.size: + # no more valid samples, create one for mixing + if buffer_index >= len(self.samples): + buffer_append = AudioChunk(init_bytes=b'') + else: + buffer_append = self.samples[buffer_index] + # append to the current array of data + # maybe does too much data churn but we'll see + buffer_array = numpy.concatenate((buffer_array, buffer_append.samples), axis=1) + buffer_index += 1 + # if we need to pad out the input to match + if buffer_array.size != new_data.size: + samples_to_add = buffer_array.size - new_data.size + new_data = numpy.concatenate((new_data, numpy.repeat(numpy.zeros(shape=(2,1)), samples_to_add//2, axis=1)), axis=1) + # actually mix the two buffers now + buffer_array = buffer_array + new_data + log.debug('Reprocessing here') + # would reprocess here + board = pedalboard.Pedalboard([ + pedalboard.Gain(gain_db=-3.0) + ]) + buffer_array = board(buffer_array, SAMPLE_RATE) + + + log.debug('Replacing samples with mixed') + locked = self.sample_lock.acquire() + for index, chunk in enumerate(self.get_sample_chunks(buffer_array)): + # either append if we've run out of runway, or replace if we have old samples + if index == len(self.samples): + self.samples.append(chunk) + else: + self.samples[index] = chunk + + log.debug('Done sample mix') + except Exception as e: + #log.debug('sample size is {} sample_index is {}'.format(self.sample_size, sample_index)) + traceback.print_exc() + finally: + if locked: + #log.debug('min deck size: {}'.format(min_deck_size)) + log.debug('releasing lock now') + self.sample_lock.release() + + # get the number of samples in the deck back up to DECK_SIZE def fill_deck(self): # block if you got nothin @@ -153,7 +218,6 @@ class AudioBuffer(discord.AudioSource): async def process_file(self, filename): #rand_str = str(hex(random.randint(0, 10000))) #fifo_path = '/tmp/fifo{}'.format(rand_str) - locked = False try: min_deck_size = self.DECK_SIZE chunks_to_append = [] @@ -184,50 +248,20 @@ class AudioBuffer(discord.AudioSource): shift_tones = random.randint(-10, 10) board = pedalboard.Pedalboard([ pedalboard.PitchShift(semitones=shift_tones), - pedalboard.Gain(gain_db=-3.0) ]) buffer_samples = board(buffer_samples, SAMPLE_RATE) - index = 0 - - next_samples = buffer_samples[:,index:index+MAX_SAMPLES] - while next_samples.size > 0: - chunk = AudioChunk(init_samples=next_samples) - #log.debug(chunk, chunk.samples) - chunks_to_append.append(chunk) - # get next chunk - index += MAX_SAMPLES - next_samples = buffer_samples[:,index:index+MAX_SAMPLES] - # chunk append/insertion (along with mixing) - # this is the part that actually needs locked access - locked = self.sample_lock.acquire() - sample_index = 0 log.debug('starting the chunk append now') - for chunk in chunks_to_append: - if self.deck_size < min_deck_size: - min_deck_size = self.deck_size - - if self.sample_size == sample_index:# or True: - #log.debug('appending chunk {} {}'.format(chunk, chunk.samples)) - self.samples.append(chunk) - # replace - else: - #log.debug('mixing chunk {}'.format(chunk)) - self.samples[sample_index] = self.samples[sample_index].mix_stream(chunk) - sample_index +=1 - log.debug('finished chunk append final sample_index {} sample_size {}'.format(sample_index, self.sample_size)) + self.mix_new_data(buffer_samples) + #log.debug('finished chunk append final sample_index {} sample_size {}'.format(sample_index, self.sample_size)) + log.debug('finished chunk append final') except Exception as e: #log.debug('sample size is {} sample_index is {}'.format(self.sample_size, sample_index)) traceback.print_exc() - finally: - if locked: - log.debug('min deck size: {}'.format(min_deck_size)) - self.sample_lock.release() - #os.unlink(fifo_path) def print_buffer(self): for sample in self.samples: