Android Opensl-es无法获得频率(kHz)

时间:2015-11-02 06:21:09

标签: android opensl

我在Android频率问题上遇到OpenSL ES问题。 使用OpenSL ES,我想创建44.1kHz波形的正弦波。 我的源代码如下。 以下信号源产生44.1Hz正弦波但不是44.1kHz。某处我错过了x1000(k)。 谁能给一些指导?根据OpenSL ES,它说44.1kHz不是44.1Hz。

提前致谢。

//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);
}

1 个答案:

答案 0 :(得分:0)

生成正弦的正确方法如下:

  1. 44.1 kHz的采样率为44,100个样本/秒
  2. 44100 kHz波是44,100周/秒
  3. 正弦函数的周期为2 * PI
  4. 现在让代码:

    #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);
    }