Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在iphone中播放与频率相关的嘟嘟声&;分贝_Iphone_Avaudioplayer_Frequency_Beep - Fatal编程技术网

在iphone中播放与频率相关的嘟嘟声&;分贝

在iphone中播放与频率相关的嘟嘟声&;分贝,iphone,avaudioplayer,frequency,beep,Iphone,Avaudioplayer,Frequency,Beep,我已经研究过在iphone中播放与我给出的频率和分贝相关的哔哔声 我提到的链接: 我还使用Flite在我的应用程序中进行文本到语音转换 我想知道,是否可以在iphone中使用flite播放与频率和分贝相关的哔哔声 我知道他们正在根据输入创建一个音频文件(仅与音高、方差、速度和给定字符串相关),并在创建音频播放器后通过它播放 但是他们没有自定义的方法来设置频率和分贝 那么,有谁能为我提供一个在iphone上实现这一点的好方法呢 在此问题上的任何帮助都将不胜感激 谢谢本课程允许您以给定的频

我已经研究过在iphone中播放与我给出的频率和分贝相关的哔哔声

我提到的链接:

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

我想知道,是否可以在iphone中使用flite播放与频率和分贝相关的哔哔声

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

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

那么,有谁能为我提供一个在iphone上实现这一点的好方法呢

在此问题上的任何帮助都将不胜感激


谢谢

本课程允许您以给定的频率和振幅播放嘟嘟声。 它使用AudioToolbox.framework中的AudioQueues。这只是一个草图,很多东西都需要改进,但创建信号的机制是有效的

如果您看到
@界面
,则使用方法非常简单

#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
对于浮点频率,你应该考虑到在一秒钟的音频数据中不需要整数的振荡,所以在两个缓冲器之间的交界处表示的信号是不连续的,并且产生奇怪的“嘀嗒声”。例如,您可以设置较少的采样,使交叉点处于信号周期的末尾

  • 正如Paul R所指出的,您应该首先校准硬件,以便在实现中设置的值和设备产生的声音之间进行可靠的转换。实际上,在这段代码中生成的浮点样本的范围是-1到1,所以我只是将振幅值转换成dB(20*log_10(振幅)
  • 查看注释,了解实现中的其他细节和“已知限制”(所有这些“要做”)。苹果公司在其参考资料中详细记录了所使用的功能

  • 分贝(dB)用于表示两个量级之间的比率。你可能指的是
    dbspl
    (dB声压级),这是人们通常在谈论声音的分贝大小时的意思。要生成具有给定dB SPL振幅的声音,您需要能够以某种方式校准硬件。me也需要相同的。。。。。必须创建一个蜂鸣音和分贝。。。。我在看着……对我不起作用。沉默。或者我不明白如何使用这段代码。@ValeriyVan刚刚再次测试了它,它确实有效。链接到AudioToolbox.framework,只有一个视图和一个按钮可以调用
    [tone play]。你能更具体一点吗?我已经建立了一个干净的测试项目来处理这个问题,现在它可以工作了。但是这些是周期性的点击吗?我在模拟器和真实设备上都能听到它们。在例行的
    handleBuffer
    中有一条注释解释了这一点。当AudioToolbox播放完缓冲区后,缓冲区将退出队列,
    handleBuffer
    将被调用,并将同一缓冲区重新排队。这引入了一些毫秒的延迟,在此期间没有声音再现;所以你有1秒的音频和几毫秒的静音:这就是“滴答声”。可能使用两个缓冲区(例如,具有相同内容)可以解决这一问题:当第二个缓冲区播放时,第一个缓冲区重新排队,当一个缓冲区播放完后,另一个缓冲区已经排队并“无缝”复制。如何修改为具有一系列脉冲的方波?
    float x = fmodf(unit*(CGFloat)(tone.frequency*i), 2 * M_PI);
    data[i] = amplitude * (x > M_PI ? -1.0 : 1.0);