2012-06-08 12 views
6

He investigado a punto de reproducir un pitido en el iphone relacionado con la frecuencia & decibeles que he dado.Reproducir sonido de pitido en iphone relacionado con la frecuencia y decibelios

enlaces que se hace referencia:

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

También he usado Flite para hacer texto a voz en mi aplicación.

Lo sé, es posible reproducir un pitido en el iphone relacionado con la frecuencia & decibeles con flite.

Sé que están creando un archivo de audio según la entrada (solo relacionado con el tono, la varianza, la velocidad y la cadena dada) y reproduciéndolo Audioplayer una vez creado.

Pero no tienen métodos personalizados para establecer la frecuencia & decibelios !!!!

Entonces, ¿podría alguien proporcionarme una buena manera de hacerlo en iphone.

Se agradece cualquier ayuda en esta pregunta.

Gracias

+0

Los decibelios (dB) se utilizan para expresar una * relación * entre dos magnitudes. Probablemente se refiera a 'dB SPL' (Nivel de presión sonora dB), que es lo que las personas generalmente quieren decir cuando hablan sobre qué tan alto está el sonido en decibelios. Para generar un sonido con una amplitud dB SPL dada, necesitará calibrar el hardware de alguna manera. –

+0

yo también necesito lo mismo ..... tengo que crear un beep asper frecuencia y decibelios .... estoy buscando .. –

Respuesta

0

Esta clase le permite reproducir un sonido a una frecuencia dada, y con una amplitud dada. Utiliza AudioQueues desde AudioToolbox.framework. Es solo un boceto, muchas cosas deben ser refinadas, pero el mecanismo para crear la señal funciona.

El uso es bastante sencillo si ve el @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 clase genera una forma de onda oscilante cos a la frecuencia entero dado (amplitud * cos (2pi * frecuencia t *)); todo el trabajo se realiza por void handleBuffer(...), usando un AudioQueue con formato PCM lineal, mono, flotante @ 44.1kHz. Para cambiar la forma de la señal, puedes cambiar esa línea. Por ejemplo, el siguiente código producirá una forma de onda cuadrada:

    float x = fmodf(unit*(CGFloat)(tone.frequency*i), 2 * M_PI); 
    data[i] = amplitude * (x > M_PI ? -1.0 : 1.0); 
    
  • Para frecuencias de punto flotante, se debe considerar que no hay necessarely un número entero de oscilaciones en un segundo de datos de audio, por lo que la señal representada es discontinuo en la unión entre dos memorias intermedias, y produce un extraño 'tic'. Por ejemplo, podría establecer menos muestras para que la unión se encuentre al final de un período de señal.

  • Como señaló Paul R, primero debe calibrar el hardware para obtener una conversión confiable entre el valor que establece en su implementación y el sonido producido por su dispositivo.En realidad, las muestras de coma flotante generadas en este código varían de -1 a 1, así que acabo de convertir el valor de amplitud en dB (20 * log_10 (amplitud)).
  • Eche un vistazo a los comentarios sobre otros detalles en la implementación y las "limitaciones conocidas" (todos esos 'HACER'). Las funciones utilizadas están bien documentadas por Apple en su referencia.
+0

No funciona para mí. Silencio. O no entiendo cómo usar este código. –

+0

@ValeriyVan Acabo de probarlo de nuevo y funciona. Vinculado con AudioToolbox.framework, solo una vista y un botón que llaman '[tone play];'. ¿Puedes ser mas específico? –

+0

He creado un proyecto de prueba limpio para jugar con esto y ahora funciona. Pero, ¿cuáles son esos clics periódicos? Los escucho tanto en el simulador como en el dispositivo real. –

Cuestiones relacionadas