如何在PortAudio中使用Pa_IsStreamActive?

时间:2016-09-27 22:37:39

标签: portaudio

我使用PortAudio V19-devel(pa_stable_v19_20140130)来合成文本转语音引擎的输出。

首先,我使用PaStreamFinishedCallback (void *userData)注册了一个函数,以便在音频流变为非活动状态时调用它。

根据Stream State Machine,当处于状态“Active”(换句话说是处理音频数据的回调)并返回paAbort时,我们触发转换到状态“Callback finished”取消所有缓冲区后,Pa_IsStreamActive返回0。

不幸的是我不知道如何做到这一点,因为Pa_IsStreamActivepaAbort之后返回1。问题是如何确定所有缓冲区都已被取消?您可以在下面找到我的代码的相应片段:

int AudioConnection::onAudioDataReceived (const void *input, void *output,
        unsigned long frames, const PaStreamCallbackTimeInfo *time,
        PaStreamCallbackFlags status, void *userdata
    ) {

    int finished;
    unsigned int i;
    AudioConnection *data = (AudioConnection *)userdata;
    unsigned int framesLeft = data->numFrames - data->cursor;

    int8_t *out = (int8_t *)output;

    // Declared to prevent unused variable warnings
    (void) time; (void) input; (void) status;

    if (framesLeft >= frames) {
        for (i = 0; i < frames; i++) {
            *out++ = data->audioSamples[data->cursor++];
            *out++ = data->audioSamples[data->cursor++];

        }
        data->cursor += frames;
        finished = paContinue;
    }

    else if (framesLeft == 0) {
        *out++ = 0;
        *out++ = 0;
        data->cursor = 0;
        finished = paAbort;
    }

    // final buffer
    else if (framesLeft < frames) {
        for (i = 0; i < framesLeft; i++) {
            *out++ = data->audioSamples[data->cursor++];
            *out++ = data->audioSamples[data->cursor++];
        }
        data->cursor = 0;
        finished = paComplete;
    }

    // should never happen
    else {
        finished = paAbort;
    }

    return finished;
}

这是我的回调代码,在音频流完成后调用:

void AudioConnection::onAudioStreamFinished (void *userdata) {

    AudioConnection *data = (AudioConnection *) userdata;

    ACE_DEBUG ((LM_TRACE, ACE_TEXT ("(%t | %P | %D | %N) AudioConnection::onAudioStreamFinished ()\n")));
    ACE_DEBUG ((LM_TRACE, ACE_TEXT ("(%t | %P | %D | %N) AudioConnection::isAudioStreamActive () = %d \n"), data->isAudioStreamActive ()));
}

bool AudioConnection::isAudioStreamActive () {

    return Pa_IsStreamActive (audioStream) ? true : false;
}

以下跟踪表明问题 - 我希望最后一行中的isAudioStreamActive返回0.对此的任何反馈都表示赞赏。谢谢!

(1987417168 | 19339 | 2016-09-27 23:10:30.935040 | ../src/AudioConnection.cpp) AudioConnection::isAudioStreamActive () = 0 
(1987417168 | 19339 | 2016-09-27 23:10:30.936162 | ../src/AudioConnection.cpp) AudioConnection::playAudioStream ()
(1954542672 | 19339 | 2016-09-27 23:10:30.977247 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 27648 
(1954542672 | 19339 | 2016-09-27 23:10:31.007114 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 26112 
(1954542672 | 19339 | 2016-09-27 23:10:31.037122 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 24576 
(1954542672 | 19339 | 2016-09-27 23:10:31.067106 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 23040 
(1954542672 | 19339 | 2016-09-27 23:10:31.097107 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 21504 
(1954542672 | 19339 | 2016-09-27 23:10:31.137147 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 19968 
(1954542672 | 19339 | 2016-09-27 23:10:31.187113 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 18432 
(1954542672 | 19339 | 2016-09-27 23:10:31.237124 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 16896 
(1954542672 | 19339 | 2016-09-27 23:10:31.287146 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 15360 
(1954542672 | 19339 | 2016-09-27 23:10:31.337112 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 13824 
(1954542672 | 19339 | 2016-09-27 23:10:31.387106 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 12288 
(1954542672 | 19339 | 2016-09-27 23:10:31.437225 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 10752 
(1954542672 | 19339 | 2016-09-27 23:10:31.487161 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 9216 
(1954542672 | 19339 | 2016-09-27 23:10:31.537158 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 7680 
(1954542672 | 19339 | 2016-09-27 23:10:31.587206 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 6144 
(1954542672 | 19339 | 2016-09-27 23:10:31.637156 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 4608 
(1954542672 | 19339 | 2016-09-27 23:10:31.687188 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 3072 
(1954542672 | 19339 | 2016-09-27 23:10:31.737236 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 1536 
(1954542672 | 19339 | 2016-09-27 23:10:31.787165 | ../src/AudioConnection.cpp) AudioConnection framesLeft: 0 .......silence.
(1954542672 | 19339 | 2016-09-27 23:10:31.787428 | ../src/AudioConnection.cpp) AudioConnection::onAudioStreamFinished ()
(1954542672 | 19339 | 2016-09-27 23:10:31.787736 | ../src/AudioConnection.cpp) AudioConnection::isAudioStreamActive () = 1

1 个答案:

答案 0 :(得分:0)

Pa_IsStreamActive的结果取决于您使用的主机。它在paAbort之后返回1并不令人惊讶,因为这意味着发生异常并且PortAudio应该立即退出。在这种情况下,您最有可能想要使用paComplete。我想你想要framesLeft <= frames作为“最终缓冲区”。