根据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
}
这基本上称为“:basicaly with”。
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赫兹(当然要使用adjustedDuration),则没有点击声。仍然为了测试目的,如果我使用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.18秒的声音...
但无论如何...我想象过,如果我在一秒钟内采样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);
那不行,它只会使声音变得更尖锐。而且我仍然不明白为什么会这样。我以为声音质量会降低,因为采样率减少了。
有人能帮我生成任何所需延迟、所需质量和频率的(可循环)波形声音吗?
我确信这听起来很容易,但我没有找到实现这个目标的方法。
我曾尝试过放置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。如果您有解决方法,可以节省我几天时间。