ConcatenatingAudioSource.m 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #import "AudioSource.h"
  2. #import "ConcatenatingAudioSource.h"
  3. #import <AVFoundation/AVFoundation.h>
  4. #import <stdlib.h>
  5. @implementation ConcatenatingAudioSource {
  6. NSMutableArray<AudioSource *> *_audioSources;
  7. NSMutableArray<NSNumber *> *_shuffleOrder;
  8. }
  9. - (instancetype)initWithId:(NSString *)sid audioSources:(NSMutableArray<AudioSource *> *)audioSources {
  10. self = [super initWithId:sid];
  11. NSAssert(self, @"super init cannot be nil");
  12. _audioSources = audioSources;
  13. return self;
  14. }
  15. - (int)count {
  16. return _audioSources.count;
  17. }
  18. - (void)insertSource:(AudioSource *)audioSource atIndex:(int)index {
  19. [_audioSources insertObject:audioSource atIndex:index];
  20. }
  21. - (void)removeSourcesFromIndex:(int)start toIndex:(int)end {
  22. if (end == -1) end = _audioSources.count;
  23. for (int i = start; i < end; i++) {
  24. [_audioSources removeObjectAtIndex:start];
  25. }
  26. }
  27. - (void)moveSourceFromIndex:(int)currentIndex toIndex:(int)newIndex {
  28. AudioSource *source = _audioSources[currentIndex];
  29. [_audioSources removeObjectAtIndex:currentIndex];
  30. [_audioSources insertObject:source atIndex:newIndex];
  31. }
  32. - (int)buildSequence:(NSMutableArray *)sequence treeIndex:(int)treeIndex {
  33. for (int i = 0; i < [_audioSources count]; i++) {
  34. treeIndex = [_audioSources[i] buildSequence:sequence treeIndex:treeIndex];
  35. }
  36. return treeIndex;
  37. }
  38. - (void)findById:(NSString *)sourceId matches:(NSMutableArray<AudioSource *> *)matches {
  39. [super findById:sourceId matches:matches];
  40. for (int i = 0; i < [_audioSources count]; i++) {
  41. [_audioSources[i] findById:sourceId matches:matches];
  42. }
  43. }
  44. - (NSArray *)getShuffleOrder {
  45. NSMutableArray *order = [NSMutableArray new];
  46. int offset = [order count];
  47. NSMutableArray *childOrders = [NSMutableArray new]; // array of array of ints
  48. for (int i = 0; i < [_audioSources count]; i++) {
  49. AudioSource *audioSource = _audioSources[i];
  50. NSArray *childShuffleOrder = [audioSource getShuffleOrder];
  51. NSMutableArray *offsetChildShuffleOrder = [NSMutableArray new];
  52. for (int j = 0; j < [childShuffleOrder count]; j++) {
  53. [offsetChildShuffleOrder addObject:@([childShuffleOrder[j] integerValue] + offset)];
  54. }
  55. [childOrders addObject:offsetChildShuffleOrder];
  56. offset += [childShuffleOrder count];
  57. }
  58. for (int i = 0; i < [_audioSources count]; i++) {
  59. [order addObjectsFromArray:childOrders[[_shuffleOrder[i] integerValue]]];
  60. }
  61. return order;
  62. }
  63. - (int)shuffle:(int)treeIndex currentIndex:(int)currentIndex {
  64. int currentChildIndex = -1;
  65. for (int i = 0; i < [_audioSources count]; i++) {
  66. int indexBefore = treeIndex;
  67. AudioSource *child = _audioSources[i];
  68. treeIndex = [child shuffle:treeIndex currentIndex:currentIndex];
  69. if (currentIndex >= indexBefore && currentIndex < treeIndex) {
  70. currentChildIndex = i;
  71. } else {}
  72. }
  73. // Shuffle so that the current child is first in the shuffle order
  74. _shuffleOrder = [NSMutableArray arrayWithCapacity:[_audioSources count]];
  75. for (int i = 0; i < [_audioSources count]; i++) {
  76. [_shuffleOrder addObject:@(0)];
  77. }
  78. NSLog(@"shuffle: audioSources.count=%d and shuffleOrder.count=%d", [_audioSources count], [_shuffleOrder count]);
  79. // First generate a random shuffle
  80. for (int i = 0; i < [_audioSources count]; i++) {
  81. int j = arc4random_uniform(i + 1);
  82. _shuffleOrder[i] = _shuffleOrder[j];
  83. _shuffleOrder[j] = @(i);
  84. }
  85. // Then bring currentIndex to the front
  86. if (currentChildIndex != -1) {
  87. for (int i = 1; i < [_audioSources count]; i++) {
  88. if ([_shuffleOrder[i] integerValue] == currentChildIndex) {
  89. NSNumber *v = _shuffleOrder[0];
  90. _shuffleOrder[0] = _shuffleOrder[i];
  91. _shuffleOrder[i] = v;
  92. break;
  93. }
  94. }
  95. }
  96. return treeIndex;
  97. }
  98. @end