audio playback improvement
This commit is contained in:
1 parent
ca69fd62d9
commit
46834a8a8b
1 file changed
+31
-4
@@ -15,6 +15,7 @@
|
|||||||
#import "DataManager.h"
|
#import "DataManager.h"
|
||||||
|
|
||||||
#import <VideoToolbox/VideoToolbox.h>
|
#import <VideoToolbox/VideoToolbox.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
|
||||||
#define SDL_MAIN_HANDLED
|
#define SDL_MAIN_HANDLED
|
||||||
#import <SDL.h>
|
#import <SDL.h>
|
||||||
@@ -56,6 +57,7 @@ static AVAudioEngine *audioEngine;
|
|||||||
static AVAudioPlayerNode *audioPlayerNode;
|
static AVAudioPlayerNode *audioPlayerNode;
|
||||||
static AVAudioPCMBuffer *pcmBuffer;
|
static AVAudioPCMBuffer *pcmBuffer;
|
||||||
static AVAudioFormat *audioFormat;
|
static AVAudioFormat *audioFormat;
|
||||||
|
static atomic_long systemAudioQueuedFrames;
|
||||||
|
|
||||||
static bool muteInBackground;
|
static bool muteInBackground;
|
||||||
static bool fullColorRange;
|
static bool fullColorRange;
|
||||||
@@ -64,6 +66,20 @@ static VideoDecoderRenderer* renderer;
|
|||||||
|
|
||||||
static BandwidthTracker *bwTracker;
|
static BandwidthTracker *bwTracker;
|
||||||
|
|
||||||
|
static void SystemAudioConsumeQueuedFrames(long frameCount)
|
||||||
|
{
|
||||||
|
long currentFrames;
|
||||||
|
long newFrames;
|
||||||
|
|
||||||
|
do {
|
||||||
|
currentFrames = atomic_load(&systemAudioQueuedFrames);
|
||||||
|
newFrames = currentFrames - frameCount;
|
||||||
|
if (newFrames < 0) {
|
||||||
|
newFrames = 0;
|
||||||
|
}
|
||||||
|
} while (!atomic_compare_exchange_weak(&systemAudioQueuedFrames, ¤tFrames, newFrames));
|
||||||
|
}
|
||||||
|
|
||||||
int DrDecoderSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags)
|
int DrDecoderSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags)
|
||||||
{
|
{
|
||||||
[renderer setupWithVideoFormat:videoFormat width:width height:height frameRate:redrawRate fullRange:fullColorRange];
|
[renderer setupWithVideoFormat:videoFormat width:width height:height frameRate:redrawRate fullRange:fullColorRange];
|
||||||
@@ -348,6 +364,7 @@ void ArCleanup(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioEngineInit(int sampleRate, int channelCount) {
|
void AudioEngineInit(int sampleRate, int channelCount) {
|
||||||
|
atomic_store(&systemAudioQueuedFrames, 0);
|
||||||
|
|
||||||
audioEngine = [[AVAudioEngine alloc] init];
|
audioEngine = [[AVAudioEngine alloc] init];
|
||||||
audioPlayerNode = [[AVAudioPlayerNode alloc] init];
|
audioPlayerNode = [[AVAudioPlayerNode alloc] init];
|
||||||
@@ -426,20 +443,28 @@ void ArDecodeAndPlaySample(char* sampleData, int sampleLength)
|
|||||||
float* fbuf = (float*)audioBuffer;
|
float* fbuf = (float*)audioBuffer;
|
||||||
|
|
||||||
if(useSystemAudioEngine){
|
if(useSystemAudioEngine){
|
||||||
// 创建 AVAudioPCMBuffer
|
long maxQueuedFrames = (long)audioConfig.samplesPerFrame * 10;
|
||||||
|
while (atomic_load(&systemAudioQueuedFrames) > maxQueuedFrames) {
|
||||||
|
[NSThread sleepForTimeInterval:0.001f];
|
||||||
|
}
|
||||||
|
|
||||||
AVAudioFrameCount frameCount = decodeLen;
|
AVAudioFrameCount frameCount = decodeLen;
|
||||||
AVAudioPCMBuffer *buffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:audioFormat frameCapacity:frameCount];
|
AVAudioPCMBuffer *buffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:audioFormat frameCapacity:frameCount];
|
||||||
buffer.frameLength = frameCount;
|
buffer.frameLength = frameCount;
|
||||||
|
|
||||||
// 拷贝数据到 buffer
|
|
||||||
for (int ch = 0; ch < audioConfig.channelCount; ch++) {
|
for (int ch = 0; ch < audioConfig.channelCount; ch++) {
|
||||||
float *dst = buffer.floatChannelData[ch];
|
float *dst = buffer.floatChannelData[ch];
|
||||||
for (int i = 0; i < decodeLen; i++) {
|
for (int i = 0; i < decodeLen; i++) {
|
||||||
dst[i] = fbuf[i * audioConfig.channelCount + ch] * volume; // 非交错数据
|
dst[i] = fbuf[i * audioConfig.channelCount + ch] * volume; // 非交错数据
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 播放
|
|
||||||
if(!audioSessionInterrupted) [audioPlayerNode scheduleBuffer:buffer completionHandler:nil];
|
if(!audioSessionInterrupted) {
|
||||||
|
atomic_fetch_add(&systemAudioQueuedFrames, frameCount);
|
||||||
|
[audioPlayerNode scheduleBuffer:buffer completionHandler:^{
|
||||||
|
SystemAudioConsumeQueuedFrames(frameCount);
|
||||||
|
}];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else{
|
else{
|
||||||
@@ -535,6 +560,7 @@ void ClSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t
|
|||||||
// won't be able to acquire it if LiStartConnection is in
|
// won't be able to acquire it if LiStartConnection is in
|
||||||
// progress.
|
// progress.
|
||||||
LiInterruptConnection();
|
LiInterruptConnection();
|
||||||
|
atomic_store(&systemAudioQueuedFrames, 0);
|
||||||
[audioPlayerNode stop];
|
[audioPlayerNode stop];
|
||||||
[audioEngine stop];
|
[audioEngine stop];
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
@@ -557,6 +583,7 @@ void ClSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case AVAudioSessionInterruptionTypeBegan:
|
case AVAudioSessionInterruptionTypeBegan:
|
||||||
audioSessionInterrupted = true;
|
audioSessionInterrupted = true;
|
||||||
|
atomic_store(&systemAudioQueuedFrames, 0);
|
||||||
[audioPlayerNode stop];
|
[audioPlayerNode stop];
|
||||||
[audioEngine stop];
|
[audioEngine stop];
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in new issue
Block a user