Search code examples
pythonwavelooperpyaudio

Recording and playing byte list in pyaudio/wave


I want to record and play my voice using pyaudio and wave lib but I don't know how to do it because wave lib requires a path to a file and even if I'm trying to set it as a variable with list of bytes recorded a few second ago, still doesn't work beacuse I can't use 'read' for a list. Does someone have some idea? I want to make a looper like KORG stuff, etc

I want to play it immediately after stopped recording, like real looper, without saving record as file.

There is my code (Python 3.4):

def record(self): #recording a voice

    #var for bytes from recording
    self.stream = self.player.open(format = self.FORMAT,
            channels = self.CHANNELS,
            rate = self.RATE,
            input = True,
            frames_per_buffer = self.CHUNK)

    print("Recording")

    self.frames = [] #byte list

    #recoring for a few seconds (5sec at this moment)
    for i in range(0, int(self.RATE / self.CHUNK * self.RECORD_SECONDS)):
        self.data = self.stream.read(self.CHUNK) #sing stream do data var
        self.frames.append(self.data) #add bytes to the end of a list
    print("Stop recording")

    self.stopRecording()

def stopRecording(self):

    self.stream.stop_stream()
    self.stream.close()
    print("Recording has been stopped")

    self.play()

def play(self): #playing a record
    print("Playing")


    f = wave.open(self.frames,"rb")  
    #read data  
    data = f.readframes(CHUNK)  

    #play stream  
    while data != '':  
        self.stream.write(data)  
        data = f.readframes(CHUNK)  

    self.stopPlaying()

Solution

  • After stop your record you need join your appended data, use data = ''.join(self.frames), and at the end build a loop (for, while) to stream all your byte list, here is how i did:

    import pyaudio
    
    chunk = 1024
    FORMAT = pyaudio.paInt16
    CHANNELS = 1
    RATE = 41000
    RECORD_SECONDS = 5
    
    
    p = pyaudio.PyAudio()
    
    stream = p.open(format = FORMAT,
        channels = CHANNELS,
        rate = RATE,
        input = True,
        output = True,
        frames_per_buffer = chunk)
    
    
    
    print ("***Recording***")
    
    all = [] 
    
    for i in range(0, RATE / chunk * RECORD_SECONDS):
         data = stream.read(chunk)
         all.append(data) 
    
    
    print("***Stop recording***")
    
    
    print ("***START PLAY***")
    
    
    data = ''.join(all)
    
    
    for i in range(0, len(data), chunk):
        stream.write(data[i:i+chunk])