Skip to main content

基于 libsndfile、CFFI 和 NumPy 的音频库

项目描述

版本 Python 地位 执照

贡献者 下载

soundfile模块是一个基于 libsndfile、CFFI 和 NumPy 的音频库完整的文档可在https://python-soundfile.readthedocs.io/上找到。

soundfile模块可以读写声音文件通过libsndfile支持文件读/写,这是一个免费的跨平台开源 (LGPL) 库,用于读取和写入许多不同的采样声音文件格式,可在包括 Windows、OS X 和 Unix 在内的许多平台上运行。它通过 CFFI访问,CFFI是 Python 调用 C 代码的外部函数接口。CPython 2.6+、3.x 和 PyPy 2.0+ 支持 CFFI。soundfile模块将音频数据表示为 NumPy 数组。

python-soundfile 已获得 BSD 许可(BSD 3-Clause License)。
(c) 2013 年,巴斯蒂安·贝希托德

开放式问题 封闭问题 公开档案 封闭式prs

重大变化

soundfile模块在最近的几个版本中发展迅速最值得注意的是,我们在 0.7 中将导入名称从import pysoundfile更改为 import soundfile 。在 0.6 中,我们清理了许多小的不一致之处,特别是在函数参数的排序和命名以及索引接口的删除方面。

在 0.8.0 中,我们将always_2d的默认值从True 更改为False。此外,write函数的参数顺序从write(data, file, ...)更改为write(file, data, ...)

在 0.9.0 中,我们使用 Numpy dtype表示法将buffer_ * 方法的ctype参数更改为 dtype 。旧的 ctype参数仍然有效,但现在已正式弃用。

安装

soundfile模块依赖于 Python 包 CFFI 和 NumPy,以及系统库 libsndfile

在现代 Python 中,您可以使用pip install soundfile下载并安装最新版本的soundfile模块及其依赖项。在 Windows 和 OS X 上,这也将安装库 libsndfile。在 Linux 上,您需要使用发行版的包管理器安装 libsndfile,例如sudo apt-get install libsndfile1

如果您在不寻常的平台上运行,或者您使用的是旧版本的 Python,则可能需要分别安装 NumPy 和 CFFI,例如使用Anaconda包管理器或用于 Python 扩展包的非官方 Windows 二进制文件

错误报告

在 API 使用错误的情况下,声音文件模块会引发通常的ValueErrorTypeError

对于其他错误,会引发SoundFileError(以前是RuntimeError)。特别是,libsndfile 库报告的错误会引发此异常的LibsndfileError子类。在这种情况下,异常对象在 LibsndfileError.code 属性中提供 libsndfile 内部错误代码,并在LibsndfileError.error_string属性中提供原始 libsndfile 错误消息。

读/写函数

可以使用soundfile.write()将数据写入文件,或使用soundfile.read ()从文件中读取数据。soundfile模块可以打开libsndfile 支持的所有文件格式,例如 WAV、FLAC、OGG 和 MAT 文件(请参阅下面关于编写 OGG 文件的已知问题)。

下面是一个读取波形文件并将其复制到 FLAC 文件中的程序示例:

import soundfile as sf

data, samplerate = sf.read('existing_file.wav')
sf.write('new_file.flac', data, samplerate)

块处理

声音文件也可以简短地读取,可选择与soundfile.blocks()重叠块。例如,这会计算长文件的每个块的信号电平:

import numpy as np
import soundfile as sf

rms = [np.sqrt(np.mean(block**2)) for block in
       sf.blocks('myfile.wav', blocksize=1024, overlap=512)]

声音文件对象

声音文件也可以作为SoundFile对象打开。每个 SoundFile都有特定的采样率、数据格式和一组通道数。

如果打开文件,只要SoundFile 对象存在,它就会保持打开状态。当对象被垃圾回收时文件关闭,但您应该使用SoundFile.close()方法或上下文管理器显式关闭文件:

import soundfile as sf

with sf.SoundFile('myfile.wav', 'r+') as f:
    while f.tell() < f.frames:
        pos = f.tell()
        data = f.read(1024)
        f.seek(pos)
        f.write(data*2)

所有数据访问都使用帧作为索引。一帧是声音文件中的一个离散时间步长。每帧包含与文件中的通道一样多的样本。

原始文件

soundfile.read()通常可以自动检测声音文件的文件类型。但是,这对于 RAW 文件是不可能的:

import soundfile as sf

data, samplerate = sf.read('myfile.raw', channels=1, samplerate=44100,
                           subtype='FLOAT')

请注意,在 x86 上,这默认为endian='LITTLE'。如果您正在读取大端数据(主要是旧的基于 PowerPC/6800 的文件),则必须相应地设置endian='BIG'

您可以以类似的方式编写 RAW 文件,但请注意,在大多数情况下,更具表现力的格式会更好,应改为使用。

虚拟 IO

如果你有一个打开的类文件对象,soundfile.read()可以像普通文件一样打开它:

import soundfile as sf
with open('filename.flac', 'rb') as f:
    data, samplerate = sf.read(f)

下面是一个使用 HTTP 请求的示例:

import io
import soundfile as sf
from urllib.request import urlopen

url = "http://tinyurl.com/shepard-risset"
data, samplerate = sf.read(io.BytesIO(urlopen(url).read()))

请注意,上面的示例仅适用于 Python 3.x。对于 Python 2.x 支持,将第三行替换为:

from urllib2 import urlopen

已知的问题

写入 OGG 文件可能会导致具有某些版本的 libsndfile 的空文件。有关此问题的新闻,请参见#130

如果使用 Buildroot 风格的系统,Python 无法定位libsndfile.so文件,这会导致无法加载 python-soundfile。这显然是python中的一个错误。目前,在soundfile.py中,您可以删除对 _find_library 的调用,并在_ffi.dlopen中硬编码 libsndfile.so 的位置。有关此问题的讨论,请参见#258

消息

2013-08-27 V0.1.0 巴斯蒂安 Bechtold:

初始原型。Python 中 libsndfile 的简单包装器

2013-08-30 V0.2.0 巴斯蒂安 Bechtold:

错误修复和与 PySoundCard 的更多一致性

2013-08-30 V0.2.1 巴斯蒂安 Bechtold:

Bug修复

2013-09-27 V0.3.0 巴斯蒂安 Bechtold:

添加了适用于 Windows 的二进制安装程序和上下文管理器

2013-11-06 V0.3.1 巴斯蒂安 Bechtold:

从 distutils 切换到 setuptools 以便于安装

2013-11-29 V0.4.0 巴斯蒂安 Bechtold:

感谢 David Blewett,现在有了虚拟 IO!

2013-12-08 V0.4.1 巴斯蒂安 Bechtold:

感谢 Xidorn Quan,FLAC 文件不再是 float32。

2014-02-26 V0.5.0 巴斯蒂安 Bechtold:

感谢 Matthias Geier,改进了 seek 和 flush() 方法。

2015-01-19 V0.6.0 巴斯蒂安·贝希托德:

非常非常感谢 Matthias Geier,他完成了大部分工作!

  • 切换到float64作为默认数据类型。

  • 为保持一致性而更改了函数参数。

  • 添加了单元测试。

  • 添加了全局read()write()blocks()便利功能。

  • readthedocs 上的文档大修和托管。

  • 添加了“x”打开模式。

  • 添加了tell()方法。

  • 添加了 __repr__()方法。

2015-04-12 V0.7.0 巴斯蒂安 Bechtold:

再次感谢 Matthias Geier 的辛勤工作,也感谢 Nils Werner 和 Whistler7 的许多建议和帮助。

  • 将 import pysoundfile重命名为import soundfile

  • 通过包含 OS X 和 Windows 所需库的 pip 轮进行安装。

  • 删除了write()的Exclusive_creation参数。

  • 添加了 truncate()方法。

2015-10-20 V0.8.0 巴斯蒂安 Bechtold:

再一次,Matthias Geier 为这个版本做出了很多努力。

  • 将always_2d的默认值从True更改为 False

  • Numpy 现在是可选的,并且只为readwrite加载。

  • 添加了 SoundFile.buffer_read()SoundFile.buffer_read_into()SoundFile.buffer_write(),它们在不涉及 Numpy 的情况下读取/写入原始数据。

  • 添加了返回声音文件元数据的info()函数。

  • 将write()函数 的参数顺序从write(data, file, ...)更改为write(file, data, ...)

还有更多小错误修复。

2017-02-02 V0.9.0 巴斯蒂安·贝希托德:

感谢 Matthias Geier、Tomas Garcia 和 Todd 为本版本做出的贡献。

  • 添加对 ALAC 文件的支持。

  • 添加新成员__libsndfile_version__

  • 将帧数添加到信息

  • dtype参数添加到buffer_*方法

  • 弃用buffer_*方法的ctype参数

  • 添加对 Python 3.6 的官方支持

以及一些小错误修复。

2017-11-12 V0.10.0 巴斯蒂安 Bechtold:

感谢 Matthias Geier、Toni Barth、Jon Peirce、Till Hoffmann 和 Tomas Garcia 为本版本做出的贡献。

  • 现在应该与 cx_freeze 一起使用。

  • 自述文件中的几个文档修复。

  • 删除不推荐使用的ctype参数以支持buffer_*()中的dtype

  • 添加SoundFile.frames以支持现已弃用的__len__()

  • 提高blocks()SoundFile.blocks()的性能。

  • 通过使用 CFFI 的离线模式来缩短导入时间。

  • 添加用于构建发行版的构建脚本。

2022-06-02 V0.11.0 巴斯蒂安 Bechtold:

谢谢你,tennies,Hannes Helmholz,Christoph Boeddeker,Matt Vollrath,Matthias Geier,Jacek Konieczny,Boris Verkhovskiy,Jonas Haag,Eduardo Moguillansky,Panos Laganakos,Jarvy Jarvison,Domingo Ramirez,Tim Chagnon,Kyle Benesch,Fabian-Robert Stöter,Joe托德

  • MP3 支持

  • 为 macOS M1 添加二进制轮子

  • 提高了与 macOS 的兼容性,特别是针对 M1 机器

  • 修复了在 Windows 和 Python 3.5+ 上为二进制轮子打开的文件描述符

  • 将 libsndfile 更新到 v1.1.0

  • 添加用于一次检索所有元数据的 get_strings 方法

  • 改进文档、错误消息和测试

  • 显示样本中非常短文件的长度

  • 支持文件系统路径协议(pathlib et al)

下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

内置发行版

soundfile-0.11.0-py2.py3-none-win_amd64.whl (1.0 MB 查看哈希

已上传 py2 py3

soundfile-0.11.0-py2.py3-none-win32.whl (886.9 kB 查看哈希

已上传 py2 py3

soundfile-0.11.0-py2.py3-none-any.whl (23.4 kB 查看哈希

已上传 py2 py3