2015-11-02 1 views
0

У меня возникла проблема с OpenSL ES в проблемной частоте Android. Используя OpenSL ES, я хочу создать синусоидальную волну с частотой волны 44,1 кГц. Мои исходные коды заключаются в следующем. Следующий источник составляет 44,1 Гц синусоида, но не 44,1 кГц. Где-то мне не хватает x1000 (k). Может ли кто-нибудь дать какой-нибудь путеводитель? Согласно OpenSL ES, он говорит, что 44.1kHz не 44.1Hz.Android Opensl-es не может получить частоту (кГц)

Заранее спасибо.

//Buffer: 
#define DEFAULT_FRAMES 1000 
for (i = 0; i < DEFAULT_FRAMES; ++i) { 
    defaultSineBuffer[i] = (sin((2 * 3.14) * (i%1000)*0.001))*(32767) ; // 1000 samples 
} 

// Call back buffer 
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) 
{ 
    nextBuffer = defaultSineBuffer; 
    nextSize = sizeof(defaultSineBuffer); 

    result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize); 
} 

// Create Engine 
JNIEXPORT jboolean JNICALL Java_com_droid_Inspector_createEngine 
     (JNIEnv *env, jobject jObject) { 

    SLresult result; 

    // create engine 
    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 
    if(SL_RESULT_SUCCESS != result){ 
     return JNI_FALSE; 
    } 

    // realize the engine 
    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 
    if(SL_RESULT_SUCCESS != result) { 
     return JNI_FALSE; 
    } 

    // get the engine interface, which is needed in order to create other objects 
    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 
    if(SL_RESULT_SUCCESS != result) { 
     return JNI_FALSE; 
    } 


    // create output mix, with environmental reverb specified as a non-required interface 
    const SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB}; 
    const SLboolean req[1] = {SL_BOOLEAN_FALSE}; 
    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req); 
    if(SL_RESULT_SUCCESS != result) { 
     return JNI_FALSE; 
    } 


    // realize the output mix 
    result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); 
    if(SL_RESULT_SUCCESS != result) { 
     return JNI_FALSE; 
    } 


    // get the environmental reverb interface 
    // this could fail if the environmental reverb effect is not available, 
    // either because the feature is not present, excessive CPU load, or 
    // the required MODIFY_AUDIO_SETTINGS permission was not requested and granted 
    result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB, 
               &outputMixEnvironmentalReverb); 
    if (SL_RESULT_SUCCESS == result) { 
     result = (*outputMixEnvironmentalReverb)->SetEnvironmentalReverbProperties(
       outputMixEnvironmentalReverb, &reverbSettings); 
    } 

    return JNI_TRUE; 
} 

// Create buffer player with 44.1kHz 
JNIEXPORT jboolean JNICALL Java_com_droid_Inspector_createBufferQueueAudioPlayer 
     (JNIEnv *env, jobject jObect, jint jInt) { 
    SLresult result; 

    // configure audio source 
    SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; 


    SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_44_1, 
         SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, 
         SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN}; 

    SLDataSource audioSrc = {&loc_bufq, &format_pcm}; 

    // configure audio sink 
    SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject}; 
    SLDataSink audioSnk = {&loc_outmix, NULL}; 

    // create audio player 
    const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND, SL_IID_VOLUME}; 
    const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; 
    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 3, ids, req); 
    if(SL_RESULT_SUCCESS != result) { 
     return JNI_FALSE; 
    } 
} 


// Play it 
JNIEXPORT jboolean JNICALL Java_com_droid_Inspector_playWave { 
    result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize); 
} 

ответ

0

Правильный путь для генерации Синус выглядит следующим образом:

  1. с частотой дискретизации 44,1 кГц 44100 выборок/секунду
  2. волны А 44100 кГц 44.100 циклов/секунду
  3. цикл синусоидальной функции 2 * PI

Теперь давайте код:

#define DEFAULT_FRAMES 1000 

    for(i = 0; i < DEFAULT_FRAMES ; i++) 
{ 
    // i is the sample index 
    // Straight sine function means one cycle every 2*pi samples: 
    // defaultSineBuffer[i] = sin(i); 
    // Multiply by 2*pi--now it's one cycle per sample: 
    // defaultSineBuffer[i] = sin((2 * pi) * i); 
    // Multiply by 44,100 samples per second--now it's 44,100 cycles per second: 
    // defaultSineBuffer[i] = sin(44100* (2 * pi) * i); 
    // Divide by 44,100 samples per second--now it's 44,100 cycles per 44,100 
    // samples, which is just what we needed: 
    //defaultSineBuffer[i] = sin(44100 * (2 * pi) * i/44100); 
    defaultSineBuffer[i] = sin(2 * pi * i) * (32767); 
}