Search code examples
c++swiftcore-audio

CoreAudio Stuff From C++ to Swift


How to convert the code below to swift? Someone help.

I want to convert this cpp code to swift, from project FreeStreamer.

But some C++ struct and some C callback drive me crazy.

Help.

Here is the code from audio_stream.h and audio_stream.cpp

    // var
    queued_packet_t *m_queuedHead;
    queued_packet_t *m_queuedTail;
    queued_packet_t *m_playPacket;

    std::list <queued_packet_t*> m_processedPackets;
    //struct
    typedef struct queued_packet {
        UInt64 identifier;
        AudioStreamPacketDescription desc;
        struct queued_packet *next;
        char data[];
    } queued_packet_t;
//function one
OSStatus Audio_Stream::encoderDataCallback(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, AudioBufferList *ioData, AudioStreamPacketDescription **outDataPacketDescription, void *inUserData) {
    Audio_Stream *THIS = (Audio_Stream *)inUserData;




    pthread_mutex_trylock(&THIS->m_packetQueueMutex);

    // Dequeue one packet per time for the decoder
    queued_packet_t *front = THIS->m_playPacket;

    if (!front) {
        /* Don't deadlock */
        AS_LOCK_TRACE("encoderDataCallback 2: unlock\n");

        pthread_mutex_unlock(&THIS->m_packetQueueMutex);

        pthread_mutex_trylock(&THIS->m_streamStateMutex);
        THIS->m_converterRunOutOfData = true;
        pthread_mutex_unlock(&THIS->m_streamStateMutex);

        *ioNumberDataPackets = 0;

        ioData->mBuffers[0].mDataByteSize = 0;

        return noErr;
    }

    *ioNumberDataPackets = 1;

    ioData->mBuffers[0].mData = front->data;
    ioData->mBuffers[0].mDataByteSize = front->desc.mDataByteSize;
    ioData->mBuffers[0].mNumberChannels = THIS->m_srcFormat.mChannelsPerFrame;

    if (outDataPacketDescription) {
        *outDataPacketDescription = &front->desc;
    }

    THIS->m_playPacket = front->next;

    THIS->m_processedPackets.push_front(front);

    AS_LOCK_TRACE("encoderDataCallback 5: unlock\n");
    pthread_mutex_unlock(&THIS->m_packetQueueMutex);

    return noErr;
}

//function two
void Audio_Stream::streamDataCallback(void *inClientData, UInt32 inNumberBytes, UInt32 inNumberPackets, const void *inInputData, AudioStreamPacketDescription *inPacketDescriptions) {
    AS_TRACE("%s: inNumberBytes %u, inNumberPackets %u\n", __FUNCTION__, (unsigned int)inNumberBytes, (unsigned int)inNumberPackets);

    Audio_Stream *THIS = static_cast<Audio_Stream*>(inClientData);

    if (!THIS->m_audioStreamParserRunning) {
        AS_TRACE("%s: stray callback detected!\n", __PRETTY_FUNCTION__);
        return;
    }

    for (int i = 0; i < inNumberPackets; i++) {
        /* Allocate the packet */
        UInt32 size = inPacketDescriptions[i].mDataByteSize;
        queued_packet_t *packet = (queued_packet_t *)malloc(sizeof(queued_packet_t) + size);

        packet->identifier = THIS->m_packetIdentifier;

        // If the stream didn't provide bitRate (m_bitRate == 0), then let's calculate it
        if (THIS->m_bitRate == 0 && THIS->m_bitrateBufferIndex < kAudioStreamBitrateBufferSize) {
            // Only keep sampling for one buffer cycle; this is to keep the counters (for instance) duration
            // stable.

            THIS->m_bitrateBuffer[THIS->m_bitrateBufferIndex++] = 8 * inPacketDescriptions[i].mDataByteSize / THIS->m_packetDuration;

            if (THIS->m_bitrateBufferIndex == kAudioStreamBitrateBufferSize) {
                if (THIS->m_delegate) {
                    THIS->m_delegate->bitrateAvailable();
                }
            }
        }

        AS_LOCK_TRACE("streamDataCallback: lock\n");
        pthread_mutex_trylock(&THIS->m_packetQueueMutex);

        /* Prepare the packet */
        packet->next = NULL;
        packet->desc = inPacketDescriptions[i];
        packet->desc.mStartOffset = 0;
        memcpy(packet->data, (const char *)inInputData + inPacketDescriptions[i].mStartOffset,
               size);

        if (THIS->m_queuedHead == NULL) {
            THIS->m_queuedHead = THIS->m_queuedTail = THIS->m_playPacket = packet;
        } else {
            THIS->m_queuedTail->next = packet;
            THIS->m_queuedTail = packet;
        }

        THIS->m_cachedDataSize += size;

        THIS->m_packetIdentifier++;

        AS_LOCK_TRACE("streamDataCallback: unlock\n");
        pthread_mutex_unlock(&THIS->m_packetQueueMutex);
    }

    THIS->determineBufferingLimits();
}

Solution

  • All the FreeStreamer project has been rewrite wieth Swift 3.0 in here FreePlayer

    Answer can be found here AudioStream