抱歉,如果这是一个非常明显的问题。我正在使用matplotlib生成一些光谱图,用作机器学习模型中的训练数据。频谱图是音乐的短片段,我想模拟随机加速或减慢歌曲,以在数据中产生变化。我在下面展示了生成每个光谱图的代码。我临时修改了它,从歌曲中的同一点开始生成两个图像,一个有变化,一个没有变化,以便比较它们,看看它是否按预期工作
from pydub import AudioSegment
import matplotlib.pyplot as plt
import numpy as np
BPM_VARIATION_AMOUNT = 0.2
FRAME_RATE = 22050
CHUNK_SIZE = 2
BUFFER = FRAME_RATE * 5
def generate_random_specgram(track):
# Read audio data from file
audio = AudioSegment.from_file(track.location)
audio = audio.set_channels(1).set_frame_rate(FRAME_RATE)
samples = audio.get_array_of_samples()
start = np.random.randint(BUFFER, len(samples) - BUFFER)
chunk = samples[start:start + int(CHUNK_SIZE * FRAME_RATE)]
# Plot specgram and save to file
filename = ('specgrams/%s-%s-%s.png' % (track.trackid, start, track.bpm))
plt.figure(figsize=(2.56, 0.64), frameon=False).add_axes([0, 0, 1, 1])
plt.axis('off')
plt.specgram(chunk, Fs = FRAME_RATE)
plt.savefig(filename)
plt.close()
# Perform random variations to the BPM
frame_rate = FRAME_RATE
bpm = track.bpm
variation = 1 - BPM_VARIATION_AMOUNT + (
np.random.random() * BPM_VARIATION_AMOUNT * 2)
bpm *= variation
bpm = round(bpm, 2)
# I thought this next line should have been /= but that stretched the wrong way?
frame_rate *= (bpm / track.bpm)
# Read audio data from file
chunk = samples[start:start + int(CHUNK_SIZE * frame_rate)]
# Plot specgram and save to file
filename = ('specgrams/%s-%s-%s.png' % (track.trackid, start, bpm))
plt.figure(figsize=(2.56, 0.64), frameon=False).add_axes([0, 0, 1, 1])
plt.axis('off')
plt.specgram(chunk, Fs = frame_rate)
plt.savefig(filename)
plt.close()
我认为,通过更改指定给specgram函数的Fs参数,这将沿x轴拉伸数据,但它似乎在调整整个图形的大小,并以奇怪且不可预测的方式在图像顶部引入空白。我肯定我遗漏了什么,但我看不出是什么。下面是一张图片来说明我得到了什么
帧率是一个固定的数字,仅取决于您的数据,如果您更改它,将有效地“拉伸”x轴,但方式错误。例如,如果有1000个对应于1秒的数据点,则帧速率(或更好的采样频率)将为1000。如果您的信号是一个简单的200Hz正弦信号,它会在时间上略微增加频率,那么
specgram
将是:如果更改帧率,则x轴和y轴比例将错误。如果将帧速率设置为500,则将具有:
曲线图非常相似,但这次是错误的:x轴上几乎有2秒,而你应该只有1秒,而且,你读取的起始频率是100Hz,而不是200Hz
总之,您设置的采样频率必须是正确的。如果要拉伸绘图,可以使用类似
plt.xlim(0.2, 0.4)
的方法。如果要避免在绘图顶部出现白带,可以手动将ylim
设置为帧速率的一半:这是因为傅里叶变换和Nyquist-Shannon theorem的简单特性
我的问题的解决方案是设置绘图的xlim和ylim。以下是我的测试文件中的代码,在该文件中,我最终消除了所有奇怪的空白:
相关问题 更多 >
编程相关推荐