redribben

BMHttpAudioStreamManager.m

Aug 21st, 2014
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //  BMHttpAudioStreamManager.m
  2. //  Радио СВЕТ
  3. //  Created by Bogdan Michalchuk on 8/21/14.
  4. //  Copyright (c) 2014 Радио CBET. All rights reserved.
  5.  
  6. #import "BMHttpAudioStreamManager.h"
  7.  
  8.  
  9. // static void PlayCallback(void *inUserData, AudioQueueRef inAudioQueue, AudioQueueBufferRef inBuffer) {
  10.  
  11. //+ (void) playCallbackWithData:BMHttpAudioStreamManager *) inUserData
  12. //            withAudioQueueRef:inAudioQueue
  13. //        withAudioQueueBufferRef:inBuffer {
  14. //  BMHttpAudioStreamManager *player = (__bridge BMHttpAudioStreamManager *)inUserData;
  15. //  if (player.playing && player.block != nil) {
  16. //  player.block(inBuffer, player.audioFormat);
  17. //  AudioQueueEnqueueBuffer(inAudioQueue, inBuffer, 0, NULL);
  18. //  }
  19. //}
  20.  
  21. @implementation BMHttpAudioStreamManager {
  22.     CFReadStreamRef stream8;
  23.     AudioData *_audioData;
  24.     AudioQueueBufferRef _audioQueueBuffer[kNumAQBufs];      // audio queue buffers
  25.     //Located audioData in the instance variable of ViewController
  26.     //    AudioQueueRef audioQueue;
  27.  
  28. }
  29.  
  30. static const CFOptionFlags kNetworkEvents = kCFStreamEventOpenCompleted |
  31. kCFStreamEventHasBytesAvailable |
  32. kCFStreamEventEndEncountered |
  33. kCFStreamEventErrorOccurred;
  34.  
  35. #pragma mark Interruptions
  36. //static void InterruptionListenerCallback(void *inUserData, UInt32 interruptionState) {
  37. + (void) interruptionListenerCallbackWithManager:(BMHttpAudioStreamManager *) player
  38.                             withInteruptionState:(NSUInteger) interruptionState {
  39. //    BMHttpAudioStreamManager *player = (__bridge BMHttpAudioStreamManager *)inUserData;
  40.    
  41.     switch (interruptionState) {
  42.         case kAudioSessionBeginInterruption:
  43.             [player tearDownAudio];
  44.             break;
  45.            
  46.         case kAudioSessionEndInterruption:
  47.             [player setUpAudio];
  48.             [player start];
  49.             break;
  50.     }
  51. }
  52.  
  53.  
  54. //int MyFindQueueBuffer(AudioData* audioData, AudioQueueBufferRef inBuffer) {
  55. + (int) myFindQueueBufferWithAudioData:(AudioData *) audioData
  56.                             withBuffer:(AudioQueueBufferRef) inBuffer {
  57.     for (unsigned int i = 0; i < kNumAQBufs; ++i) {
  58.         if (inBuffer == audioData->audioQueueBuffer[i]) return i;
  59.     }
  60.     return -1;
  61. }
  62.  
  63. // Called by the system when an audio queue buffer is available for reuse.
  64. void MyAudioQueueOutputCallback(void*               inUserData,
  65.                                 AudioQueueRef       inAQ,
  66.                                 AudioQueueBufferRef inBuffer) {
  67.     BMHttpAudioStreamManager *manager = (__bridge BMHttpAudioStreamManager*) inUserData;
  68.     [manager myAudioQueueOutputCallback: inAQ buffer: inBuffer];
  69. }
  70.  
  71. - (void) myAudioQueueOutputCallback:(AudioQueueRef) inAQ
  72.                            buffer:(AudioQueueBufferRef) inBuffer {
  73.  
  74.     // this is called by the audio queue when it has finished decoding our data.
  75.     // The buffer is now free to be reused.
  76.     // unsigned int bufIndex = MyFindQueueBuffer(audioData, (AudioQueueBufferRef) inBuffer);
  77.     unsigned int bufIndex = [BMHttpAudioStreamManager myFindQueueBufferWithAudioData: _audioData
  78.                                                                           withBuffer: inBuffer];
  79.    
  80.     // signal waiting thread that the buffer is free.
  81.     pthread_mutex_lock(&(_audioData->mutex));
  82.     _audioData->inuse[bufIndex] = false;
  83.     pthread_cond_signal(&(_audioData->cond));
  84.     pthread_mutex_unlock(&(_audioData->mutex));
  85. }
  86.  
  87.  
  88.  
  89. //OSStatus StartQueueIfNeeded(AudioData* audioData) {
  90. + (OSStatus) startQueueIfNeededWithData:(AudioData *) audioData {
  91.     OSStatus err = noErr;
  92.     if (!audioData->started) {      // start the queue if it has not been started already
  93.         if ((err = AudioQueueStart(audioData->audioQueue, NULL))) {
  94.             PRINTERROR("AudioQueueStart");
  95.             audioData->failed = true;
  96.             //return err;
  97.             return err;
  98.         }
  99.         audioData->started = true;
  100.         NSLog(@"started");
  101.     }
  102.     return err;
  103. }
  104.  
  105.  
  106. /**/
  107. // OSStatus MyEnqueueBuffer(AudioData* audioData) {
  108. // Conversion done 10.6.14
  109.  
  110. +(OSStatus) myEnqueueBufferWithData:(AudioData *) audioData {
  111.  OSStatus err = noErr;
  112.  audioData->inuse[audioData->fillBufferIndex] = true;       // set in use flag
  113.  
  114.  // enqueue buffer
  115.  AudioQueueBufferRef fillBuf = audioData->audioQueueBuffer[audioData->fillBufferIndex];
  116.  fillBuf->mAudioDataByteSize = audioData->bytesFilled;
  117.  err = AudioQueueEnqueueBuffer(audioData->audioQueue, fillBuf, audioData->packetsFilled, audioData->packetDescs);
  118.  if (err) {
  119.  PRINTERROR("AudioQueueEnqueueBuffer");
  120.  audioData->failed = true;
  121.  return err;
  122.  }
  123.  
  124.  /* Dont know what I was trying to do with this code here
  125.  AudioQueueStart(audioData->audioQueue, NULL);       // Way to bypass
  126.  (audioData);
  127.   */
  128. [BMHttpAudioStreamManager startQueueIfNeededWithData:audioData];
  129.  
  130. /*
  131. Moved this section to "setUpAudioSession" method
  132.  // Allows Audio to play when phone is put to sleep or working in other apps and silent slider
  133.  UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
  134.  AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
  135.  [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; // Allows to manage from locked screen
  136.  AudioSessionSetActive(true);
  137.  */
  138.  return err;
  139.  }
  140.  
  141.  
  142. //void WaitForFreeBuffer(AudioData* audioData)  {
  143. + (void) waitForFreeBufferForData:(AudioData *) audioData {
  144.     // go to next buffer
  145.     if (++audioData->fillBufferIndex >= kNumAQBufs) audioData->fillBufferIndex = 0;
  146.     audioData->bytesFilled = 0;     // reset bytes filled
  147.     audioData->packetsFilled = 0;       // reset packets filled
  148.     /*
  149.      // wait until next buffer is not in use
  150.      printf("->lock\n");
  151.      pthread_mutex_lock(&audioData->mutex);
  152.      while (audioData->inuse[audioData->fillBufferIndex])      // When flag is set for filled
  153.      {
  154.      printf("... WAITING ...\n");
  155.      pthread_cond_wait(&audioData->cond, &audioData->mutex);
  156.      }
  157.      pthread_mutex_unlock(&audioData->mutex);
  158.      printf("<-unlock\n");
  159.      */
  160. }
  161.  
  162.  
  163.  
  164. void MyAudioQueueIsRunningCallback(void*                 inClientData,
  165.                                       AudioQueueRef         inAQ,
  166.                                       AudioQueuePropertyID  inID) {
  167.     BMHttpAudioStreamManager *manager = (__bridge BMHttpAudioStreamManager*) inClientData;
  168.     [manager myAudioQueuePropertyListenerProcWithRef: inAQ withPropertyID: inID];
  169. }
  170.    
  171. - (void) myAudioQueuePropertyListenerProcWithRef:(AudioQueueRef) inAQ
  172.                                 withPropertyID:(AudioQueuePropertyID) inID {    
  173.     UInt32 running, size;
  174.     OSStatus err = AudioQueueGetProperty(inAQ, kAudioQueueProperty_IsRunning, &running, &size);
  175.     if (err) {
  176.         PRINTERROR("get kAudioQueueProperty_IsRunning");
  177.         return;
  178.     }
  179.     if (!running) {
  180.         pthread_mutex_lock(&_audioData->mutex);
  181.         pthread_cond_signal(&_audioData->done);
  182.         pthread_mutex_unlock(&_audioData->mutex);
  183.     }
  184. }
  185.  
  186. void MyPropertyListenerProc(void                        *inUserData,
  187.                             AudioFileStreamID           inAudioFileStream,
  188.                             AudioFileStreamPropertyID   inPropertyID,
  189.                             UInt32                      *ioFlags) {
  190.     BMHttpAudioStreamManager *manager = (__bridge BMHttpAudioStreamManager*) inUserData;
  191.     [manager myPropertyListenerProcForStreamID:inAudioFileStream forPropertyID:inPropertyID forIOFlags:ioFlags];
  192. }
  193.  
  194. - (void) myPropertyListenerProcForStreamID:(AudioFileStreamID) inAudioFileStream
  195.                        forPropertyID:(AudioFileStreamPropertyID) inPropertyID
  196.                           forIOFlags:(UInt32 *) ioFlags {
  197.     // this is called by audio file stream when it finds property values
  198.         OSStatus err = noErr;
  199.     printf("found property '%c%c%c%c'\n", (char)(inPropertyID>>24)&255, (char)(inPropertyID>>16)&255, (char)(inPropertyID>>8)&255, (char)inPropertyID&255);
  200.    
  201.     if (inPropertyID == kAudioFileStreamProperty_ReadyToProducePackets) {
  202.         // the file stream parser is now ready to produce audio packets.
  203.         // get the stream format.
  204.         AudioStreamBasicDescription asbd;
  205.         UInt32 asbdSize = sizeof(asbd);
  206.         err = AudioFileStreamGetProperty(inAudioFileStream, kAudioFileStreamProperty_DataFormat, &asbdSize, &asbd);
  207.         if (err) {
  208.             PRINTERROR("get kAudioFileStreamProperty_DataFormat");
  209.             _audioData->failed = true;
  210.             return;
  211.         }
  212.        
  213.         // create the audio queue
  214.         err = AudioQueueNewOutput(&asbd, MyAudioQueueOutputCallback, (__bridge void *)(self), NULL, NULL, 0, &(_audioData->audioQueue));
  215.         if (err) { PRINTERROR("AudioQueueNewOutput");
  216.             _audioData->failed = true;
  217.             return;
  218.         }
  219.        
  220.         // allocate audio queue buffers
  221.         for (unsigned int i = 0; i < kNumAQBufs; ++i) {
  222.             err = AudioQueueAllocateBuffer(_audioData->audioQueue, kAQBufSize, &_audioData->audioQueueBuffer[i]);
  223.             if (err) { PRINTERROR("AudioQueueAllocateBuffer");
  224.                 _audioData->failed = true;
  225.                 break;
  226.             }
  227.         }
  228.        
  229.         // get the cookie size
  230.         UInt32 cookieSize;
  231.         Boolean writable;
  232.         err = AudioFileStreamGetPropertyInfo(inAudioFileStream, kAudioFileStreamProperty_MagicCookieData, &cookieSize, &writable);
  233.         if (err) {
  234.             PRINTERROR("info kAudioFileStreamProperty_MagicCookieData");
  235.             return;
  236.         }
  237.         printf("cookieSize %d\n", (unsigned int)cookieSize);
  238.        
  239.         // get the cookie data
  240.         void* cookieData = calloc(1, cookieSize);
  241.         err = AudioFileStreamGetProperty(inAudioFileStream, kAudioFileStreamProperty_MagicCookieData, &cookieSize, cookieData);
  242.         if (err) {
  243.             PRINTERROR("get kAudioFileStreamProperty_MagicCookieData");
  244.             free(cookieData);
  245.             return;
  246.         }
  247.        
  248.         // set the cookie on the queue.
  249.         err = AudioQueueSetProperty(_audioData->audioQueue, kAudioQueueProperty_MagicCookie, cookieData, cookieSize);
  250.         free(cookieData);
  251.         if (err) {
  252.             PRINTERROR("set kAudioQueueProperty_MagicCookie");
  253.             return;
  254.         }
  255.        
  256.         // listen for kAudioQueueProperty_IsRunning
  257.         err = AudioQueueAddPropertyListener(_audioData->audioQueue, kAudioQueueProperty_IsRunning, MyAudioQueueIsRunningCallback, _audioData);
  258.         if (err) { PRINTERROR("AudioQueueAddPropertyListener");
  259.             _audioData->failed = true;
  260.             return;
  261.         }
  262.     }
  263. }
  264.  
  265. void ReadStreamClientCallBack(CFReadStreamRef   stream,
  266.                           CFStreamEventType     type,
  267.                           void*                 clientCallBackInfo) {
  268.     BMHttpAudioStreamManager *manager = (__bridge BMHttpAudioStreamManager*) clientCallBackInfo;
  269.     [manager readStreamClientCallBackWithData:stream withType:type];
  270. }
  271.  
  272. - (void) readStreamClientCallBackWithData:(CFReadStreamRef) stream
  273.                                  withType:(CFStreamEventType) type {
  274.    
  275.     if(type == kCFStreamEventHasBytesAvailable) {
  276.         UInt8 buffer[2048];
  277.         CFIndex bytesRead = CFReadStreamRead(stream, buffer, sizeof(buffer));
  278.        
  279.         if (bytesRead < 0) {
  280.             //nothing
  281.         }
  282.         // If zero bytes were read, wait for the EOF to come.
  283.         else if (bytesRead) {
  284.             // parse the data. this will call MyPropertyListenerProc and MyPacketsProc
  285.             // AudioFileStreamParseBytes function called when you have data to pass to the parser.
  286.             // Send the data to the parser sequentially and, if possible, without gaps.
  287.             OSStatus err = AudioFileStreamParseBytes(_audioData->audioFileStream, bytesRead, buffer, 0);
  288. /*   This is what I had before, before I changed it to work 10.13.14
  289.             OSStatus err = AudioFileStreamParseBytes(((AudioData *) audioData)->audioFileStream, bytesRead, buffer, 0);
  290. */
  291.             if (err) PRINTERROR("AudioFileStreamParseBytes");
  292.         }
  293.     }
  294. }
  295.  
  296. void MyPacketsProc(void *                           inClientData,
  297.                    UInt32                           inNumberBytes,
  298.                    UInt32                           inNumberPackets,
  299.                    const void *                     inInputData,
  300.                    AudioStreamPacketDescription     *inPacketDescriptions) {
  301.     BMHttpAudioStreamManager *manager = (__bridge BMHttpAudioStreamManager*) inClientData;
  302.     [manager myPacketsProcforNumberBytes: inNumberBytes forNumberPackets: inNumberPackets forInputData: inInputData withPacketDescription: inPacketDescriptions];
  303. }
  304.  
  305. - (void) myPacketsProcforNumberBytes:(UInt32) inNumberBytes
  306.               forNumberPackets:(UInt32) inNumberPackets
  307.                   forInputData:(const void *) inInputData
  308.          withPacketDescription:(AudioStreamPacketDescription *) inPacketDescriptions {
  309.  
  310. //    if (viewController.connectionStopped) {
  311. //        return;
  312. //    }
  313.    
  314.     // this is called by audio file stream when it finds packets of audio
  315.     printf("got data.  bytes: %d  packets: %d\n", (unsigned int)inNumberBytes, (unsigned int)inNumberPackets);
  316.    
  317.     // the following code assumes we're streaming VBR data. for CBR data, you'd need another code branch here.
  318.     for (int i = 0; i < inNumberPackets; ++i) {
  319.         SInt64 packetOffset = inPacketDescriptions[i].mStartOffset;
  320.         SInt64 packetSize   = inPacketDescriptions[i].mDataByteSize;
  321.        
  322.         // if the space remaining in the buffer is not enough for this packet, then enqueue the buffer.
  323.         size_t bufSpaceRemaining = kAQBufSize - _audioData->bytesFilled;
  324.         if (bufSpaceRemaining < packetSize/* && !viewController.connectionStopped*/) {
  325. // I changed this line of code to objc 10.6.14            MyEnqueueBuffer(audioData);
  326.             [BMHttpAudioStreamManager myEnqueueBufferWithData:_audioData];
  327. // I changed this line of code to objc 10.6.14            WaitForFreeBuffer(audioData);
  328.             [BMHttpAudioStreamManager waitForFreeBufferForData:_audioData];
  329.         }
  330.        
  331.         // copy data to the audio queue buffer
  332.         AudioQueueBufferRef fillBuf = _audioData->audioQueueBuffer[_audioData->fillBufferIndex];
  333.         memcpy((char*)fillBuf->mAudioData + _audioData->bytesFilled, (const char*)inInputData + packetOffset, packetSize);
  334.         // fill out packet description
  335.         _audioData->packetDescs[_audioData->packetsFilled] = inPacketDescriptions[i];
  336.         _audioData->packetDescs[_audioData->packetsFilled].mStartOffset = _audioData->bytesFilled;
  337.         // keep track of bytes filled and packets filled
  338.         _audioData->bytesFilled += packetSize;
  339.         _audioData->packetsFilled += 1;
  340.        
  341.         // if that was the last free packet description, then enqueue the buffer.
  342.         size_t packetsDescsRemaining = kAQMaxPacketDescs - _audioData->packetsFilled;
  343.         if (packetsDescsRemaining == 0/* && !BMHttpAudioStreamManager.connectionStopped*/) {
  344. // I changed this line of code to objc 10.6.14            MyEnqueueBuffer(audioData);
  345.             [BMHttpAudioStreamManager myEnqueueBufferWithData:_audioData];
  346. // I changed this line of code to objc 10.6.14            WaitForFreeBuffer(audioData);
  347.             [BMHttpAudioStreamManager waitForFreeBufferForData:_audioData];        }
  348.     }
  349. }
  350.  
  351.  
  352. #pragma mark connectionStart
  353. -(void) connectionStart {
  354.    
  355.     self.playButtonClicked = YES; //this is where it says that stream is playing.
  356.     NSLog(@"%s", "Hello");
  357.    
  358.     @try {
  359.        
  360.         // allocate a struct for storing our state
  361.         _audioData = (AudioData*)calloc(1, sizeof(AudioData));
  362.        
  363.         // initialize a mutex and condition so that we can block on buffers in use.
  364.         pthread_mutex_init(&_audioData->mutex, NULL);
  365.         pthread_cond_init(&_audioData->cond, NULL);
  366.         pthread_cond_init(&_audioData->done, NULL);
  367.        
  368.         // create an audio file stream parser
  369.         OSStatus err = AudioFileStreamOpen((__bridge void *)(self), MyPropertyListenerProc, MyPacketsProc,
  370.                                            kAudioFileMP3Type, &_audioData->audioFileStream);
  371.         if (err) { PRINTERROR("AudioFileStreamOpen"); //return 1;
  372.         }
  373.  
  374.        
  375.         CFStreamClientContext ctxt = {0, (__bridge void*)self, NULL, NULL, NULL};
  376.        
  377.         CFStringRef bodyData = CFSTR(""); // Usually used for POST data
  378.         CFStringRef headerFieldName = CFSTR("X-My-Favorite-Field");
  379.         CFStringRef headerFieldValue = CFSTR("Dreams");
  380.        
  381.         CFStringRef url = CFSTR(RADIO_LOCATION);
  382.         CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, url, NULL);
  383.         CFStringRef requestMethod = CFSTR("GET");
  384.         CFHTTPMessageRef myRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, myURL, kCFHTTPVersion1_1);
  385.        
  386.         CFHTTPMessageSetBody(myRequest, (CFDataRef)bodyData);
  387.         CFHTTPMessageSetHeaderFieldValue(myRequest, headerFieldName, headerFieldValue);
  388.        
  389.         //CFDataRef mySerializedRequest = CFHTTPMessageCopySerializedMessage(myRequest);
  390.        
  391.         // Create the stream for the request.
  392.        
  393.        
  394.         //      CFReadStreamRef stream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest);
  395.        
  396.        
  397.         stream8
  398.         = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest);
  399.        
  400.         NSLog(@"Stage 3");
  401.        
  402.         if (!stream8) {
  403.             NSLog(@"Creating the stream failed");
  404.             return;
  405.         }
  406.        
  407.         // Use persistent conections so connection-based authentications work correctly.
  408.         //CFReadStreamSetProperty(stream, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue);
  409.        
  410.         // Set the client
  411.         if (!CFReadStreamSetClient(stream8, kNetworkEvents, ReadStreamClientCallBack, &ctxt)) {
  412.             CFRelease(stream8);
  413.             NSLog(@"Setting the stream's client failed.");
  414.             return;
  415.         }
  416.        
  417.         // Schedule the stream
  418.         CFReadStreamScheduleWithRunLoop(stream8, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
  419.        
  420.         // Start the HTTP connection
  421.         if (!CFReadStreamOpen(stream8)) {
  422.             CFReadStreamSetClient(stream8, 0, NULL, NULL);
  423.             CFReadStreamUnscheduleFromRunLoop(stream8, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
  424.             CFRelease(stream8);
  425.             NSLog(@"Opening the stream failed.");
  426.             return;
  427.          
  428.         }
  429.        
  430.        /*
  431.         // Don't need the old stream any more.
  432.        // if (stream && [self connectionStopped]) {
  433.         if (stream8) {
  434.             CFReadStreamClose(stream8);
  435.             CFRelease(stream8);
  436.        } */
  437.     }
  438.     @catch (NSException *exception) {
  439.         NSLog(@"main: Caught %@: %@", [exception name],  [exception reason]);
  440.        
  441.     }
  442. }
  443.  
  444. #pragma mark - View lifecycle
  445.  
  446. /*
  447.  //I enable this section so I could pause
  448.  -(void) resumeRadio {       //example for resume radio stream
  449.  NSLog(@"Resuming stream...");
  450.  OSStatus  err = AudioQueueStart(audioData->audioQueue, NULL);
  451.  if (err) { PRINTERROR("AudioQueueStart"); audioData->failed = true; //return err;
  452.  }
  453.  }
  454.  
  455.  -(void) pauseRadio { //example for pause radio stream
  456.  
  457.  NSLog(@"stream paused");
  458.  OSStatus  err = AudioQueuePause(audioData->audioQueue);
  459.  if (err) { PRINTERROR("AudioQueueStart"); audioData->failed = true; //return err;
  460.  }
  461.  if (stream) {
  462.  CFReadStreamClose(stream);
  463.  CFRelease(stream);
  464.  stream = nil;
  465.  }
  466.  }
  467.  */
  468.  
  469. #pragma mark stopRadio
  470. - (void) stopRadio {
  471.     self.connectionStopped = YES; //this is where it says that connection was stopped
  472.     AudioQueueStop(_audioData->audioQueue, TRUE);
  473.     AudioQueueDispose(_audioData->audioQueue, TRUE);
  474.     [self tearDownAudio];
  475.     //    [self tearDownPlayQueue];
  476.    
  477. }
  478.  
  479. -(void)tearDownPlayQueue {
  480.     AudioQueueDispose(_audioData->audioQueue, YES);
  481.     _audioData->audioQueue = NULL;
  482. }
  483.  
  484. #pragma mark - from hollance code
  485.  - (void)tearDownAudioSession {
  486.      [[AVAudioSession sharedInstance] setActive:false error:nil];
  487. // AudioSessionSetActive(false);
  488.      CFReadStreamClose(stream8);
  489.      CFRelease(stream8);
  490.      stream8 = NULL;
  491.  }
  492.  
  493.  - (void)tearDownAudio {
  494.      if (_audioData != NULL)
  495.      {
  496.          [self tearDownPlayQueue];
  497.          [self tearDownAudioSession];
  498.      }
  499.  }
  500.  
  501.  
  502.  - (void)stopAudio {
  503.      {
  504.          NSLog(@"STOPPED");
  505.          AudioQueueStop(_audioData, TRUE);
  506.          [self tearDownAudio];
  507.          self.playing = NO;
  508.      }
  509.  }
  510.  
  511.  
  512.  - (void)start {
  513.      if (!self.playing) {
  514.         self.playing = YES;
  515. //         AudioQueueStart(_audioData->audioQueue, NULL);
  516.         [self connectionStart];
  517.         [self setUpAudio];
  518.              }
  519.  }
  520.  
  521. /*- (void)primePlayQueueBuffers
  522. {
  523.     for (int i = 0; i < kNumAQBufs; ++i)
  524.     {
  525.         MyAudioQueueOutputCallback((__bridge void *)self, _audioData, _audioQueueBuffer[i]);
  526.     }
  527. }
  528. */
  529.  
  530. - (void)setUpAudio
  531. {
  532.     if (_audioData == NULL)
  533.     {
  534. //        [self setUpAVAudioSession];
  535. //        [self setUpPlayQueue];
  536. //        [self setUpPlayQueueBuffers];
  537.     }
  538. }
  539.  
  540. #pragma mark - Remote control and AVAudioSession
  541. - (void)initAVAudioSession {
  542.     //Allows the audio to be played
  543.     AVAudioSession *audioSession = [AVAudioSession sharedInstance];
  544.     NSError *setCategoryError = nil;
  545.     BOOL success = [audioSession setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
  546.     if (!success) { /* handle the error condition */ }
  547.    
  548.     NSError *activationError = nil;
  549.     success = [audioSession setActive:YES error:&activationError];
  550.     if (!success) { /* handle the error condition */ }
  551.     [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; // Allows to manage from locked screen
  552. NSLog(@"Went through");
  553.  
  554. /* ! What code I used for ios7
  555.     // Allows Audio to play when phone is put to sleep or working in other apps and silent slider
  556.     UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
  557.     AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
  558.     [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; // Allows to manage from locked screen
  559.     AudioSessionSetActive(true);
  560. */
  561. }
  562.  
  563. - (void)remoteControlReceivedWithEvent:(UIEvent *)theEvent {
  564.     if (theEvent.type == UIEventTypeRemoteControl) {
  565.         switch(theEvent.subtype) {
  566.             case UIEventSubtypeRemoteControlTogglePlayPause:
  567.                 //Insert code
  568.             case UIEventSubtypeRemoteControlPlay:
  569.                 [self start];
  570.                 break;
  571.             case UIEventSubtypeRemoteControlPause:
  572.                 [self stopAudio];
  573.                 break;
  574.             case UIEventSubtypeRemoteControlStop:
  575.                 [self stopAudio];
  576.                 break;
  577.             default:
  578.                 return;
  579.         }
  580.     }
  581. }
  582.  
  583. /*
  584.  - (void)readyPlayQueueBuffers {
  585.     for (int t = 0; t < kNumAQBufs; ++t) {
  586.         PlayCallback((__bridge void *)self, _audioData, _audioQueueBuffer[kNumAQBufs]);
  587.     }
  588. }
  589. */
  590.  
  591. @end
Advertisement
Add Comment
Please, Sign In to add comment