EQPlayer.mm 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. //
  2. // EQPlayer.m
  3. // SuperpoweredPerformance
  4. //
  5. // Created by zzl on 16/6/23.
  6. // Copyright © 2016年 imect. All rights reserved.
  7. //
  8. #import "EQPlayer.h"
  9. #import "SuperpoweredAdvancedAudioPlayer.h"
  10. #import "SuperpoweredReverb.h"
  11. #import "SuperpoweredFilter.h"
  12. #import "Superpowered3BandEQ.h"
  13. #import "SuperpoweredEcho.h"
  14. #import "SuperpoweredRoll.h"
  15. #import "SuperpoweredFlanger.h"
  16. #import "SuperpoweredSimple.h"
  17. #import "SuperpoweredIOSAudioIO.h"
  18. #import "Superpowered3BandEQ.h"
  19. #import <mach/mach_time.h>
  20. #import <libkern/OSAtomic.h>
  21. #include <AudioToolbox/AudioConverter.h>
  22. #import "superpowed/SuperpoweredIOSAudioIO.h"
  23. //M1
  24. #define NUMFXUNITS 8
  25. #define TIMEPITCHINDEX 0
  26. #define PITCHSHIFTINDEX 1
  27. #define ROLLINDEX 2
  28. #define FILTERINDEX 3
  29. #define EQINDEX 4
  30. #define FLANGERINDEX 5
  31. #define DELAYINDEX 6
  32. #define REVERBINDEX 7
  33. @interface EQPlayer ()<SuperpoweredIOSAudioIODelegate>
  34. @end
  35. SuperpoweredIOSAudioIO * g_output;
  36. @implementation EQPlayer
  37. {
  38. float * _stereoBuffer;
  39. char * _tempBuffer;
  40. SuperpoweredAdvancedAudioPlayer* _player;
  41. Superpowered3BandEQ* _bandEQ;
  42. NSString* _filePath;
  43. NSArray* _allEqNames;
  44. NSArray* _allEqData;//@[ @[ l ] , @[ m ] ,@[ h ] ..... ]
  45. NSUInteger _selectEQ;
  46. unsigned int _lastSamplerate;
  47. char* _outDataBuffer;
  48. __volatile int _outBufferPushInOffset;
  49. __volatile int _outBufferCopyOutOffset;
  50. __volatile int _outBufferNowSize;//当前有多少
  51. int _outBufferSize;
  52. OSSpinLock _outBufferSpinlock;
  53. //M2
  54. SuperpoweredFX *effects[NUMFXUNITS];
  55. }
  56. - (void)interruptionStarted {
  57. //NSLog(@"interruptionStartedbefor fuck paly:%d",_player->playing);
  58. if( _player->playing )
  59. _player->togglePlayback();
  60. //NSLog(@"interruptionStartedatfer fuck paly:%d",_player->playing);
  61. }
  62. - (void)recordPermissionRefused {
  63. }
  64. - (void)mapChannels:(multiOutputChannelMap *)outputMap inputMap:(multiInputChannelMap *)inputMap externalAudioDeviceName:(NSString *)externalAudioDeviceName outputsAndInputs:(NSString *)outputsAndInputs {
  65. }
  66. - (void)interruptionEnded {
  67. //NSLog(@"interruptionEnded befor fuck paly:%d",_player->playing);
  68. if( !_player->playing )
  69. _player->togglePlayback();
  70. //NSLog(@"interruptionEnded after fuck paly:%d",_player->playing);
  71. _player->onMediaserverInterrupt(); // If the player plays Apple Lossless audio files, then we need this. Otherwise unnecessary.
  72. //[_output onRouteChange:nil];
  73. }
  74. - (void)resetVEP
  75. {
  76. self.mVolume = 6;
  77. self.mEqName = _allEqNames[0];
  78. self.mPitch = 0;
  79. }
  80. -(int)getSampleRate
  81. {
  82. return _lastSamplerate;
  83. }
  84. -(double)mCurrentTime
  85. {
  86. return _player->positionMs/1000.0f;
  87. }
  88. -(double)mTotalTime
  89. {
  90. if( _player->positionPercent <= 0.0f )
  91. return _player->positionMs+ 1000.0f;
  92. return ( self.mCurrentTime / _player->positionPercent);
  93. }
  94. - (void)setMPitch:(int)mPitch
  95. {
  96. if( mPitch >= -12 && mPitch <= 12 )
  97. {
  98. _mPitch = mPitch;
  99. if( _player != NULL )
  100. _player->setPitchShift(_mPitch);
  101. }
  102. }
  103. - (void)setMEqName:(NSString *)mEqName
  104. {
  105. NSUInteger index = [_allEqNames indexOfObject:mEqName];
  106. if( index != NSNotFound )
  107. {
  108. _selectEQ = index;
  109. _mEqName = mEqName;
  110. [self updateEqEffect:_selectEQ];
  111. }
  112. }
  113. - (void)updateEqEffect:(NSUInteger)index
  114. {
  115. if( _bandEQ == NULL || index >= _allEqData.count )
  116. {
  117. return;
  118. }
  119. NSArray* t = _allEqData[ index ];
  120. _bandEQ->bands[0] = [t[0] floatValue];
  121. _bandEQ->bands[1] = [t[1] floatValue];
  122. _bandEQ->bands[2] = [t[2] floatValue];
  123. }
  124. - (void)setMVolume:(int)mVolume
  125. {
  126. if( mVolume >=0 && mVolume <= 12 )
  127. {
  128. _mVolume = mVolume;
  129. }
  130. }
  131. - (void)cfgEqEffectParam
  132. {
  133. _allEqNames = @[ ASLocalizedString(@"原声"),
  134. ASLocalizedString(@"悠扬"),
  135. ASLocalizedString(@"圆润"),
  136. ASLocalizedString(@"流行"),
  137. ASLocalizedString(@"轻松"),
  138. ASLocalizedString(@"空灵")];
  139. _allEqData = @[ @[ @1.0f, @1.0f,@1.0f ],// Low/mid/high gain
  140. @[ @1.0f, @1.5f,@1.5f ],
  141. @[ @1.5f, @1.5f,@1.0f ],
  142. @[ @1.1f, @1.3f,@1.0f ],
  143. @[ @1.0f, @0.8f,@0.3f ],
  144. @[ @1.0f, @1.5f,@1.5f ],
  145. ];
  146. }
  147. - (BOOL)cfgPlayer
  148. {
  149. _outBufferSpinlock = OS_SPINLOCK_INIT;
  150. _outBufferPushInOffset = 0;
  151. _outBufferCopyOutOffset = 0;
  152. [self cfgEqEffectParam];
  153. _mPitch = 0;
  154. _selectEQ = 0;
  155. _mEqName = ASLocalizedString(@"原声");
  156. _mVolume = 6;
  157. //SuperpoweredFFTTest();
  158. if (posix_memalign((void **)&_stereoBuffer, 16, 4096 + 128) != 0)
  159. {
  160. NSLog(@"posix_memalign failed");
  161. //abort()
  162. return false;
  163. } // Allocating memory, aligned to 16.
  164. //3840 是 48000 的 20ms的数据量, 8倍完全够了
  165. //M3
  166. _outBufferSize = 1024 *4*10;
  167. //_outBufferSize = 4096 * 8;
  168. if (posix_memalign((void **)&_outDataBuffer, 16, _outBufferSize ) != 0 )
  169. {
  170. NSLog(@"_outDataBuffer failed");
  171. //abort()
  172. return false;
  173. } // Allocating memory, aligned to 16.
  174. if (posix_memalign((void **)&_tempBuffer, 16,_outBufferSize) != 0 )
  175. {
  176. NSLog(@"_tempBuffer failed");
  177. //abort()
  178. return false;
  179. } // Allocating memory, aligned to 16.
  180. _lastSamplerate = 44100;
  181. //创建一个播放器
  182. //M4
  183. if (!_player) {
  184. _player = new SuperpoweredAdvancedAudioPlayer(NULL, NULL, 44100, 0);
  185. }
  186. _player->open( [_filePath fileSystemRepresentation]);
  187. _player->setBpm(124.0f);
  188. _player->setTempo(1.0f, true);
  189. //M5
  190. _player->setFirstBeatMs(40);
  191. _player->setPosition(_player->firstBeatMs, false, false);
  192. //M6 超滤共振低通
  193. SuperpoweredFilter *filter = new SuperpoweredFilter(SuperpoweredFilter_Resonant_Lowpass, 44100);
  194. filter->setResonantParameters(1000.0f, 0.1f);
  195. effects[FILTERINDEX] = filter;
  196. effects[ROLLINDEX] = new SuperpoweredRoll(44100);
  197. effects[FLANGERINDEX] = new SuperpoweredFlanger(44100);
  198. SuperpoweredReverb *reverb = new SuperpoweredReverb(44100);
  199. reverb->setRoomSize(0.8f);
  200. reverb->setMix(0.5f);
  201. effects[REVERBINDEX] = reverb;
  202. _bandEQ = new Superpowered3BandEQ(44100);
  203. _bandEQ->enable(true);
  204. if( g_output == nil )
  205. {
  206. g_output = [[SuperpoweredIOSAudioIO alloc] initWithDelegate:(id<SuperpoweredIOSAudioIODelegate>)self
  207. preferredBufferSize:12 preferredMinimumSamplerate:44100
  208. audioSessionCategory:AVAudioSessionCategoryPlayAndRecord
  209. channels:2];
  210. }
  211. return YES;
  212. }
  213. - (BOOL)startPlay:(NSString*)filepath
  214. {
  215. _filePath = filepath;
  216. if( ![self cfgPlayer] )
  217. {
  218. NSLog(@"cfg player failed");
  219. return NO;
  220. }
  221. //重置音效
  222. //[self resetVEP];
  223. //开始播放
  224. _player->play(false);
  225. //设置代理
  226. [g_output setdelg:self];
  227. if( !_player->playing )
  228. {
  229. _player->togglePlayback();
  230. }
  231. if( ![g_output getRuning] )
  232. [g_output start];
  233. return YES;
  234. }
  235. // This is where the Superpowered magic happens.
  236. - (bool)audioProcessingCallback:(float **)buffers inputChannels:(unsigned int)inputChannels outputChannels:(unsigned int)outputChannels numberOfSamples:(unsigned int)numberOfSamples samplerate:(unsigned int)samplerate hostTime:(UInt64)hostTime {
  237. if( !_player->playing )
  238. {
  239. NSLog(@"not palying");
  240. return false;
  241. }
  242. uint64_t startTime = mach_absolute_time();
  243. if (samplerate != _lastSamplerate) { // Has samplerate changed?
  244. //采样率变化了,就更新
  245. _lastSamplerate = samplerate;
  246. _player->setSamplerate(samplerate);
  247. _bandEQ->setSamplerate( samplerate );
  248. };
  249. // We're keeping our Superpowered time-based effects in sync with the player... with one line of code. Not bad, eh?
  250. //((SuperpoweredRoll *)effects[ROLLINDEX])->bpm = ((SuperpoweredFlanger *)effects[FLANGERINDEX])->bpm = ((SuperpoweredEcho *)effects[DELAYINDEX])->bpm = player->currentBpm;
  251. /*
  252. Let's process some audio.
  253. If you'd like to change connections or tap into something, no abstract connection handling and no callbacks required!
  254. */
  255. float fff = _mVolume / 12.0f;
  256. bool silence = !_player->process(_stereoBuffer, false, numberOfSamples, fff, 0.0f, -1.0);
  257. _bandEQ->process(_stereoBuffer, _stereoBuffer, numberOfSamples);
  258. /*
  259. 暂时不要其他效果
  260. if (effects[ROLLINDEX]->process(silence ? NULL : stereoBuffer, stereoBuffer, numberOfSamples)) silence = false;
  261. effects[FILTERINDEX]->process(stereoBuffer, stereoBuffer, numberOfSamples);
  262. effects[EQINDEX]->process(stereoBuffer, stereoBuffer, numberOfSamples);
  263. effects[FLANGERINDEX]->process(stereoBuffer, stereoBuffer, numberOfSamples);
  264. if (effects[DELAYINDEX]->process(silence ? NULL : stereoBuffer, stereoBuffer, numberOfSamples)) silence = false;
  265. if (effects[REVERBINDEX]->process(silence ? NULL : stereoBuffer, stereoBuffer, numberOfSamples)) silence = false;
  266. */
  267. /*
  268. 时间计算处理
  269. // CPU measurement code to show some nice numbers for the business guys.
  270. uint64_t elapsedUnits = mach_absolute_time() - startTime;
  271. if (elapsedUnits > maxTime) maxTime = elapsedUnits;
  272. timeUnitsProcessed += elapsedUnits;
  273. samplesProcessed += numberOfSamples;
  274. if (samplesProcessed >= samplerate) {
  275. avgUnitsPerSecond = timeUnitsProcessed;
  276. maxUnitsPerSecond = (double(samplerate) / double(numberOfSamples)) * maxTime;
  277. samplesProcessed = timeUnitsProcessed = maxTime = 0;
  278. };
  279. */
  280. if (!silence) SuperpoweredDeInterleave(_stereoBuffer, buffers[0], buffers[1], numberOfSamples); // The stereoBuffer is ready now, let's put the finished audio into the requested buffers.
  281. // _bandConvert->process( _stereoBuffer, _tempBuffer, numberOfSamples);
  282. //M7
  283. memset( _tempBuffer, 0, 1024 *4*10);
  284. SuperpoweredFloatToShortInt(_stereoBuffer, (short int*)_tempBuffer, numberOfSamples);
  285. // for ( int j = 8192*4-1; j >=0; j--) {
  286. // if( _tempBuffer[ j ] != 0 )
  287. // {
  288. // NSLog(@"thiscopyleng:%d",j);
  289. // break;
  290. // }
  291. // }
  292. [self pushBuffer:_tempBuffer size: numberOfSamples *4 ];
  293. // if (!silence) SuperpoweredDeInterleave(_tempBuffer, buffers[0], buffers[1], numberOfSamples); // The stereoBuffer is ready now, let's put the finished audio into the requested buffers.
  294. /*
  295. memset(_tempBuffer, 0, 4096 + 128 );
  296. if (!silence) SuperpoweredDeInterleave(_stereoBuffer, buffers[0], buffers[1], numberOfSamples); // The stereoBuffer is ready now, let's put the finished audio into the requested buffers.
  297. */
  298. return !silence;
  299. }
  300. - (void)changeRt
  301. {
  302. //M8
  303. _player->setSamplerate(44100);
  304. }
  305. - (void)stopPlay
  306. {
  307. if( _player->playing )
  308. {
  309. //暂停
  310. _player->togglePlayback();
  311. [g_output setdelg:nil];
  312. }
  313. }
  314. //所有的EQ 配置,比如 @[ ASLocalizedString(@"原声"),ASLocalizedString(@"悠扬"),ASLocalizedString(@"流行")...];
  315. -(NSArray*)getAllEQSet
  316. {
  317. return _allEqNames;
  318. }
  319. - (void)pushBuffer:(char*)inbuffer size:(int)buffersize
  320. {
  321. OSSpinLockLock(&_outBufferSpinlock);
  322. if( _outBufferPushInOffset + buffersize > _outBufferSize )
  323. {
  324. memcpy( &_outDataBuffer[ _outBufferPushInOffset ] , inbuffer, _outBufferSize - _outBufferPushInOffset );
  325. memcpy( &_outDataBuffer[ 0 ] , &inbuffer [ _outBufferSize - _outBufferPushInOffset ] , buffersize - (_outBufferSize - _outBufferPushInOffset) );
  326. _outBufferPushInOffset = buffersize - (_outBufferSize - _outBufferPushInOffset);
  327. }
  328. else
  329. {
  330. memcpy( &_outDataBuffer[ _outBufferPushInOffset ] , inbuffer, buffersize );
  331. _outBufferPushInOffset += buffersize;
  332. }
  333. _outBufferNowSize += buffersize;
  334. if( _outBufferNowSize > _outBufferSize )
  335. {
  336. NSLog(@"mem full...");
  337. }
  338. //NSLog(@"_outBufferNowSize:%d",_outBufferNowSize);
  339. OSSpinLockUnlock(&_outBufferSpinlock);
  340. }
  341. //如果没有足够的 buffersize 长度数据,就不拷贝 返回0 ,等着下次,
  342. -(int)copyOutBuffer:(char*)buffer buffersize:(int)buffersize
  343. {
  344. OSSpinLockLock(&_outBufferSpinlock);
  345. if( _outBufferNowSize < buffersize )
  346. {
  347. OSSpinLockUnlock(&_outBufferSpinlock);
  348. return 0;
  349. }
  350. if( _outBufferCopyOutOffset + buffersize > _outBufferSize )
  351. {
  352. memcpy( buffer , &_outDataBuffer[ _outBufferCopyOutOffset ], _outBufferSize - _outBufferCopyOutOffset );
  353. memcpy( &buffer[ _outBufferSize - _outBufferCopyOutOffset ] , &_outDataBuffer[ 0 ], buffersize - (_outBufferSize - _outBufferCopyOutOffset) );
  354. _outBufferCopyOutOffset = buffersize - (_outBufferSize - _outBufferCopyOutOffset);
  355. }
  356. else
  357. {
  358. memcpy( buffer , &_outDataBuffer[ _outBufferCopyOutOffset ], buffersize );
  359. _outBufferCopyOutOffset += buffersize;
  360. }
  361. _outBufferNowSize -= buffersize;
  362. OSSpinLockUnlock(&_outBufferSpinlock);
  363. return buffersize;
  364. }
  365. - (void)dealloc
  366. {
  367. if( _outDataBuffer )
  368. free( _outDataBuffer );
  369. if( _stereoBuffer )
  370. free( _stereoBuffer );
  371. if( _tempBuffer)
  372. free( _tempBuffer );
  373. //M8
  374. // if( g_output )
  375. // { //这里不能 主动删除,,否则 点击 关闭,,再点歌,,,对方听不见。。无效
  376. // [g_output stop];
  377. // // g_output = nil;
  378. // }
  379. //M9
  380. // delete _player;
  381. //M10
  382. // for (int n = 2; n < NUMFXUNITS; n++) delete effects[n];
  383. // free(_stereoBuffer);
  384. //M11
  385. }
  386. /*
  387. #pragma mark - Navigation
  388. // In a storyboard-based application, you will often want to do a little preparation before navigation
  389. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  390. // Get the new view controller using [segue destinationViewController].
  391. // Pass the selected object to the new view controller.
  392. }
  393. */
  394. @end