转换wav - > mp3 - > wav会产生静态噪音

时间:2017-07-09 09:50:58

标签: python python-3.x audio pyaudio pydub

我正在尝试将麦克风音频转换为mp3文件,然后将其保存在磁盘上,以便录制和保存音轨。

但要以pyaudio的方式播放,我需要将其转换为wav格式 它最初记录在wav中,我正在尝试wav -> mp3 -> wav

我已经将我的代码的最小调试版本放在一起,它看起来如下:

import pyaudio
from array import array
from struct import pack
from sys import byteorder
from io import BytesIO
from pydub import AudioSegment

p = pyaudio.PyAudio()
stream_mic = p.open(rate=11000,
                        format=pyaudio.paInt16,
                        channels=1,
                        input=True,
                        frames_per_buffer=500)

stream_out = p.open(rate=11000,
                        format=pyaudio.paInt16,
                        channels=1,
                        output=True,
                        frames_per_buffer=500)

def is_odd(a):
    return bool(a - ((a>>1)<<1))

def wav_obj(raw_data):
    wavHandle = AudioSegment(data=raw_data, sample_width=2, frame_rate=11000, channels=1)
    return wavHandle

def wavToMp3(audioFrame):
    mp3 = BytesIO()
    file_handle = audioFrame.export(mp3, format="mp3")
    mp3.seek(0)
    data = mp3.read()
    ## == Data needs to be multiple of (sample_width * channels)
    ##    Easiest way is to strip of a trailing data, 
    while is_odd(len(data)):
        data = data[:-1]
    return AudioSegment(data=data, sample_width=2, frame_rate=11000, channels=1)

def mp3ToWav(audioFrame):
    #remasteredAudioFrame = audioFrame.set_frame_rate(11000)
    wav = BytesIO()
    file_handle = audioFrame.export(wav, format="wav")
    wav.seek(0)
    return AudioSegment(data=wav.read(), sample_width=2, frame_rate=11000, channels=1)

while 1:
    snd_data = array('h', stream_mic.read(500))
    if byteorder == 'big':
        snd_data.byteswap()

    frame = array('h')
    frame.extend(snd_data)

    wav = wav_obj(frame)

    ## == convert from .wav -> .mp3 -> .wav
    ##    just to see the loss of audio.
    mp3 = wavToMp3(wav)
    wav = mp3ToWav(mp3)

    stream_out.write(wav.raw_data)

stream_out.stop_stream()
stream_mic.stop_stream()
stream_out.close()
stream_mic.close()
p.terminate()

这会产生一种可怕的静电,这是一种100%的音频损失 起初我认为这是data[:-1]的剪辑,但至少对我来说似乎不是问题。

其次我认为帧速率可能会关闭,所以我尝试set_frame_rate(11000),但这也不起作用。

评论这两行:

mp3 = wavToMp3(wav)
wav = mp3ToWav(mp3)

使播放声音“美观”。没有数据丢失,质量正如我所定义的那样。

我不能因为我的爱而弄清楚我在哪里混合数据压缩 注意:如果可能的话,我想在内存中执行此操作,因为我稍后会处理数据以尝试创建效果等。

进度

正如@Anthon指出的那样,我应该逐个隔离转换,看看哪两个失败了。我通过将wav -> mp3保存到磁盘来实现此目的。

started = time()
sound = AudioSegment(data=b'', sample_width=2, frame_rate=11000, channels=1)
while 1:
    snd_data = array('h', stream_mic.read(500))
    if byteorder == 'big':
        snd_data.byteswap()

    frame = array('h')
    frame.extend(snd_data)

    wav = wav_obj(frame)

    ## == convert from .wav -> .mp3 -> .wav
    ##    just to see the loss of audio.
    mp3 = wavToMp3(wav)
    sound = sound + mp3
    #wav = mp3ToWav(mp3)

    #stream_out.write(mp3.raw_data)
    if time() - started > 1.5:
        break

print(sound.raw_data)
with open('test.mp3', 'wb') as fh:
    fh.write(sound.raw_data)

然后我将test.mp3猛烈地抨击大胆,看看形成的波形是什么样的 果然它看起来像是.mp3转换那是不可能的。

它看起来像肉眼,好像音频帧被拖出并单独扭曲。声音总共应该大约1.5秒,但是看一下波形,压缩器增加了每帧的暂停和延迟:

enter image description here

所以我在使用此值的所有实例上将值frames_per_buffer=500提升为2000

stream_mic = p.open(frames_per_buffer=5000, ...)
stream_out = p.open(frames_per_buffer=5000, ...)
stream_mic.read(5000)

高于1.5 seconds的任何值都应该是一个足够好的价值 果然,波形看起来完全不同:

enter image description here

似乎有效的是:

wav = wav_obj(frame)
sound = sound + wav

sound.export("test.mp3",
              format="mp3",
              bitrate="11k",
              tags={"album": "test", "artist": "Not Ariana Grande"})

所以有些方法,wav frame -> mp3 frame -> combine several mp3 frames不起作用 但是wav frame -> combine several wav frames -> export to mp3可以正常工作。

这是我再次陷入困境的地方 显然,mp3转换是不稳定的,而且有些方法会在每个段的波形中增加失真间距。
我希望你们这里的某个人能够使用pydub,尤其是mp3转换,因为我很失落。

这是mp3:s聚集的地方:

0 个答案:

没有答案
相关问题