2017-02-28 10 views
0

사운드 파일을 프레임으로 분할하여 프레임의 특정 사운드 주파수를 자세하게 설명하는 numpy 배열로 변환 할 수있는 방법을 아는 사람이 있습니까?사운드 파일에서 프레임 가져 오기

예를 들어 cv2를 사용하면 필름 클립을 프레임으로 분할하여 이미지 라이브러리로 저장할 수 있습니다. 이 코드는 작업을 멋지게 처리합니다. 나중에 각 이미지의 색상 막대 그래프를 쉽게 얻을 수 있습니다.

filepath1 = input('Please enter the filepath for where the frames should be saved: ') 

name = input('Please enter the name of the clip: ') 

ret, frame = clip.read() 
count = 0 
ret == True 
while ret: 
    ret, frame = clip.read() 
    cv2.imwrite(os.path.join(filepath1,name+'%d.png'%count), frame) 
    count += 1 

그러나 나는 소리 파일에 대해 똑같이 똑같은 것을 찾을 수 없습니다. 누구든지 어떻게 할 수 있는지에 대한 제안이 있습니까?

+0

그냥 확실하게 - 당신은 ** ** 오른쪽 사운드 파일에서 이미지의 시퀀스를 생성하고 싶지 않아? – kazemakase

+0

예, 예. 왜냐하면 사운드 파일에서 일련의 이미지를 찾는다면 여기에 게시 된 것보다 훨씬 큰 문제가 있기 때문입니다. 필자는 비유로만 필름 예제를 사용합니다. 나는 사운드 파일을 필름 프레임과 동등하게 원한다. – Lodore66

답변

1

엄밀히 말하면, 영화 프레임과 동일한 사운드 파일은 오디오 샘플입니다. 이는 채널 당 하나의 값일 뿐이므로 원하는 것이 맞는지 확실하지 않습니다. 내가 성취하고자하는 바를 가장 잘 추측하는 것은 시간이 지남에 따라 파일의 주파수 내용이 어떻게 변하는 지 분석하는 것입니다.

아마도 spectrogram을보고 싶으십니까? 이 경우 www.frank-zalkow.de에서 가져온 다음 스크립트는 원하는 것을 정확하게 수행하거나 시작하는 방법에 대한 아이디어를 줄 수 있습니다. enter image description here

#!/usr/bin/env python 
#coding: utf-8 
""" This work is licensed under a Creative Commons Attribution 3.0 Unported License. 
    Frank Zalkow, 2012-2013 """ 

import numpy as np 
from matplotlib import pyplot as plt 
import scipy.io.wavfile as wav 
from numpy.lib import stride_tricks 

""" short time fourier transform of audio signal """ 
def stft(sig, frameSize, overlapFac=0.5, window=np.hanning): 
    win = window(frameSize) 
    hopSize = int(frameSize - np.floor(overlapFac * frameSize)) 

    # zeros at beginning (thus center of 1st window should be for sample nr. 0) 
    samples = np.append(np.zeros(np.floor(frameSize/2.0)), sig)  
    # cols for windowing 
    cols = np.ceil((len(samples) - frameSize)/float(hopSize)) + 1 
    # zeros at end (thus samples can be fully covered by frames) 
    samples = np.append(samples, np.zeros(frameSize)) 

    frames = stride_tricks.as_strided(samples, shape=(cols, frameSize), strides=(samples.strides[0]*hopSize, samples.strides[0])).copy() 
    frames *= win 

    return np.fft.rfft(frames)  

""" scale frequency axis logarithmically """  
def logscale_spec(spec, sr=44100, factor=20.): 
    timebins, freqbins = np.shape(spec) 

    scale = np.linspace(0, 1, freqbins) ** factor 
    scale *= (freqbins-1)/max(scale) 
    scale = np.unique(np.round(scale)) 

    # create spectrogram with new freq bins 
    newspec = np.complex128(np.zeros([timebins, len(scale)])) 
    for i in range(0, len(scale)): 
     if i == len(scale)-1: 
      newspec[:,i] = np.sum(spec[:,scale[i]:], axis=1) 
     else:   
      newspec[:,i] = np.sum(spec[:,scale[i]:scale[i+1]], axis=1) 

    # list center freq of bins 
    allfreqs = np.abs(np.fft.fftfreq(freqbins*2, 1./sr)[:freqbins+1]) 
    freqs = [] 
    for i in range(0, len(scale)): 
     if i == len(scale)-1: 
      freqs += [np.mean(allfreqs[scale[i]:])] 
     else: 
      freqs += [np.mean(allfreqs[scale[i]:scale[i+1]])] 

    return newspec, freqs 

""" plot spectrogram""" 
def plotstft(audiopath, binsize=2**10, plotpath=None, colormap="jet"): 
    samplerate, samples = wav.read(audiopath) 
    s = stft(samples, binsize) 

    sshow, freq = logscale_spec(s, factor=1.0, sr=samplerate) 
    ims = 20.*np.log10(np.abs(sshow)/10e-6) # amplitude to decibel 

    timebins, freqbins = np.shape(ims) 

    plt.figure(figsize=(15, 7.5)) 
    plt.imshow(np.transpose(ims), origin="lower", aspect="auto", cmap=colormap, interpolation="none") 
    plt.colorbar() 

    plt.xlabel("time (s)") 
    plt.ylabel("frequency (hz)") 
    plt.xlim([0, timebins-1]) 
    plt.ylim([0, freqbins]) 

    xlocs = np.float32(np.linspace(0, timebins-1, 5)) 
    plt.xticks(xlocs, ["%.02f" % l for l in ((xlocs*len(samples)/timebins)+(0.5*binsize))/samplerate]) 
    ylocs = np.int16(np.round(np.linspace(0, freqbins-1, 10))) 
    plt.yticks(ylocs, ["%.02f" % freq[i] for i in ylocs]) 

    if plotpath: 
     plt.savefig(plotpath, bbox_inches="tight") 
    else: 
     plt.show() 

    plt.clf() 

plotstft("my_audio_file.wav") 
+1

그러나 스펙트로 그램은 더 긴 오디오 녹음에 대해서만 의미가 있지만 단일 시간 색인에는 적합하지 않습니다. OP가 아마도 대신 원하는 것은 각 프레임에 대해 짧은 길이의 오디오를 추출하고 FFT를 수행하여 프레임에서 결과로 나타나는 주파수 스펙트럼을 제공하는 것입니다. 그런 다음 스펙트럼을 플롯하거나 파일에 저장할 수 있습니다. 이 [블로그 게시물] (http://www.cbcity.de/die-fft-mit-python-einfach-erklaert)은이 작업에 필요한 대부분의 것을 설명합니다 (독일어의 첫 번째 단락은 신경 쓰지 마십시오). – Schmuddi

+1

@Schmuddi 맞습니다. * 각 프레임에 대해 짧은 스트레치의 오디오를 추출하고 FFT를 수행하면 해당 프레임에서 최종 주파수 스펙트럼을 얻을 수 있습니다. * 스펙트로 그램에서 정확히 무슨 일이 일어나는지. 기본적으로 결과 이미지의 각 열은 오디오의 "스트레치"의 FFT/PSD입니다. – kazemakase

+0

감사합니다 여러분; 이 모든 대답은 유용하며 두 가지 모두 내가 관심있는 일을 수행하는 소중한 (그리고 보완적인) 방법을 제공합니다. 이제는 그들과 함께 일하는 것이 가장 좋습니다! – Lodore66