Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 端口音频和Libsndfile无数据?_C++_Class_Audio_Portaudio_Libsndfile - Fatal编程技术网

C++ 端口音频和Libsndfile无数据?

C++ 端口音频和Libsndfile无数据?,c++,class,audio,portaudio,libsndfile,C++,Class,Audio,Portaudio,Libsndfile,我可能做了一些愚蠢的事情,但当我在开发的声音系统中使用libsndfile时,我并没有从中获得任何形式的数据。 sf_read_floatf返回的值大于零,但从缓冲区本身看,它只是将数据置零。我也在使用libsamplerate,但目前我有音频文件和端口音频的两个采样器,用于测试 端口音频构造函数: PortAudioSystem::PortAudioSystem(double sampleRate, PaDeviceIndex device, void * hostApiSpecificStr

我可能做了一些愚蠢的事情,但当我在开发的声音系统中使用libsndfile时,我并没有从中获得任何形式的数据。 sf_read_floatf返回的值大于零,但从缓冲区本身看,它只是将数据置零。我也在使用libsamplerate,但目前我有音频文件和端口音频的两个采样器,用于测试

端口音频构造函数:

PortAudioSystem::PortAudioSystem(double sampleRate, PaDeviceIndex device, void * hostApiSpecificStreamInfo) {
    this->m_masterVol = this->m_musicVol = this->m_sfxVol = 1.0f;
    this->m_deltaTime = 0.0f;
    this->audioStream = nullptr;
    this->_hasPaError = false;

    this->m_sampleRate = sampleRate;

    PaStreamParameters streamParams;
    streamParams.device = device; //set device to use
    streamParams.hostApiSpecificStreamInfo = hostApiSpecificStreamInfo;
    streamParams.sampleFormat = paFloat32; // 32bit float format
    streamParams.suggestedLatency = 0.2; //200 ms ought to satisfy even the worst sound card
    streamParams.channelCount = 2; //number of channels (1: mono, 2: left/right, etc)

    int err = 0;

    err = Pa_OpenStream(
        &this->audioStream,
        0, // no input
        &streamParams,
        sampleRate,
        paFramesPerBufferUnspecified, // let portaudio choose the buffersize
        paNoFlag,/* no special modes (clip off, dither off) */
        PortAudioSystem::paCallbackCommon,
        this
    );

    if (err != paNoError) {
        pushPaError(err, Pa_GetErrorText(err));
        this->audioStream = nullptr;
    }

    int src_err;
    this->m_srcState = src_new(SRC_SINC_FASTEST,2,&src_err); //create a new sample rate converter

    if (this->m_srcState == NULL) {
        //src_error(this->m_srcState);
        this->pushPaError(src_err, src_strerror(src_err));
    }

    this->m_nextPlayID = 0;
}
端口音频回调:

int PortAudioSystem::paCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) {
    this->m_deltaTime = (float)((double)framesPerBuffer / this->m_sampleRate); //get delta time based on sample rate and number of frames per buffer
    if (this->m_playingAudioFiles.size() == 0) return paContinue; //if we dont have any playing audio files, skip.

    AudioFrame::_2 *outFrame = (AudioFrame::_2*)outputBuffer; //convert the port audio buffer to an audio frame buffer.

    //zero out the output buffer.
    for (unsigned long zeroI = 0; zeroI < framesPerBuffer; zeroI++) {
        outFrame[zeroI].left = 0.0f;
        outFrame[zeroI].right = 0.0f;
    }

    //for (PlayingAudioFile playingfile : this->m_playingAudioFiles) playingfile.audioFile->Seek(playingfile.currentFrame); //seek to the current position of the file

    AudioFrame::_2 *framesOut = new AudioFrame::_2[framesPerBuffer]; //create a buffer for frames out.
    //float * fFramesOut = new float[framesPerBuffer * 2]; //create a float buffer for frames out (*2 for left and right channel)

    //prep common data for sample rate conversion.
    SRC_DATA src_data;
    src_data.output_frames = framesPerBuffer; //set output frames to be the max output frames to have.
    src_data.end_of_input = 0; //we are not at the end of the file (change for specific audio file system [function?]).
    src_data.data_out = (float *)framesOut; //set our output frames to be the buffer that we created.

    flow.lock(); //mutex lock
    for (std::pair<long, PlayingAudioFile> entry : this->m_playingAudioFiles){ //for each playing audio file
        if (entry.second.paused) continue; //if the audio file is paused, skip it.

        PlayingAudioFile& playingfile = entry.second;
        playingfile.audioFile->Seek(playingfile.currentFrame); //seek to the current position of the file

        src_data.src_ratio = this->m_sampleRate / playingfile.audioFile->GetSampleRate(); //get the ratio of the sample rate conversion

        if (src_data.src_ratio == 1) { //if we are 1 to 1, dont do sample rate conversion.
            src_data.input_frames_used = src_data.output_frames_gen = (long)playingfile.audioFile->GetFrames(framesPerBuffer, (float *)framesOut);
        } else { //otherwise convert to port audio system's sample rate.
            //adjust the number of frames to read based on ratio.
            long long framesToRead//;
            /*if (fmod((double)framesPerBuffer, src_data.src_ratio) == 0) framesToRead = framesPerBuffer;
            else framesToRead*/ = (framesPerBuffer / ((long long)src_data.src_ratio));// + 2;

            AudioFrame::_2* framesIn = new AudioFrame::_2[framesToRead]; //create a buffer for frames in.
            //float * fFramesIn = new float[framesToRead * 2]; //create a float buffer to read in frames. (*2 for left and right audio channel)
            src_data.data_in = (float *)framesIn; //set the frame in buffer

            src_data.input_frames = (long)playingfile.audioFile->GetFrames(framesToRead, (float *)framesIn); //read the frames; //set the number of frames that were read

            if (src_data.input_frames == 0) {
                delete[] framesIn; //free up the frame in buffer to prevent memory leaks.
                continue; //if we have no data, skip
            }

            src_reset(this->m_srcState); //reset the sample rate conversion state
            int src_err = src_process(this->m_srcState, &src_data); //convert the sample rate

            if (src_err != 0) this->pushPaError(src_err, src_strerror(src_err)); //if we have an error, push it back.

            delete[] framesIn; //free up the frame in buffer
        }

        //AudioFrame::_2* framesOut = (AudioFrame::_2*) fFramesOut; //convert the float buffer to an audio frame buffer for easier access to the channels

        for (unsigned long outFrameI = 0; outFrameI < src_data.output_frames_gen; outFrameI++) { //for each frame (based on how many frames were generated from conversion [possibly under framesPerBuffer])
            //individual frame data;
            AudioFrame::_2 frame = framesOut[outFrameI];

            //adjust volume from master volume
            frame.left *= this->m_masterVol;
            frame.right *= this->m_masterVol;

            //adjust volume
            switch (playingfile.channel) { //based on sound channel
            case eAT_Music: //if we are a music channel
                frame.left *= this->m_musicVol;
                frame.right *= this->m_musicVol;
                break;
            case eAT_SFX: //if we are a sfx channel
                frame.left *= this->m_sfxVol;
                frame.right *= this->m_sfxVol;
                break;
            }

            if (frame.left != 0.0f){ //make sure we have data.
                if (outFrame[outFrameI].left == 0.0f) { //if the output frame has no data
                    outFrame[outFrameI].left = frame.left; //set the audio
                } else { //if the output frame has data
                    outFrame[outFrameI].left += frame.left; //mix the channels
                    outFrame[outFrameI].left /= 2; //ghetto way of making sure we dont clip?
                }
            }
            if (frame.right != 0.0f){ //make sure we have data.
                if (outFrame[outFrameI].right == 0.0f) { //if the output frame has no data
                    outFrame[outFrameI].right = frame.right; //set the audio
                } else { //if the output frame has data 
                    outFrame[outFrameI].right += frame.right; //mix the channels
                    outFrame[outFrameI].right /= 2; //ghetto way of making sure we dont clip?
                }
            }
        }

        playingfile.currentFrame += src_data.input_frames_used; //update the current position time based on how many frames were converted;

        if (playingfile.currentFrame >= playingfile.endFrame && !playingfile.loop) { //if we are finnished playing.
            //mark for removal.
            m_stoppedAudioFiles.push_back(entry.first);
        } else {
            //loop the file
            playingfile.currentFrame = playingfile.startFrame;
        }
    }

    delete [] framesOut;

    //removed stopped audio files.
    while (m_stoppedAudioFiles.size() > 0) {
        this->m_playingAudioFiles.erase(m_stoppedAudioFiles.back());
        m_stoppedAudioFiles.pop_back();
    }

    flow.unlock(); //mutex unlock

    return paContinue; //continue playback
}
音频帧::_2:

    struct _2 {
        float left;
        float right;

        _2() : left(0.0f), right(0.0f) {}
    };
播放音频文件:

struct PlayingAudioFile {
    IAudioFile* audioFile;
    long long currentFrame;
    long long startFrame;
    long long endFrame;
    bool loop;
    bool paused;
    EAudioChannel channel;
};

我知道整个代码有点长,但我现在不知道我做错了什么。。。我相信我正确地构造了缓冲区,但我尝试了纯浮点指针,这两种指针都是用new定义和创建的,但都不起作用。我也尝试过使用for循环逐帧运行,并将其保存到单个浮点中,但这显然给我带来了一个围绕变量的堆栈,这是一个损坏的错误。。。任何帮助都将不胜感激。

修复了它。我在做傻事。 这就是罪魁祸首:

    if (playingfile.currentFrame >= playingfile.endFrame && !playingfile.loop) { //if we are finnished playing.
        //mark for removal.
        m_stoppedAudioFiles.push_back(entry.first);
    } else {
        //loop the file
        playingfile.currentFrame = playingfile.startFrame;
    }
将“else”更改为“else if(playingsource.currentFrame>=playingsource.endFrame&&playingsource.loop)”,因为它每次都将当前帧设置为起始帧

    if (playingfile.currentFrame >= playingfile.endFrame && !playingfile.loop) { //if we are finnished playing.
        //mark for removal.
        m_stoppedAudioFiles.push_back(entry.first);
    } else {
        //loop the file
        playingfile.currentFrame = playingfile.startFrame;
    }