如何让 python 加载一个大(2小时)的波形文件并将其内容转换为时频数组?
我想用 array[5000][440] 之类的东西访问数组,意思是从开始起 5000ms,频率为 440hz,它会给我这个位置的频率幅度值。
我在这里找不到类似的东西,如果有的话,请指点我。
I would like to access the array with something like array[5000][440] meaning 5000ms from the start and 440hz and it would give me a value of the frequency's amplitude at this very position.
I could not find something like that here, if there is, please point me to it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您基本上需要一个频谱图。首先,将声音文件分成小块,例如,每个块是 1/10 秒,然后对每个块进行 FFT。 (当然,要查找 5000ms 和 440Hz,请转到相应块的 FFT。)
You basically want a spectrogram. To get you started, go through your sound file in small chunks, where each chunk is, say, 1/10th of a second, and FFT each of these chunks. (Then, of course, to look up 5000ms and 440Hz, go to the FFT of the appropriate chunk.)
您的操作存在一些误解。
您无法获得特定时间点的波频率。您需要选择一个时间窗口,包括兴趣点之前和之后的许多点。包含的点越多,频率细分的分辨率就越高。您需要在这些点上运行某种加窗函数,然后对它们进行 FFT。
一旦获得 FFT 的结果,数字将对应于频率,但它不会是一个简单的关系。您无法控制每个输出对应的频率,该频率已经由信号的采样频率与样本数相结合确定。恐怕我手头没有转换公式。每个频率都有两个分量:实部和虚部,幅度为
sqrt(r**2+i**2)
。You're operating under a couple of misconceptions.
You can't get the frequency of a wave at a particular point in time. You need to select a window of time, including many points before and after the point of interest. The more points you include, the more resolution you'll have in your frequency breakdown. You'll need to run some sort of windowing function on those points, then subject them to a FFT.
Once you have the results of the FFT, the numbers will correspond to frequencies but it won't be a simple relationship. You don't have any control over the frequency corresponding to each output, that was already determined by the sampling frequency of your signal combined with the number of samples. I'm afraid I don't have the conversion formula at hand. Each frequency will have two components, a real and an imaginary, and the amplitude will be
sqrt(r**2+i**2)
.您可以即时转换时间和频率。您必须使用 __getitem__ 以及可能的 lru_cache 来存储一些值以供进一步使用。
假设傅里叶是这样的,
您可以应用相同的方法来从傅里叶访问时间。因此,您可以创建新的时间对象,使您能够选择任何有效时间并返回该时间,或者使用某种插值来返回表中没有的值。
如果您无法将所有值存储在内存中,您可以使用标准库中的
shelve
模块来存储和访问磁盘中的项目,如果需要,您可以在其上应用接口和插值。You can convert times and frequencies on fly. You have to use
__getitem__
and probablylru_cache
to store some values for further usage.Let say that fourier is something like this
You can apply same thing for accessing time from Fourier. So you can create new time object that enables you picking any valid time and returns that time or use some kind of interpolation to return values that are not in table.
If you will not be able to store all values in ram, you can use
shelve
module from standard library to store and acess items from disk and you can apply interface whit interpolation on it if required.