Python으로 사운드 파일을 재생하는 방법을 가르치고 음성 간격에 따라 사운드를 조각으로 자릅니다.

실생활에는 많은 소리 신호가 있으며 오늘날의 정보 폭발 사회에서는 유용한 소리 신호를 추출하는 것이 매우 중요합니다. 소리 신호를 수집 할 때 필요한 소리 정보를 추출하기 위해 분석을 위해이 소리의 각 문장을 분리해야하는 경우가 있습니다. 큰 부분의 소리를 효과적으로 자르는 방법이 있습니다.

먼저 필요한 리소스 라이브러리 패키지를 가져와야합니다.

리소스 라이브러리 가져 오기

사운드 파일 pip install soundfile
여기에 사진 설명 삽입
다운로드 : 다운로드 재시도 :pip install retry
여기에 사진 설명 삽입

소리의 파형을 관찰하기 위해 오디오 파일 읽기

import matplotlib.pyplot as plt
import soundfile as sf

musicFileName = '8_Channel_ID.wav'
sig, sample_rate = sf.read(musicFileName)
print("采样率:%d" % sample_rate)
print("时长:", sig.shape[0]/sample_rate, '秒')

# 声音有两个通道
serviceData = sig.T[0]
clientData = sig.T[1]

plt.rcParams['figure.figsize'] = (20, 5) # 设置figure_size尺寸
plt.figure()
l=sig.shape[0]
x = [i/8000 for i in range(l)]
plt.plot(x, serviceData, c='b')
plt.show()

취해진 사운드 정보 : 사운드
여기에 사진 설명 삽입
의 파형 :
여기에 사진 설명 삽입

세 가지 매개 변수의 정의

사실 사운드 파일을 읽은 후에는 벡터가됩니다. 실제로는 벡터의 처리입니다. 음파 형이 변동하고 각 문장 사이에 일정한 간격이 있고, 여전히 사운드 간격에 일정량의 노이즈가 있음을 알 수 있습니다. . 절단을 완료하기 위해 세 가지 매개 변수가 설정됩니다.

  1. voiceMinValue: 최소 음량,이 값 미만은 소음으로 판단
  2. voiceMaxDistanceSecond: 두 문장 사이의 시간 간격을 늘립니다.이 값보다 크면 두 문장으로 간주하고, 그렇지 않으면 한 문장으로 간주합니다.
  3. voiceMinSecond: 단일 오디오의 최소 시간 길이입니다.이 값보다 작 으면 노이즈로 간주됩니다.

클래스의 초기 값

위의 세 가지 매개 변수와 오디오 파일 이름 및 파일 출력 경로는 클래스의 초기 값을 구성합니다.

class Voicesplit(object):
    def __init__(self, musicFileName, outFilePath):
        # 音频文件名称
        self.musicFileName = musicFileName
        # 文件输出路径
        self.outFilePath = outFilePath
        # 最小音量
        self.voiceMinValue = 0.01
        # 两句话之间最大时间间隔(秒)
        self.voiceMaxDistanceSecond = 0.1
        # 单个音频最小时间长度(秒)
        self.voiceMinSecond = 0.1

사운드 커팅을 위해 다음 세 가지 주요 매개 변수를 사용하십시오.

# 分割声音,分段保存
    def splitVoiceAndSave(self):
        sig, self.sample_rate = sf.read(self.musicFileName)
        print('正在读取文件:%s' % musicFileName)
        print("采样率:%d" % self.sample_rate)
        print("时长:%s" % (sig.shape[0] / self.sample_rate), '秒')

        # 我的音频文件有两个通道,这里读取第一个通道,你需要根据你的音频文件是否是双通道,进行修改
        inputData = sig.T[0]

        dd = {
    
    }
        for k, v in tqdm(enumerate(inputData)):
            if abs(v) < self.voiceMinValue:
                dd[k] = 0
            else:
                dd[k] = v

        x = [i / self.sample_rate for i in range(len(inputData))]
        y = list(dd.values())

        # 删除空白部分
        for key in list(dd):
            if dd[key] == 0:
                dd.pop(key)

        # 判断声音间隔
        voiceSignalTime = list(dd.keys())
        list1 = []
        list2 = []
        for k, v in enumerate(voiceSignalTime[:-2]):
            list2.append(v)
            if voiceSignalTime[k + 1] - v > self.voiceMaxDistanceSecond * self.sample_rate:
                list1.append(list2)
                list2 = []

        if len(list1) == 0:
            list1.append(list2)

        if len(list1) > 0 and (
                voiceSignalTime[-1] - voiceSignalTime[-2]) < self.voiceMaxDistanceSecond * self.sample_rate:
            list1[-1].append(voiceSignalTime[-2])

        voiceTimeList = [x for x in list1 if len(x) > self.voiceMinSecond * self.sample_rate]
        print('分解出声音片段:', len(voiceTimeList))

        for voiceTime in voiceTimeList:
            voiceTime1 = int(max(0, voiceTime[0] - 0.8 * self.sample_rate))
            voiceTime2 = int(min(sig.shape[0], voiceTime[-1] + 0.8 * self.sample_rate))
            self.wavWriteByTime(musicFileName=self.musicFileName, outData=inputData, voiceTime1=voiceTime1, voiceTime2=voiceTime2)

잘라낸 사운드 클립 저장

# wav文件写入,分时间间隔
def wavWriteByTime(self, musicFileName, outData, voiceTime1, voiceTime2):
    outData = outData[voiceTime1:voiceTime2]
    fileAbsoluteName = os.path.splitext(os.path.split(musicFileName)[-1])[0]
    fileSavePath = os.path.join(self.outFilePath, fileAbsoluteName)

    if not os.path.exists(fileSavePath):
        os.makedirs(fileSavePath)

    outfile = os.path.join(fileSavePath,os.path.splitext(os.path.split(musicFileName)[-1])[0] + '_%d_%d_%s_split.wav' % (voiceTime1, voiceTime2, self.sample_rate))


    # 判断文件是否存在
    if not os.path.exists(outfile):
        print('正在生成文件:', outfile)
        with wave.open(outfile, 'wb') as outwave:  # 定义存储路径以及文件名
            nchannels = 1
            sampwidth = 2
            fs = 8000
            data_size = len(outData)
            framerate = int(fs)
            nframes = data_size
            comptype = "NONE"
            compname = "not compressed"
            outwave.setparams((nchannels, sampwidth, framerate, nframes, comptype, compname))
            for v in outData:
                outwave.writeframes(struct.pack('h', int(v * 64000 / 2)))

사운드 분할 결과

내 사운드 파일의 최종 사운드 세그먼트는 1입니다. 특정 사운드 파일은 자신의 정보에 따라 얻을 수 있습니다.
여기에 사진 설명 삽입
여기에 사진 설명 삽입

추천

출처blog.csdn.net/ywsydwsbn/article/details/107699470