gpt4 book ai didi

iphone - 在 iPhone 中播放蜂鸣声与频率和分贝相关

转载 作者:行者123 更新时间:2023-12-03 18:48:00 25 4
gpt4 key购买 nike

我研究了如何在 iPhone 中播放与我给出的频率和分贝相关的嘟嘟声。

我提到的链接:

http://developer.apple.com/library/ios/#samplecode/MusicCube/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008978

http://www.politepix.com/2010/06/18/decibel-metering-from-an-iphone-audio-unit/

http://atastypixel.com/blog/using-remoteio-audio-unit/

http://www.politepix.com/2010/06/18/decibel-metering-from-an-iphone-audio-unit/

How to play a sound of paticular frequency and framework not found AudioUnit question

我还在我的应用程序中使用 Flite 进行文本到语音转换。

请问,是否可以使用 flite 在 iPhone 中播放与频率和分贝相关的蜂鸣声。

我知道他们正在根据输入创建一个音频文件(仅与音高、方差、速度和给定的字符串相关)并在创建后通过 Audioplayer 进行播放。

但是他们没有自定义方法来设置频率和分贝!!!!

谁能给我提供一种在 iPhone 上实现此操作的好方法。

感谢您对这个问题的任何帮助。

谢谢

最佳答案

此类允许您以给定频率和给定幅度播放蜂鸣声。它使用来自 AudioToolbox.framework 的 AudioQueues。这只是一个草图,还有很多东西需要完善,但是创建信号的机制是有效的。

如果您看到@interface,那么用法就非常简单了。

#import <AudioToolbox/AudioToolbox.h>
#define TONE_SAMPLERATE 44100.

@interface Tone : NSObject {
AudioQueueRef queue;
AudioQueueBufferRef buffer;
BOOL rebuildBuffer;
}
@property (nonatomic, assign) NSUInteger frequency;
@property (nonatomic, assign) CGFloat dB;

- (void)play;
- (void)pause;
@end


@implementation Tone
@synthesize dB=_dB,frequency=_frequency;

void handleBuffer(void *inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer);

#pragma mark - Initialization and deallocation -

- (id)init
{
if ((self=[super init])) {

_dB=0.;
_frequency=440;
rebuildBuffer=YES;

// TO DO: handle AudioQueueXYZ's failures!!

// create a descriptor containing a LPCM, mono, float format
AudioStreamBasicDescription desc;

desc.mSampleRate=TONE_SAMPLERATE;
desc.mFormatID=kAudioFormatLinearPCM;
desc.mFormatFlags=kLinearPCMFormatFlagIsFloat;
desc.mBytesPerPacket=sizeof(float);
desc.mFramesPerPacket=1;
desc.mBytesPerFrame=sizeof(float);
desc.mChannelsPerFrame=1;
desc.mBitsPerChannel=8*sizeof(float);

// create a new queue
AudioQueueNewOutput(&desc,
&handleBuffer,
self,
CFRunLoopGetCurrent(),
kCFRunLoopCommonModes,
0,
&queue);

// and its buffer, ready to hold 1" of data
AudioQueueAllocateBuffer(queue,
sizeof(float)*TONE_SAMPLERATE,
&buffer);

// create the buffer and enqueue it
handleBuffer(self, queue, buffer);

}
return self;
}

- (void)dealloc
{
AudioQueueStop(queue, YES);
AudioQueueFreeBuffer(queue, buffer);
AudioQueueDispose(queue, YES);

[super dealloc];
}

#pragma mark - Main function -

void handleBuffer(void *inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer) {

// this function takes care of building the buffer and enqueuing it.

// cast inUserData type to Tone
Tone *tone=(Tone *)inUserData;

// check if the buffer must be rebuilt
if (tone->rebuildBuffer) {

// precompute some useful qtys
float *data=inBuffer->mAudioData;
NSUInteger max=inBuffer->mAudioDataBytesCapacity/sizeof(float);

// multiplying the argument by 2pi changes the period of the cosine
// function to 1s (instead of 2pi). then we must divide by the sample
// rate to get TONE_SAMPLERATE samples in one period.
CGFloat unit=2.*M_PI/TONE_SAMPLERATE;
// this is the amplitude converted from dB to a linear scale
CGFloat amplitude=pow(10., tone.dB*.05);

// loop and simply set data[i] to the value of cos(...)
for (NSUInteger i=0; i<max; ++i)
data[i]=(float)(amplitude*cos(unit*(CGFloat)(tone.frequency*i)));

// inform the queue that we have filled the buffer
inBuffer->mAudioDataByteSize=sizeof(float)*max;

// and set flag
tone->rebuildBuffer=NO;
}

// reenqueue the buffer
AudioQueueEnqueueBuffer(inAQ,
inBuffer,
0,
NULL);

/* TO DO: the transition between two adjacent buffers (the same one actually)
generates a "tick", even if the adjacent buffers represent a continuous signal.
maybe using two buffers instead of one would fix it.
*/
}

#pragma - Properties and methods -

- (void)play
{
// generate an AudioTimeStamp with "0" simply!
// (copied from FillOutAudioTimeStampWithSampleTime)

AudioTimeStamp time;

time.mSampleTime=0.;
time.mRateScalar=0.;
time.mWordClockTime=0.;
memset(&time.mSMPTETime, 0, sizeof(SMPTETime));
time.mFlags = kAudioTimeStampSampleTimeValid;

// TO DO: maybe it could be useful to check AudioQueueStart's return value
AudioQueueStart(queue, &time);
}

- (void)pause
{
// TO DO: maybe it could be useful to check AudioQueuePause's return value
AudioQueuePause(queue);
}

- (void)setFrequency:(NSUInteger)frequency
{
if (_frequency!=frequency) {
_frequency=frequency;

// we need to update the buffer (as soon as it stops playing)
rebuildBuffer=YES;
}
}

- (void)setDB:(CGFloat)dB
{
if (dB!=_dB) {
_dB=dB;

// we need to update the buffer (as soon as it stops playing)
rebuildBuffer=YES;
}
}

@end
  • 该类生成以给定整数频率振荡的 cos 波形(振幅*cos(2pi*频率*t));整个工作由 void handleBuffer(...) 完成,使用具有线性 PCM、单声道、float @44.1kHz 格式的 AudioQueue。为了改变信号形状,您只需更改该线即可。例如,以下代码将产生方波:

    float x = fmodf(unit*(CGFloat)(tone.frequency*i), 2 * M_PI);
    data[i] = amplitude * (x > M_PI ? -1.0 : 1.0);
  • 对于浮点频率,您应该考虑到音频数据的一秒内不一定有整数次振荡,因此所表示的信号在两个缓冲区之间的连接处是不连续的,并产生奇怪的“打钩'。例如,您可以设置较少的样本,以便连接点位于信号周期的末尾。

  • 正如 Paul R 指出的那样,您应该首先校准硬件,以便在实现中设置的值与设备产生的声音之间实现可靠的转换。实际上,这段代码生成的浮点样本范围是从-1到1,所以我只是将幅度值转换为dB(20*log_10(amplitude))。
  • 查看有关实现中其他细节和“已知限制”(所有这些“待办事项”)的评论。 Apple 在其引用资料中详细记录了所使用的函数。

关于iphone - 在 iPhone 中播放蜂鸣声与频率和分贝相关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10943896/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com