SamplerBox icon indicating copy to clipboard operation
SamplerBox copied to clipboard

Use sounddevice with nickyspride.nl version

Open remisarrailh opened this issue 9 years ago • 1 comments

If you want to use sounddevice instead of pyaudio with nickyspride.nl version

replace pyaudio with sounddevice

import sounddevice

Change in AudioCallback

#########################################
# AUDIO CALLBACK
#########################################

def AudioCallback(outdata, frame_count, time_info, status):
    global playingsounds, SampleLoading
    global BackingRunning
    global BackWav, BackIndex, ClickWav, ClickIndex
    global globalvolume, backvolume, clickvolume
    rmlist = []
    # print "sounds: " +str(len(playingsounds)) + " notes: " + str(len(playingnotes)) + " sust: " + str(len(sustainplayingnotes))
    playingsounds = playingsounds[-MAX_POLYPHONY:]
    b = samplerbox_audio.mixaudiobuffers(playingsounds, rmlist, frame_count, FADEOUT, FADEOUTLENGTH, SPEED)

    for e in rmlist:
        try:
            playingsounds.remove(e)
        except:
            pass

    # b *= globalvolume

    if USE_FREEVERB:
        b_temp = b
        freeverbprocess(b_temp.ctypes.data_as(c_float_p), b.ctypes.data_as(c_float_p), frame_count)

    # IF USE_TONECONTOL
    #   b = numpy.array(chain.filter(bb))
    #   b=bb

    if CHANNELS == 4:  # 4 channel playback
        # if backingtrack running: add in the audio
        if BackingRunning:
            BackData = BackWav[BackIndex:BackIndex+2*frame_count]
            ClickData = ClickWav[ClickIndex:ClickIndex+2*frame_count]
            BackIndex += 2*frame_count
            ClickIndex += 2*frame_count
            if len(b) != len(BackData) or len(b) != len(ClickData):
                BackingRunning = False
                BackData = None
                BackIndex = 0
                ClickData = None
                ClickIndex = 0

        if BackingRunning:
            newdata = (backvolume * BackData + b * globalvolume)
            Click = ClickData * clickvolume
        else:
            Click = numpy.zeros(frame_count*2, dtype=numpy.float32)
            newdata = b * globalvolume

        #  putting streams in 4 channel audio by magic in numpy reshape
        a1 = newdata.reshape(frame_count, 2)
        a2 = Click.reshape(frame_count, 2)
        ch4 = numpy.hstack((a1, a2)).reshape(1, frame_count*4)

        # Mute while loading Sample or BackingTrack
        # otherwise there could be dirty hick-ups
        if SampleLoading or (BackLoadingPerc > 0 and BackLoadingPerc < 100):
            ch4 *= 0
        return (ch4.astype(numpy.int16).tostring(), pyaudio.paContinue)

    else:  # 2 Channel playback
        # if backingtrack running: add in the audio
        if BackingRunning:
            BackData = BackWav[BackIndex:BackIndex+2*frame_count]
            BackIndex += 2*frame_count
            if len(b) != len(BackData):
                BackingRunning = False
                BackData = None
                BackIndex = 0

        if BackingRunning:
            newdata = (backvolume * BackData + b * globalvolume)
        else:
            newdata = b * globalvolume

    outdata[:] = newdata.reshape(outdata.shape)

Change in MAIN CODE

try:
    sd = sounddevice.OutputStream(device=AUDIO_DEVICE_ID, blocksize=512, samplerate=48000, channels=CHANNELS, dtype='int16', callback=AudioCallback)
    sd.start()
#    stream = p.open(format=pyaudio.paInt16, channels=CHANNELS, rate=48000, frames_per_buffer=BUFFERSIZE, output=True,
#                    output_device_index=AUDIO_DEVICE_ID, stream_callback=AudioCallback)

remisarrailh avatar Sep 05 '16 14:09 remisarrailh

Link to testing branch which contains sounddevice replacing pyaudio: https://github.com/josephernest/SamplerBox/tree/testing

josephernest avatar Sep 05 '16 15:09 josephernest

I close this one since sounddevice is now the default used module.

josephernest avatar Aug 08 '22 19:08 josephernest