错误:未知格式:3(尝试读取音频 wavfile 时) [英] Error: unknown format: 3 (When trying to read audio wavfile)

查看:33
本文介绍了错误:未知格式:3(尝试读取音频 wavfile 时)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用下面显示的以下功能来清理和缩减音频采样.我陷入了这个我缺乏理解的错误中.有人愿意解释并希望帮助我解决这个问题吗?

I am trying to clean and downsample my audio using the following functions displayed below. I get thrown into this error which I lack understanding of. Would anyone care to explain and hopefully help me resolve this issue?

我可以看到它与 wavio 功能有关,并且无法读取文件.

I can see that it has to do with wavio function and it fails to read the file.

代码如下:

def envelope(y, rate, threshold):
    mask = []
    y = pd.Series(y).apply(np.abs)
    y_mean = y.rolling(window=int(rate/20),
                       min_periods=1,
                       center=True).max()
    for mean in y_mean:
        if mean > threshold:
            mask.append(True)
        else:
            mask.append(False)
    return mask, y_mean


def downsample_mono(path, sr):
    obj = wavio.read(path)
    wav = obj.data.astype(np.float32, order='F')
    rate = obj.rate
    try:
        tmp = wav.shape[1]
        wav = to_mono(wav.T)
    except:
        pass
    wav = resample(wav, rate, sr)
    wav = wav.astype(np.int16)
    return sr, wav


def save_sample(sample, rate, target_dir, fn, ix):
    fn = fn.split('.wav')[0]
    dst_path = os.path.join(target_dir.split('.')[0], fn+'_{}.wav'.format(str(ix)))
    if os.path.exists(dst_path):
        return
    wavfile.write(dst_path, rate, sample)


def check_dir(path):
    if os.path.exists(path) is False:
        os.mkdir(path)


def split_wavs(args):
    src_root = args.src_root
    dst_root = args.dst_root
    dt = args.delta_time

    wav_paths = glob('{}/**'.format(src_root), recursive=True)
    wav_paths = [x for x in wav_paths if '.wav' in x]
    dirs = os.listdir(src_root)
    check_dir(dst_root)
    classes = os.listdir(src_root)
    for _cls in classes:
        target_dir = os.path.join(dst_root, _cls)
        check_dir(target_dir)
        src_dir = os.path.join(src_root, _cls)
        for fn in tqdm(os.listdir(src_dir)):
            src_fn = os.path.join(src_dir, fn)
            rate, wav = downsample_mono(src_fn, args.sr)
            mask, y_mean = envelope(wav, rate, threshold=args.threshold)
            wav = wav[mask]
            delta_sample = int(dt*rate)

            # cleaned audio is less than a single sample
            # pad with zeros to delta_sample size
            if wav.shape[0] < delta_sample:
                sample = np.zeros(shape=(delta_sample,), dtype=np.int16)
                sample[:wav.shape[0]] = wav
                save_sample(sample, rate, target_dir, fn, 0)
            # step through audio and save every delta_sample
            # discard the ending audio if it is too short
            else:
                trunc = wav.shape[0] % delta_sample
                for cnt, i in enumerate(np.arange(0, wav.shape[0]-trunc, delta_sample)):
                    start = int(i)
                    stop = int(i + delta_sample)
                    sample = wav[start:stop]
                    save_sample(sample, rate, target_dir, fn, cnt)


def test_threshold(args):
    src_root = args.src_root
    wav_paths = glob('{}/**'.format(src_root), recursive=True)
    wav_path = [x for x in wav_paths if args.fn in x]
    if len(wav_path) != 1:
        print('audio file not found for sub-string: {}'.format(args.fn))
        return
    rate, wav = downsample_mono(wav_path[0], args.sr)
    mask, env = envelope(wav, rate, threshold=args.threshold)
    plt.style.use('ggplot')
    plt.title('Signal Envelope, Threshold = {}'.format(str(args.threshold)))
    plt.plot(wav[np.logical_not(mask)], color='r', label='remove')
    plt.plot(wav[mask], color='c', label='keep')
    plt.plot(env, color='m', label='envelope')
    plt.grid(False)
    plt.legend(loc='best')
    plt.show()

if __name__ == '__main__':

    parser = argparse.ArgumentParser(description='Cleaning audio data')
    parser.add_argument('--src_root', type=str, default='Audio Data/Ordered Files',
                        help='directory of audio files in total duration')
    parser.add_argument('--dst_root', type=str, default='Audio Data/Clean Audio',
                        help='directory to put audio files split by delta_time')
    parser.add_argument('--delta_time', '-dt', type=float, default=2.0,
                        help='time in seconds to sample audio')
    parser.add_argument('--sr', type=int, default=44100,
                        help='rate to downsample audio')

    parser.add_argument('--fn', type=str, default='HBJQWAO',
                        help='file to plot over time to check magnitude')
    parser.add_argument('--threshold', type=str, default=20,
                        help='threshold magnitude for np.int16 dtype')
    args, _ = parser.parse_known_args()

    test_threshold(args)
    #split_wavs(args)

错误:

Error                                     Traceback (most recent call last)
<ipython-input-16-97e9b68095c0> in <module>()
     17     args, _ = parser.parse_known_args()
     18 
---> 19     test_threshold(args)
     20     #split_wavs(args)

6 frames
<ipython-input-14-fe4eeabe5e06> in test_threshold(args)
     85         print('audio file not found for sub-string: {}'.format(args.fn))
     86         return
---> 87     rate, wav = downsample_mono(wav_path[0], args.sr)
     88     mask, env = envelope(wav, rate, threshold=args.threshold)
     89     plt.style.use('ggplot')

<ipython-input-14-fe4eeabe5e06> in downsample_mono(path, sr)
     14 
     15 def downsample_mono(path, sr):
---> 16     obj = wavio.read(path)
     17     wav = obj.data.astype(np.float32, order='F')
     18     rate = obj.rate

/usr/local/lib/python3.6/dist-packages/wavio.py in read(file)
    166     with values that have been sign-extended.
    167     """
--> 168     wav = _wave.open(file)
    169     rate = wav.getframerate()
    170     nchannels = wav.getnchannels()

/usr/lib/python3.6/wave.py in open(f, mode)
    497             mode = 'rb'
    498     if mode in ('r', 'rb'):
--> 499         return Wave_read(f)
    500     elif mode in ('w', 'wb'):
    501         return Wave_write(f)

/usr/lib/python3.6/wave.py in __init__(self, f)
    161         # else, assume it is an open file object already
    162         try:
--> 163             self.initfp(f)
    164         except:
    165             if self._i_opened_the_file:

/usr/lib/python3.6/wave.py in initfp(self, file)
    141             chunkname = chunk.getname()
    142             if chunkname == b'fmt ':
--> 143                 self._read_fmt_chunk(chunk)
    144                 self._fmt_chunk_read = 1
    145             elif chunkname == b'data':

/usr/lib/python3.6/wave.py in _read_fmt_chunk(self, chunk)
    258             self._sampwidth = (sampwidth + 7) // 8
    259         else:
--> 260             raise Error('unknown format: %r' % (wFormatTag,))
    261         self._framesize = self._nchannels * self._sampwidth
    262         self._comptype = 'NONE'

Error: unknown format: 3

推荐答案

检查波头,例如soxi 你会发现WAVE不是用int16写的格式,但 float.我怎么知道?这段代码读取wFormatTag代码>标签.在您的情况下,异常返回代码 3,即 FLOAT (参考).

Check the wave header with e.g. soxi and you will find that the WAVE was not written with int16 format, but float. How do I know that? This code reads the wFormatTag tag. In your case the exception returned with code 3 which is FLOAT (reference).

一种选择是使用 pySoundFile 并指定 float 作为数据格式.

One option would be to use pySoundFile and specify float as the data format.

import soundfile as sf
data, samplerate = sf.read('file.wav', dtype='float32')

这篇关于错误:未知格式:3(尝试读取音频 wavfile 时)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆