2012-06-08 15 views
6

Ho cercato di riprodurre un suono beep in iphone relativo alla frequenza & decibel che ho dato.Riproduci suono bip in iphone relativo a frequenza e decibel

Links ho fatto riferimento:

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

Inoltre ho usato Flite per fare il text to speech nella mia applicazione.

May so, è possibile riprodurre un suono beep in iphone relativo alla frequenza & decibel utilizzando il flite.

So che stanno creando un file audio come da input (solo in relazione all'altezza, alla varianza, alla velocità e alla stringa data) e riproducendolo tramite Audioplayer una volta creato.

Ma non hanno metodi personalizzati per impostare la frequenza & decibel !!!!

Quindi qualcuno potrebbe darmi un buon modo per farlo in iphone.

Qualsiasi aiuto su questa domanda è apprezzato.

Grazie

+0

I decibel (dB) vengono utilizzati per esprimere un * rapporto * tra due grandezze. Probabilmente vuoi dire "dB SPL" (dB Sound Pressure Level), che è ciò che le persone solitamente intendono quando parlano di quanto forte sia il suono in decibel. Per generare un suono con una determinata ampiezza di dB SPL, dovrai comunque essere in grado di calibrare l'hardware in qualche modo. –

+0

anche io ho bisogno dello stesso ..... devo creare un beep asper freequency e decibel .... sto cercando .. –

risposta

0

Questa classe consente di riprodurre un segnale acustico ad una data frequenza, e con una data ampiezza. Utilizza AudioQueues da AudioToolbox.framework. È solo uno schizzo, molte cose dovrebbero essere raffinate, ma il meccanismo per creare il segnale funziona.

L'utilizzo è piuttosto semplice se si visualizza lo @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 
  • La classe genera una forma d'onda oscillante cos a una data frequenza intero (ampiezza * cos (2pi * frequenza * t)); l'intero lavoro viene eseguito da void handleBuffer(...), utilizzando un AudioQueue con un formato PCM lineare, mono, float @ 44.1kHz. Per cambiare la forma del segnale, puoi semplicemente cambiare quella linea. Ad esempio, il codice seguente produrrà una forma d'onda quadra:

    float x = fmodf(unit*(CGFloat)(tone.frequency*i), 2 * M_PI); 
    data[i] = amplitude * (x > M_PI ? -1.0 : 1.0); 
    
  • per floating point frequenze, si dovrebbe considerare che non c'è necessarely un numero intero di oscillazioni in un secondo di dati audio, in modo che il segnale rappresentato è discontinuo all'incrocio tra due buffer e produce uno strano "tick". Ad esempio è possibile impostare meno campioni in modo che la giunzione si trovi alla fine di un periodo di segnale.

  • Come ha sottolineato Paul R, è necessario prima calibrare l'hardware per ottenere una conversione affidabile tra il valore impostato nell'implementazione e il suono prodotto dal dispositivo.In realtà, i campioni in virgola mobile generati in questo codice vanno da -1 a 1, quindi ho appena convertito il valore dell'ampiezza in dB (20 * log_10 (ampiezza)).
  • Dai un'occhiata ai commenti per ulteriori dettagli sull'implementazione e sui "limiti noti" (tutti quelli "DA FARE"). Le funzioni utilizzate sono ben documentate da Apple nel loro riferimento.
+0

Non funziona per me. Silenzio. O non capisco come usare questo codice. –

+0

@ValeriyVan Appena testato di nuovo e funziona. Collegato a AudioToolbox.framework, solo una vista e un pulsante che chiama '[riproduzione toni];'. Può essere più preciso? –

+0

Ho costruito un progetto di test pulito per giocare con questo e ora funziona. Ma i wort sono quei clic periodici? Li sento in Simulatore e sul dispositivo reale. –

Problemi correlati