66// Copyright © 2019 Agora. All rights reserved.
77//
88
9- #import " AgoraAudioTube.h"
109#import < CoreMedia/CoreMedia.h>
10+ #import " AgoraAudioTube.h"
11+ #import " AgoraAudioProcessing.h"
1112#include " external_resampler.h"
1213
1314#pragma mark - Audio Buffer
14- const int bufferSize = 48000 ;
15- int16_t appAudio[bufferSize];
16- int16_t micAudio[bufferSize];
17- int appAudioIndex = 0 ;
18- int micAudioIndex = 0 ;
15+ const int bufferSamples = 48000 * 8 ;
16+ size_t dataPointerSize = bufferSamples;
17+ int16_t dataPointer[bufferSamples];
18+ int16_t appAudio[bufferSamples];
19+ int16_t micAudio[bufferSamples];
20+ int64_t appAudioIndex = 0 ;
21+ int64_t micAudioIndex = 0 ;
22+
23+ int16_t mixPushAudio[bufferSamples];
1924
2025#pragma mark - Resample
21- int resampleApp (int16_t * sourceBuffer, size_t sourceBufferSize, size_t totalSamples, int inDataSamplesPer10ms, int outDataSamplesPer10ms, int channels, int sampleRate, int resampleRate);
22- int resampleMic (int16_t * sourceBuffer, size_t sourceBufferSize, size_t totalSamples, int inDataSamplesPer10ms, int outDataSamplesPer10ms, int channels, int sampleRate, int resampleRate);
26+ int resampleApp (int16_t * sourceBuffer,
27+ size_t sourceBufferSize,
28+ size_t totalSamples,
29+ int inDataSamplesPer10ms,
30+ int outDataSamplesPer10ms,
31+ int channels,
32+ int sampleRate,
33+ int resampleRate);
34+
35+ int resampleMic (int16_t * sourceBuffer,
36+ size_t sourceBufferSize,
37+ size_t totalSamples,
38+ int inDataSamplesPer10ms,
39+ int outDataSamplesPer10ms,
40+ int channels,
41+ int sampleRate,
42+ int resampleRate);
2343
2444static external_resampler* resamplerAppLeft;
2545static external_resampler* resamplerAppRight;
2646static external_resampler* resampleMicLeft;
2747static external_resampler* resampleMicRight;
2848
2949// App
30- int16_t inLeftAppResampleBuffer[bufferSize ];
31- int16_t inRightAppResampleBuffer[bufferSize ];
50+ int16_t inLeftAppResampleBuffer[bufferSamples ];
51+ int16_t inRightAppResampleBuffer[bufferSamples ];
3252
3353int inLeftAppResampleBufferIndex = 0 ;
3454int inRightAppResampleBufferIndex = 0 ;
3555
3656// Mic
37- int16_t inLeftMicResampleBuffer[bufferSize ];
38- int16_t inRightMicResampleBuffer[bufferSize ];
57+ int16_t inLeftMicResampleBuffer[bufferSamples ];
58+ int16_t inRightMicResampleBuffer[bufferSamples ];
3959
4060int inLeftMicResampleBufferIndex = 0 ;
4161int inRightMicResampleBufferIndex = 0 ;
4262
4363// Resample Out Buffer
44- int16_t outLeftResampleBuffer[bufferSize ];
45- int16_t outRightResampleBuffer[bufferSize ];
64+ int16_t outLeftResampleBuffer[bufferSamples ];
65+ int16_t outRightResampleBuffer[bufferSamples ];
4666
4767int outLeftResampleBufferIndex = 0 ;
4868int outRightResampleBufferIndex = 0 ;
5272@implementation AgoraAudioTube
5373
5474+ (void )agoraKit : (AgoraRtcEngineKit * _Nonnull)agoraKit pushAudioCMSampleBuffer : (CMSampleBufferRef _Nonnull)sampleBuffer resampleRate : (NSUInteger )resampleRate type : (AudioType)type ; {
55-
5675 @synchronized (lock) {
5776 [self privateAgoraKit: agoraKit
5877 pushAudioCMSampleBuffer: sampleBuffer
@@ -67,41 +86,46 @@ + (void)privateAgoraKit:(AgoraRtcEngineKit * _Nonnull)agoraKit pushAudioCMSample
6786 OSStatus err = noErr;
6887
6988 CMBlockBufferRef audioBuffer = CMSampleBufferGetDataBuffer (sampleBuffer);
89+ if (audioBuffer == nil ) {
90+ CFRelease (sampleBuffer);
91+ return ;
92+ }
93+
7094 size_t lengthAtOffset;
7195 size_t totalBytes;
7296 char *samples;
97+
7398 err = CMBlockBufferGetDataPointer (audioBuffer,
7499 0 ,
75100 &lengthAtOffset,
76101 &totalBytes,
77102 &samples);
78103
79- if (totalBytes == 0 ) {
104+ if (totalBytes == 0 || err != noErr ) {
80105 CFRelease (sampleBuffer);
81106 return ;
82107 }
83108
84109 CMAudioFormatDescriptionRef format = CMSampleBufferGetFormatDescription (sampleBuffer);
85110 const AudioStreamBasicDescription *description = CMAudioFormatDescriptionGetStreamBasicDescription (format);
86111
87- size_t dataPointerSize = 0 ;
88-
89- if (description->mChannelsPerFrame == 1 ) {
90- dataPointerSize = bufferSize * 2 ;
91- } else {
92- dataPointerSize = bufferSize;
93- }
112+ memset (dataPointer, 0 , sizeof (int16_t ) * bufferSamples);
94113
95- char dataPointer[dataPointerSize];
96114 err = CMBlockBufferCopyDataBytes (audioBuffer,
97115 0 ,
98116 totalBytes,
99117 dataPointer);
100118
119+ if (err != noErr) {
120+ CFRelease (sampleBuffer);
121+ return ;
122+ }
123+
101124 size_t totalSamples = totalBytes / (description->mBitsPerChannel / 8 );
102125 UInt32 channels = description->mChannelsPerFrame ;
103126 Float64 sampleRate = description->mSampleRate ;
104127
128+ // float to int
105129 if (description->mFormatFlags & kAudioFormatFlagIsFloat ) {
106130 float * floatData = (float *)dataPointer;
107131 int16_t * intData = (int16_t *)dataPointer;
@@ -112,6 +136,7 @@ + (void)privateAgoraKit:(AgoraRtcEngineKit * _Nonnull)agoraKit pushAudioCMSample
112136 }
113137 }
114138
139+ // big endian to little endian
115140 if (description->mFormatFlags & kAudioFormatFlagIsBigEndian ) {
116141 uint8_t * p = (uint8_t *)dataPointer;
117142 for (int i = 0 ; i < totalBytes; i += 2 ) {
@@ -122,6 +147,7 @@ + (void)privateAgoraKit:(AgoraRtcEngineKit * _Nonnull)agoraKit pushAudioCMSample
122147 }
123148 }
124149
150+ // rearrange left and right channels
125151 if ((description->mFormatFlags & kAudioFormatFlagIsNonInterleaved ) && channels == 2 ) {
126152 int16_t * intData = (int16_t *)dataPointer;
127153 int16_t newBuffer[totalSamples];
@@ -132,10 +158,15 @@ + (void)privateAgoraKit:(AgoraRtcEngineKit * _Nonnull)agoraKit pushAudioCMSample
132158 memcpy (dataPointer, newBuffer, sizeof (int16_t ) * totalSamples);
133159 }
134160
135- // convert mono to stereo
161+ // mono to stereo
136162 if (channels == 1 ) {
137163 int16_t * intData = (int16_t *)dataPointer;
138164 int16_t newBuffer[totalSamples * 2 ];
165+
166+ if ((totalSamples * sizeof (int16_t )) > dataPointerSize) {
167+ NSLog (@" totalSamples size: %lu " , (totalSamples * sizeof (int16_t )));
168+ }
169+
139170 for (int i = 0 ; i < totalSamples; i++) {
140171 newBuffer[2 * i] = intData[i];
141172 newBuffer[2 * i + 1 ] = intData[i];
@@ -146,7 +177,7 @@ + (void)privateAgoraKit:(AgoraRtcEngineKit * _Nonnull)agoraKit pushAudioCMSample
146177 channels = 2 ;
147178 }
148179
149- // ResampleRate
180+ // ResampleRate
150181 if (sampleRate != resampleRate) {
151182 int inDataSamplesPer10ms = sampleRate / 100 ;
152183 int outDataSamplesPer10ms = (int )resampleRate / 100 ;
@@ -167,19 +198,12 @@ + (void)privateAgoraKit:(AgoraRtcEngineKit * _Nonnull)agoraKit pushAudioCMSample
167198 totalBytes = totalSamples * sizeof (int16_t );
168199 }
169200
170- CMTime time = CMSampleBufferGetPresentationTimeStamp (sampleBuffer);
171-
172201 switch (type) {
173202 case AudioTypeApp: {
174203 memcpy (appAudio + appAudioIndex, dataPointer, totalBytes);
175204 appAudioIndex += totalSamples;
176205
177- int mixIndex = appAudioIndex > micAudioIndex ? micAudioIndex : appAudioIndex;
178-
179- if (mixIndex <= 0 || mixIndex > micAudioIndex || mixIndex > appAudioIndex) {
180- CFRelease (sampleBuffer);
181- return ;
182- }
206+ int64_t mixIndex = appAudioIndex > micAudioIndex ? micAudioIndex : appAudioIndex;
183207
184208 int16_t pushBuffer[appAudioIndex];
185209
@@ -189,14 +213,13 @@ + (void)privateAgoraKit:(AgoraRtcEngineKit * _Nonnull)agoraKit pushAudioCMSample
189213 pushBuffer[i] = (appAudio[i] + micAudio[i]) / 2 ;
190214 }
191215
192- [agoraKit pushExternalAudioFrameRawData: pushBuffer
193- samples: appAudioIndex / 2
194- timestamp: CMTimeGetSeconds (time)];
216+ [AgoraAudioProcessing pushAudioFrame: (unsigned char *)pushBuffer
217+ withFrameSize: appAudioIndex * sizeof (int16_t )];
195218
196- memset (appAudio, 0 , bufferSize * sizeof (int16_t ));
219+ memset (appAudio, 0 , bufferSamples * sizeof (int16_t ));
197220 appAudioIndex = 0 ;
198221
199- memmove (micAudio, micAudio + mixIndex, (bufferSize - mixIndex) * sizeof (int16_t ));
222+ memmove (micAudio, micAudio + mixIndex, (bufferSamples - mixIndex) * sizeof (int16_t ));
200223 micAudioIndex -= mixIndex;
201224 }
202225 break ;
@@ -252,7 +275,7 @@ int resampleApp(int16_t* sourceBuffer, size_t sourceBufferSize, size_t totalSamp
252275
253276 memmove (inRightAppResampleBuffer,
254277 inRightAppResampleBuffer + pPos,
255- sizeof (int16_t ) * (bufferSize - pPos));
278+ sizeof (int16_t ) * (bufferSamples - pPos));
256279
257280 // App Left
258281 pPos = 0 ;
@@ -275,7 +298,7 @@ int resampleApp(int16_t* sourceBuffer, size_t sourceBufferSize, size_t totalSamp
275298
276299 memmove (inLeftAppResampleBuffer,
277300 inLeftAppResampleBuffer + pPos,
278- sizeof (int16_t ) * (bufferSize - pPos));
301+ sizeof (int16_t ) * (bufferSamples - pPos));
279302
280303 memset (intData, 0 , sourceBufferSize);
281304
@@ -334,7 +357,7 @@ int resampleMic(int16_t* sourceBuffer, size_t sourceBufferSize, size_t totalSamp
334357
335358 memmove (inRightMicResampleBuffer,
336359 inRightMicResampleBuffer + pPos,
337- sizeof (int16_t ) * (bufferSize - pPos));
360+ sizeof (int16_t ) * (bufferSamples - pPos));
338361
339362 // App Left
340363 pPos = 0 ;
@@ -357,7 +380,7 @@ int resampleMic(int16_t* sourceBuffer, size_t sourceBufferSize, size_t totalSamp
357380
358381 memmove (inLeftMicResampleBuffer,
359382 inLeftMicResampleBuffer + pPos,
360- sizeof (int16_t ) * (bufferSize - pPos));
383+ sizeof (int16_t ) * (bufferSamples - pPos));
361384
362385 memset (intData, 0 , sourceBufferSize);
363386
0 commit comments