【发布时间】:2023-03-12 00:03:01
【问题描述】:
按照 Ben 的回答进行编辑
我正在尝试做一些对使用信号处理的人来说应该很容易的东西,但这让我很头疼。我只是想生成一个可以播放任意秒数的波形声音,可以少于或超过一秒(0.1 秒、0.88 秒、1.2 秒……)。
为了产生波浪声,我使用的是众所周知的方法:
+ (NSData*) WAVSoundForFrequency:(float)frequency duration:(float)seconds sampleRate:(unsigned int)sampleRate gain:(float)gain
{
int frames = seconds * sampleRate;
float* rawSound = (float*)malloc(frames*sizeof(float));
if (rawSound == NULL) return nil;
for (int i = 0; i < frames; i++)
rawSound[i] = gain * sinf(i*2*M_PI*frequency/sampleRate);
// converting to raw sound and returning the whole thing
}
这基本上被称为:
AVAudioPlayer* player = [self.audioPlayerManager buildSoundFrequency:200 duration:0.18 sampleRate:44100 gain:1.0];
player.volume = 1.0;
player.numberOfLoops = -1;
[player play];
问题在于,使用这些参数时,波形最终似乎并不完整,因此它会产生在每个循环中都能听到的咔嗒声。但是,如果我使用 0.5 秒或 1.0 秒的持续时间和 200 赫兹(当然使用调整的持续时间),则不会单击。仍然出于测试目的,如果我使用 400 赫兹或 440 赫兹而不是 200 赫兹,我现在有 0.5 秒的点击次数。
请注意,这里的循环仅用于测试并查找是否有点击。最后,声音应该只在所需的持续时间播放。
我猜那是因为持续时间不是波浪周期的整数倍,所以我调整了这样的调用,将想要的持续时间调整为最接近的持续时间,这将是一个周期的倍数想要的频率:
float wantedDuration = 0.18;
float hertz = 200;
int wantedSampleRate = 44100;
// Adjusting wanted duration so the duration contains an entiere number of waves
float oneWaveDurationInSeconds = 1.0/hertz;
int nbWavesNeeded = roundf(wantedDuration/oneWaveDurationInSeconds);
float adjustedDuration = nbWavesNeeded * oneWaveDurationInSeconds;
// Adjusting sample rate so one wave takes an entiere number of samples
float oneSampleDuration = 1.0/wantedSampleRate;
int adjustedSamplerate = wantedSampleRate;
while (YES) {
oneSampleDuration = 1.0/adjustedSamplerate;
if (roundf(oneWaveDurationInSeconds/oneSampleDuration) == oneWaveDurationInSeconds/oneSampleDuration) break;
adjustedSamplerate++;
NSLog(@"%d", adjustedSamplerate);
}
// Debug
float nbSamplesForOneWave = oneWaveDurationInSeconds / (1.0/adjustedSamplerate);
NSLog(@"nbSamplesForOneWave : %f", nbSamplesForOneWave);
// Execute
MyAudioPlayer* player = [self.manager preloadSoundFrequency:hertz duration:adjustedDuration sampleRate:adjustedSamplerate gain:1.0
identifier:@"ii" category:@"Radar"];
player.volume = 1.0;
player.numberOfLoops = -1;
[player play];
但是还是有点击。
有人告诉我,问题可能出在采样率上。但我真的不明白为什么。据我了解,采样率是在一秒钟内定义的样本数。所以对我来说,它不依赖于持续时间或频率。
还有……为什么我不应该有 44100 采样质量的 0.18s 的声音……
但是无论如何...我想象如果我在一秒钟内采样 44100 个点,要求 0.18 的持续时间应该会导致 44100*0.18 个样本。这是int frames 表示的数字。所以我尝试替换
rawSound[i] = gain * sinf(i*2*M_PI*frequency/sampleRate);
与
rawSound[i] = gain * sinf(i*2*M_PI*frequency/frames);
这不起作用,只会使声音更加尖锐。我仍然不明白为什么。我认为这将是一个质量较差的声音,因为 tehre 只是更少的样本。
有人可以帮我为任何想要的延迟、所需的质量和频率生成(可能是可循环的)波形声音吗?
我确信这听起来 (:-)) 很容易,但我看不出实现这一目标的方法。
我试图放一个 NSLog 来查看使用的值(没有 Paul 斜坡的日志):
if (i<20 || i > frames-20) NSLog(@"%f", rawSound[i]);
对于 440Hz、44100 采样率、1.0 持续时间(无调整): 没有点击
2011-10-31 01:02:34.110 testAudio[9602:207] 0.000000
2011-10-31 01:02:34.112 testAudio[9602:207] 0.062648
2011-10-31 01:02:34.113 testAudio[9602:207] 0.125051
2011-10-31 01:02:34.114 testAudio[9602:207] 0.186961
2011-10-31 01:02:34.115 testAudio[9602:207] 0.248138
2011-10-31 01:02:34.116 testAudio[9602:207] 0.308339
2011-10-31 01:02:34.116 testAudio[9602:207] 0.367330
2011-10-31 01:02:34.117 testAudio[9602:207] 0.424877
2011-10-31 01:02:34.117 testAudio[9602:207] 0.480755
2011-10-31 01:02:34.118 testAudio[9602:207] 0.534744
2011-10-31 01:02:34.119 testAudio[9602:207] 0.586632
2011-10-31 01:02:34.121 testAudio[9602:207] 0.636216
2011-10-31 01:02:34.121 testAudio[9602:207] 0.683300
2011-10-31 01:02:34.122 testAudio[9602:207] 0.727699
2011-10-31 01:02:34.123 testAudio[9602:207] 0.769240
2011-10-31 01:02:34.123 testAudio[9602:207] 0.807759
2011-10-31 01:02:34.124 testAudio[9602:207] 0.843104
2011-10-31 01:02:34.125 testAudio[9602:207] 0.875137
2011-10-31 01:02:34.126 testAudio[9602:207] 0.903732
2011-10-31 01:02:34.127 testAudio[9602:207] 0.928777
2011-10-31 01:02:34.130 testAudio[9602:207] -0.928790
2011-10-31 01:02:34.130 testAudio[9602:207] -0.903724
2011-10-31 01:02:34.131 testAudio[9602:207] -0.875102
2011-10-31 01:02:34.132 testAudio[9602:207] -0.843167
2011-10-31 01:02:34.132 testAudio[9602:207] -0.807795
2011-10-31 01:02:34.133 testAudio[9602:207] -0.769245
2011-10-31 01:02:34.134 testAudio[9602:207] -0.727667
2011-10-31 01:02:34.135 testAudio[9602:207] -0.683225
2011-10-31 01:02:34.135 testAudio[9602:207] -0.636283
2011-10-31 01:02:34.136 testAudio[9602:207] -0.586658
2011-10-31 01:02:34.137 testAudio[9602:207] -0.534724
2011-10-31 01:02:34.138 testAudio[9602:207] -0.480687
2011-10-31 01:02:34.138 testAudio[9602:207] -0.424978
2011-10-31 01:02:34.139 testAudio[9602:207] -0.367383
2011-10-31 01:02:34.140 testAudio[9602:207] -0.308342
2011-10-31 01:02:34.140 testAudio[9602:207] -0.248087
2011-10-31 01:02:34.141 testAudio[9602:207] -0.186856
2011-10-31 01:02:34.142 testAudio[9602:207] -0.125132
2011-10-31 01:02:34.142 testAudio[9602:207] -0.062676
对于 440Hz,44100 采样率,0.5 持续时间(无调整): 没有点击
2011-10-31 01:04:51.043 testAudio[9714:207] 0.000000
2011-10-31 01:04:51.045 testAudio[9714:207] 0.062648
2011-10-31 01:04:51.047 testAudio[9714:207] 0.125051
2011-10-31 01:04:51.049 testAudio[9714:207] 0.186961
2011-10-31 01:04:51.049 testAudio[9714:207] 0.248138
2011-10-31 01:04:51.050 testAudio[9714:207] 0.308339
2011-10-31 01:04:51.051 testAudio[9714:207] 0.367330
2011-10-31 01:04:51.052 testAudio[9714:207] 0.424877
2011-10-31 01:04:51.053 testAudio[9714:207] 0.480755
2011-10-31 01:04:51.054 testAudio[9714:207] 0.534744
2011-10-31 01:04:51.055 testAudio[9714:207] 0.586632
2011-10-31 01:04:51.055 testAudio[9714:207] 0.636216
2011-10-31 01:04:51.056 testAudio[9714:207] 0.683300
2011-10-31 01:04:51.057 testAudio[9714:207] 0.727699
2011-10-31 01:04:51.059 testAudio[9714:207] 0.769240
2011-10-31 01:04:51.060 testAudio[9714:207] 0.807759
2011-10-31 01:04:51.060 testAudio[9714:207] 0.843104
2011-10-31 01:04:51.061 testAudio[9714:207] 0.875137
2011-10-31 01:04:51.062 testAudio[9714:207] 0.903732
2011-10-31 01:04:51.062 testAudio[9714:207] 0.928777
2011-10-31 01:04:51.064 testAudio[9714:207] -0.928795
2011-10-31 01:04:51.065 testAudio[9714:207] -0.903730
2011-10-31 01:04:51.065 testAudio[9714:207] -0.875109
2011-10-31 01:04:51.066 testAudio[9714:207] -0.843109
2011-10-31 01:04:51.067 testAudio[9714:207] -0.807731
2011-10-31 01:04:51.067 testAudio[9714:207] -0.769253
2011-10-31 01:04:51.068 testAudio[9714:207] -0.727676
2011-10-31 01:04:51.069 testAudio[9714:207] -0.683324
2011-10-31 01:04:51.070 testAudio[9714:207] -0.636199
2011-10-31 01:04:51.070 testAudio[9714:207] -0.586669
2011-10-31 01:04:51.071 testAudio[9714:207] -0.534736
2011-10-31 01:04:51.072 testAudio[9714:207] -0.480806
2011-10-31 01:04:51.072 testAudio[9714:207] -0.424880
2011-10-31 01:04:51.073 testAudio[9714:207] -0.367282
2011-10-31 01:04:51.074 testAudio[9714:207] -0.308355
2011-10-31 01:04:51.074 testAudio[9714:207] -0.248100
2011-10-31 01:04:51.075 testAudio[9714:207] -0.186989
2011-10-31 01:04:51.076 testAudio[9714:207] -0.125025
2011-10-31 01:04:51.077 testAudio[9714:207] -0.062689
对于 440Hz、44100 采样率、0.25 持续时间(无调整): 硬点击
2011-10-31 01:05:25.245 testAudio[9759:207] 0.000000
2011-10-31 01:05:25.247 testAudio[9759:207] 0.062648
2011-10-31 01:05:25.249 testAudio[9759:207] 0.125051
2011-10-31 01:05:25.250 testAudio[9759:207] 0.186961
2011-10-31 01:05:25.251 testAudio[9759:207] 0.248138
2011-10-31 01:05:25.252 testAudio[9759:207] 0.308339
2011-10-31 01:05:25.252 testAudio[9759:207] 0.367330
2011-10-31 01:05:25.253 testAudio[9759:207] 0.424877
2011-10-31 01:05:25.254 testAudio[9759:207] 0.480755
2011-10-31 01:05:25.254 testAudio[9759:207] 0.534744
2011-10-31 01:05:25.255 testAudio[9759:207] 0.586632
2011-10-31 01:05:25.256 testAudio[9759:207] 0.636216
2011-10-31 01:05:25.257 testAudio[9759:207] 0.683300
2011-10-31 01:05:25.257 testAudio[9759:207] 0.727699
2011-10-31 01:05:25.258 testAudio[9759:207] 0.769240
2011-10-31 01:05:25.259 testAudio[9759:207] 0.807759
2011-10-31 01:05:25.260 testAudio[9759:207] 0.843104
2011-10-31 01:05:25.261 testAudio[9759:207] 0.875137
2011-10-31 01:05:25.261 testAudio[9759:207] 0.903732
2011-10-31 01:05:25.262 testAudio[9759:207] 0.928777
2011-10-31 01:05:25.263 testAudio[9759:207] -0.928781
2011-10-31 01:05:25.264 testAudio[9759:207] -0.903727
2011-10-31 01:05:25.264 testAudio[9759:207] -0.875135
2011-10-31 01:05:25.265 testAudio[9759:207] -0.843105
2011-10-31 01:05:25.266 testAudio[9759:207] -0.807763
2011-10-31 01:05:25.267 testAudio[9759:207] -0.769249
2011-10-31 01:05:25.267 testAudio[9759:207] -0.727692
2011-10-31 01:05:25.268 testAudio[9759:207] -0.683296
2011-10-31 01:05:25.269 testAudio[9759:207] -0.636217
2011-10-31 01:05:25.269 testAudio[9759:207] -0.586638
2011-10-31 01:05:25.270 testAudio[9759:207] -0.534756
2011-10-31 01:05:25.271 testAudio[9759:207] -0.480746
2011-10-31 01:05:25.271 testAudio[9759:207] -0.424873
2011-10-31 01:05:25.272 testAudio[9759:207] -0.367332
2011-10-31 01:05:25.273 testAudio[9759:207] -0.308348
2011-10-31 01:05:25.273 testAudio[9759:207] -0.248152
2011-10-31 01:05:25.274 testAudio[9759:207] -0.186952
2011-10-31 01:05:25.275 testAudio[9759:207] -0.125047
2011-10-31 01:05:25.276 testAudio[9759:207] -0.062652
编辑
我已将生成的声音样本(440Hz,444100 采样率,0.1 秒)写入文件,并使用声音编辑器打开它。多次剪切和粘贴声音以发出更长的声音:它播放时没有咔嗒声。通过 AVAudioPlayer 播放的相同声音样本会在每个样本结束时产生咔嗒声。所以问题似乎出在 AVAudioPlayer 中,原因我不明白,因为只有一些特定的值会产生这些点击。
编辑
我使用了 wav 生成的文件,并让它与带有循环的 AVAudioPlayer 一起播放:点击
我使用了相同的文件,并使用自定义库使其与 OpenAL 循环播放:不再单击。问题是 OpenAL 真的很难理解,并且会导致我的声音部分完全重写,只是为了那个糟糕的声音。
问题显然是使用了 AVAudioPlayer。如果你有解决方案让它发挥作用,它会节省我几天的时间。
【问题讨论】:
-
向 Apple 提交错误报告。没有其他人可以使它工作。
标签: iphone cocoa-touch math audio signal-processing