问题描述
我已经研究过要在iphone中播放与频率有关的蜂鸣声,我给出的分贝数.
I have researched about to play a beep sound in iphone related to the frequency & decibels that i have given.
我提到的链接:
http://www.politepix.com/2010/06/18/decibel-metering-from-iphone-audio-unit/
http://atastypixel.com/blog/using-remoteio-audio-单位/
http://www.politepix.com/2010/06/18/decibel-metering-from-iphone-audio-unit/
我还使用Flite在我的应用程序中进行文字转语音.
Also i have used Flite to do text to speech in my application.
我可以知道,是否可以在iPhone中播放与频率&频率有关的蜂鸣声?分贝使用flite.
May i know , is it possible to play a beep sound in iphone related to the frequency & decibels using flite.
我知道他们正在根据输入(仅与音高,方差,速度和给定的弦有关)创建音频文件,并在创建音频播放器后对其进行播放.
I know that they are creating a audio file as per the input(only related to the pitch,variance,speed and given string) and playing through it Audioplayer once created.
但是他们没有自定义方法来设置频率&分贝!!!!
But they have no custom methods to set the frequency & decibels!!!!
因此,任何人都可以为我提供一种在iphone中进行操作的好方法.
So could any one provide me a good way to do it in iphone.
感谢您对这个问题的任何帮助.
Any help on this question is appreciated.
谢谢
推荐答案
此类可让您以给定的频率和给定的振幅播放提示音.它使用 AudioToolbox.framework 中的AudioQueues.这只是一个草图,许多事情都应该完善,但是创建信号的机制起作用.
This class allows you to play a beep at a given frequency, and with a given amplitude.It uses AudioQueues from AudioToolbox.framework. It's just a sketch, many things should be refined, but the mechanism for creating the signal works.
如果您看到@interface
,用法非常简单.
The usage is pretty straightforward if you see the @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
-
该类生成以给定整数频率( amplitude * cos(2pi * frequency * t))振荡的cos波形;整个工作由
void handleBuffer(...)
使用带有线性PCM,单声道,浮点@ 44.1kHz格式的AudioQueue来完成.为了改变信号形状,您可以改变那条线.例如,以下代码将产生一个方波:The class generates a cos waveform oscillating at the given integer frequency (amplitude*cos(2pi*frequency*t)); the whole job is done by
void handleBuffer(...)
, using an AudioQueue with a linear PCM, mono, float @44.1kHz format. In order to change the signal shape, you can just change that line. For example, the following code will produce a square waveform:float x = fmodf(unit*(CGFloat)(tone.frequency*i), 2 * M_PI); data[i] = amplitude * (x > M_PI ? -1.0 : 1.0);
-
对于浮点频率,您应考虑一秒钟的音频数据中不必存在整数个振荡,因此表示的信号在两个缓冲区之间的交界处是不连续的,并产生奇怪的打钩'.例如,您可以设置较少的样本,以使结点处于信号周期的末尾.
For floating point frequencies, you should consider that there isn't necessarely an integer number of oscillations in one second of audio data, so the signal represented is discontinuous at the junction between two buffers, and produces a strange 'tick'. For example you could set less samples so that the junction is at the end of a signal period.
这篇关于在iPhone中播放与“频率和频率"相关的哔哔声分贝的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!