为啥这种音频代码循环使用如此多的 CPU/内存?

Posted

技术标签:

【中文标题】为啥这种音频代码循环使用如此多的 CPU/内存?【英文标题】:Why is this looping of audio code using so much CPU/Memory?为什么这种音频代码循环使用如此多的 CPU/内存? 【发布时间】:2018-01-30 18:49:24 【问题描述】:
void FilePlayer::setLooping(const bool newState, float startPos)

while (newState == true)

    float endPos = startPos + 4/audioTransportSource.getLengthInSeconds();

    float currentPos = audioTransportSource.getCurrentPosition()/audioTransportSource.getLengthInSeconds();

    if (currentPos == endPos || currentPos > endPos)
    
        audioTransportSource.setPosition(startPos * audioTransportSource.getLengthInSeconds());
    


这是用于循环播放任何音频文件 4 秒的代码,无论多长时间。单击循环按钮,newState 变量变为 true。我有另一个按钮将其设置为 false,但是,当我在应用程序中执行循环任务时,CPU/内存/能源影响通过屋顶并且应用程序变得无法使用,以至于我无法单击按钮结束循环.

谁能解释一下这是为什么?

【问题讨论】:

1) 您是否正在测试优化的构建(如果没有;甚至不必费心测量)。 2) 你的分析器告诉你什么? 【参考方案1】:

您是否尝试过添加睡眠调用或确保返回主事件循环以处理按钮单击事件?

编辑:另外,您的 newState 变量是否应该通过引用(而不是 const)传递,以便您可以更改值以停止循环?

Edit2:一个非常基本/简单的线程示例:

文件播放器.h

#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>
#include <mutex>

class 

public:
    /**
      * @brief Constructor
      */
    FilePlayer();

    /**
     * @brief Destructor
     */
    ~FilePlayer();

private:
    /**
     * @brief startThread Starts the thread
     */
    void startThread();

    /**
     * @brief stopThread Stops the thread
     */
    void stopThread();

    /**
     * @brief theLoop The threaded loop
     */
    void theLoop(float startPos);

    std::atomic<bool> running; //lock for thread control
    std::mutex mtxAudioTransportSource; //mutex lock for audioTransportSource access
    std::thread td;   


文件播放器.cpp

FilePlayer::FilePlayer()

    running.store(false);


FilePlayer::~FilePlayer()

    stopThreads();


void FilePlayer::startThreads()

    if(running.load())
        //The thread is alread running, either call stopThreads before making a different one
        //or error out (I just put return in)
        return;
    
    running.store(true);
    td = thread(theLoop, 1.0);


void FilePlayer::stopThreads()

    running.store(false);
    if(td.joinable())
        td.join();
    
    delete td;
    td = NULL;


void FilePlayer::theLoop(float startPos)

    while (running.load())
    
        mtxAudioTransportSource.lock(); //Since the audioTransportSource object is being used in multiple threads, 
                                        //you must use a mutex lock to make sure only 1 thread is accessing it at any time
                                        //you will need to add the lock/unlock to all threads using it.

                                        //It is often a good idea to lock, get what you need, and unlock as soon as possible so
                                        //the other thread isn't blocked for too long if it is waiting on it.

        float audioLength = audioTransportSource.getLengthInSeconds();
        float currentPos = audioTransportSource.getCurrentPosition()/audioLength;

        mtxAudioTransportSource.unlock();

        float endPos = startPos + 4/audioLength;

        if (currentPos >= endPos)
        
            mtxAudioTransportSource.lock();
            audioTransportSource.setPosition(startPos * audioTransportSource.getLengthInSeconds());
            mtxAudioTransportSource.unlock();
        

        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    

所以我根本没有编译这个,所以可能会出现一些错误,但这只是一个让你工作的例子。如果有人有任何更正或优化,请随时说出来。关于线程,要记住的最重要的事情是在不使用某种锁的情况下永远不要访问共享变量。祝你的项目好运!

【讨论】:

更改了 const 位,如何返回主事件循环? 基本上你的代码卡在这个循环中,因此没有处理你可能试图在别处监听的任何键/UI事件。您可能需要使用线程来同时运行此循环到您的用户界面循环,以便在此循环处于活动状态时它仍会处理事件。这实际上取决于程序其余部分的结构,我只是猜测您的 UI 事件没有被处理,因为它不会从循环中返回以检查是否有事件。 好的,我明白了,您认为它可以与 CriticalSection ScopedLock 一起使用吗? 我没有机会使用它,但是是的,您需要使用一些锁来使共享变量线程安全。如果您愿意,我可以将一个示例与 C++11 标准库放在一起。 是的,这很有帮助,我不太擅长线程。今年刚刚了解他们

以上是关于为啥这种音频代码循环使用如此多的 CPU/内存?的主要内容,如果未能解决你的问题,请参考以下文章

如何让音频在 React 中更流畅地循环播放?

为啥我电脑装不了realtek高清晰音频管理器

为啥这段 Java 代码没有利用所有 CPU 内核?

计算机基础

音频混音是啥

为啥 python 的 for 循环对于大输入如此非线性?