Python:峰值内外的奇怪行为(在Audioread.Audio_open中的ValueError原因)
我正在尝试调查上下文管理器中迭代器的奇怪行为的原因。我在这里缺少一些东西,也许您可以解释。
没有任何变化,相同的迭代对象,但是如果出于某种原因出现在CM之外,则迭代停止工作。
最小代码样本: (需要在项目文件夹中的“ af_path”上的mp3文件,然后在项目文件夹中运行ffmpeg二进制文件)
import inspect
from collections.abc import Iterable
def ar_preloader(af_path):
"""creates audioread object"""
import audioread.ffdec
# !!! ffmpeg binary backend must exist in the project folder
with audioread.audio_open(af_path) as m:
test = m
print(type(test), inspect.isgenerator(test), isinstance(test, Iterable))
print(next(iter(test)), 1111)
# print(next(iter(test)), 2222)
# print(type(test), inspect.isgenerator(test), isinstance(test, Iterable))
,然后如果您在上下文管理器中注释2个打印语句,而在外面进行了不计入的最后两个语句,则您将获得停止的异常。
import inspect
from collections.abc import Iterable
def ar_preloader(af_path):
"""creates audioread object"""
import audioread.ffdec
# !!! ffmpeg binary backend must exist in the project folder
with audioread.audio_open(af_path) as m:
test = m
# print(type(test), inspect.isgenerator(test), isinstance(test, Iterable))
# print(next(iter(test)), 1111)
print(next(iter(test)), 2222)
print(type(test), inspect.isgenerator(test), isinstance(test, Iterable))
尽管它仍然是一个具有相同且相同的Audioread对象(test.CHANNELS,test.mamplator,test.Duration属性仍然可以使用)。
更奇怪的是,如果您同时离开... 1111和... 2222陈述,它将像应有的那样起作用,即下一个(...)内部的下一个(...)给出1帧,第二个(外部)给出第二帧和第二帧和因此,即现在可以迭代迭代。但是,无论如何我都不能首先遗漏。
当我试图在天秤座模块中调试错误时,我遇到了这个问题。它的文档仅描述Audioread上下文管理器方法,但我想创建一个函数,该函数加载了现有的Audioread对象,即不按路径进行。
def l_analysis_o(afo):
import librosa
lo = librosa.load(afo)
# each librosa object is a tuple, (y=array, sr=sampling rate)
l_analysis_o(ar_preloader('path_to_mp3'))
我想通过路径和类似的librosa分析将Audioread对象创建分开,但是将Audioread对象转移到audioread.audio_open()上下文管理器会导致错误:
valueerror:输入信号长度= 0太小,无法从44100-> 22050
重新样本
使用__audioread_load函数从\ librosa \ core \ core \ audio.py带有前面的内部:
for frame in input_file:
....
y.append(frame)
....
return y
libreosa iter方法),没有框架,结果y列表是空的(这会导致更多错误)。
I am trying to investigate a reason for kinda strange behaviour of an iterator within a context manager. I am missing something here, maybe you will be able to explain.
Nothing changes, same iterable object but iteration stops working if out of CM for some reason.
Minimal code sample:
(requires an mp3 file at 'af_path' and ffmpeg binary in a project folder to run)
import inspect
from collections.abc import Iterable
def ar_preloader(af_path):
"""creates audioread object"""
import audioread.ffdec
# !!! ffmpeg binary backend must exist in the project folder
with audioread.audio_open(af_path) as m:
test = m
print(type(test), inspect.isgenerator(test), isinstance(test, Iterable))
print(next(iter(test)), 1111)
# print(next(iter(test)), 2222)
# print(type(test), inspect.isgenerator(test), isinstance(test, Iterable))
Then if you comment 2 print statements in context manager and uncomment last two statements outside, you'll get StopIteration exception.
import inspect
from collections.abc import Iterable
def ar_preloader(af_path):
"""creates audioread object"""
import audioread.ffdec
# !!! ffmpeg binary backend must exist in the project folder
with audioread.audio_open(af_path) as m:
test = m
# print(type(test), inspect.isgenerator(test), isinstance(test, Iterable))
# print(next(iter(test)), 1111)
print(next(iter(test)), 2222)
print(type(test), inspect.isgenerator(test), isinstance(test, Iterable))
Despite it's still an iterable and same audioread object (test.channels, test.samplerate, test.duration attributes still work).
What is even more strange, if you leave both ...1111 and ...2222 statements at once, it will work as should, i.e. first next(...) inside gives 1 frame, 2nd (outside) gives 2nd frame and so on, i.e. now that iterator could be iterated. Nevertheless, I can't leave out first anyhow.
I ran into this issue when I were trying to debug an error in librosa module. Its docs describe audioread context manager approach only but I wanted to create a function that loads an existing audioread object, i.e. not by path.
def l_analysis_o(afo):
import librosa
lo = librosa.load(afo)
# each librosa object is a tuple, (y=array, sr=sampling rate)
l_analysis_o(ar_preloader('path_to_mp3'))
I want to split up audioread object creation by path and further librosa analysis like that but transfer of an audioread object to librosa out of audioread.audio_open() context manager results in a error:
ValueError: Input signal length=0 is too small to resample from 44100->22050
Librosa uses __audioread_load function from \librosa\core\audio.py with a for-loop inside:
for frame in input_file:
....
y.append(frame)
....
return y
So if input_file is not an iterable (doesn't have iter method), there is NO frames from it and the resulting y-list is empty (that causes further errors).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论