in handleReadFromStream, once eventType == kCFStreamEventEndEncountered, the music file has all been downloaded, it will change the state to AS_STOPPING or AS_STOPPED.
it seems that kCFStreamEventEndEncountered is trigged when all the music data left is in the audio buffer, and then try to CFReadStream again. So, the AS_STOPPING state depends on the whole buffer size, kNumAQBufs*kAQDefaultBufSize.
At that moment, audioBuffer may still have some buffers left to play. In my playlist app, it result in the early stop on the current song and switching to the next.
in handleReadFromStream, once eventType == kCFStreamEventEndEncountered, the music file has all been downloaded, it will change the state to AS_STOPPING or AS_STOPPED.
it seems that kCFStreamEventEndEncountered is trigged when all the music data left is in the audio buffer, and then try to CFReadStream again. So, the AS_STOPPING state depends on the whole buffer size, kNumAQBufs*kAQDefaultBufSize.
At that moment, audioBuffer may still have some buffers left to play. In my playlist app, it result in the early stop on the current song and switching to the next.