def get_cqt(audio): audio = essentia.array(audio) w = Windowing(type = 'hann') cqt = [] dcs =[] nys =[] CQStand = standard.NSGConstantQ(**kwargs) for frame in FrameGenerator(audio, frameSize=4096, hopSize=2048, startFromZero=True): cqt_frame, dc_frame, ny_frame = CQStand(w(frame)) h_size = cqt_frame.shape[1] cqt.append(cqt_frame.T) dcs.append(dc_frame) nys.append(ny_frame) return np.vstack(cqt), dcs, nys, h_size
def nsgcqgram(audio, frameSize=8192, transitionSize=1024, minFrequency=65.41, maxFrequency=6000, binsPerOctave=48, sampleRate=44100, rasterize='full', phaseMode='global', gamma=0, normalize='none', window='hannnsgcq'): """Frame-wise invertible Constant-Q analysis. This code replicates the Sli-CQ algorithm from [1]. A Tukey window is used to perform a zero-phased, zero-padded, half-overlapped frame-wise analysis with the `NSGConstantQ` algorithm. References: [1] Velasco, G. A., Holighaus, N., Dörfler, M., & Grill, T. (2011). "Constructing an invertible constant-Q transform with non-stationary Gabor frames". Proceedings of DAFX11, Paris, 93-99. Args: audio (vector): If it is empty, an exception is raised. Returns: (list of 2D complex arrays): Time/frequency complex matrices representing the NSGCQ `constantq` coefficients for each `frameSize // 2` samples jump. (list of complex vectors): Complex vectors representing the NSGCQ `constantqdc` coefficients for each `frameSize // 2` samples jump. (list of complex vectors): Complex vectors representing the NSGCQ `constantqnf` coefficients for each `frameSize // 2` samples jump. """ hopSize = frameSize // 2 halfTransitionSize = transitionSize // 2 NSGCQ = es.NSGConstantQ(inputSize=frameSize, minFrequency=minFrequency, maxFrequency=maxFrequency, binsPerOctave=binsPerOctave, sampleRate=sampleRate, rasterize=rasterize, phaseMode=phaseMode, gamma=gamma, normalize=normalize, window=window, minimumWindow=8) w = es.Windowing(type='hannnsgcq', normalized=False, zeroPhase=False)( np.ones(transitionSize * 2).astype('float32')) window = np.hstack([ w[-transitionSize:], np.ones(hopSize - transitionSize), w[:transitionSize] ]) # Indexes for the windowing process. evenWin = np.hstack([ np.arange(frameSize - halfTransitionSize, frameSize), np.arange(hopSize + halfTransitionSize) ]) oddWin = np.hstack([ np.arange(hopSize - halfTransitionSize, frameSize), np.arange(halfTransitionSize) ]) h0 = np.arange(-halfTransitionSize, hopSize + halfTransitionSize) # Zero-pad the signal for an integer number of frames. zeroPad = (frameSize - window.size) // 2 frameNum = int(np.ceil(audio.size / hopSize)) x = np.hstack([audio, np.zeros(hopSize * frameNum - audio.size + hopSize) ]).astype('float32') frames = np.zeros([frameNum, frameSize], dtype='float32') # Mirror-pad for the first frame. frames[0][evenWin] = np.hstack([ -x[halfTransitionSize - 1::-1], x[:hopSize + halfTransitionSize] ]) * window # Slice audio. for kk in range(2, frameNum, 2): frames[kk][evenWin] = x[(kk - 1) * hopSize + h0] * window for kk in range(1, frameNum, 2): frames[kk][oddWin] = x[(kk - 1) * hopSize + h0] * window # Compute the transform. cqShift, dcShift, nfShift = [], [], [] for i in range(frameNum): cqFrame, dcFrame, nfFrame = NSGCQ(frames[i]) cqShift.append(cqFrame) dcShift.append(dcFrame) nfShift.append(nfFrame) cqSize = cqFrame.shape[1] dcSize = dcFrame.size nfSize = nfFrame.size # Center the frames for a better display. cqShiftEven = np.hstack( [np.arange(cqSize // 4, cqSize), np.arange(0, cqSize // 4)]) dcShiftEven = np.hstack( [np.arange(dcSize // 4, dcSize), np.arange(0, dcSize // 4)]) nfShiftEven = np.hstack( [np.arange(nfSize // 4, nfSize), np.arange(0, nfSize // 4)]) cqShiftOdd = np.hstack( [np.arange(3 * cqSize // 4, cqSize), np.arange(0, 3 * cqSize // 4)]) dcShiftOdd = np.hstack( [np.arange(3 * dcSize // 4, dcSize), np.arange(0, 3 * dcSize // 4)]) nfShiftOdd = np.hstack( [np.arange(3 * nfSize // 4, nfSize), np.arange(0, 3 * nfSize // 4)]) cq = [ cqShift[i][:, cqShiftEven] if i % 2 else cqShift[i][:, cqShiftOdd] for i in range(len(cqShift)) ] dc = [ dcShift[i][dcShiftEven] if i % 2 else dcShift[i][dcShiftOdd] for i in range(len(dcShift)) ] nf = [ nfShift[i][nfShiftEven] if i % 2 else nfShift[i][nfShiftOdd] for i in range(len(nfShift)) ] return cq, dc, nf