long AudioStreamDecoder::Stop()
{
	long err = 0;

	if (mStream)
	{
		err = AudioFileStreamClose(mStream);
		CARP_IF(err, "AudioFileStreamClose returned %ld\n", err);

		mStream = NULL;
	}

	if (mStarted)
	{
		err = AudioQueueFlush(mQueue);
		BAIL_IF(err, "AudioQueueFlush returned %ld\n", err);

		err = AudioQueueStop(mQueue, true);
		BAIL_IF(err, "AudioQueueStop returned %ld\n", err);

		err = pthread_mutex_lock(&mMutex);
		BAIL_IF(err, "pthread_mutex_lock returned %ld\n", err);

		if (!mFinished)
		{
			err = pthread_cond_wait(&mCond, &mMutex);
			BAIL_IF(err, "pthread_cond_wait returned %ld\n", err);
		}

		err = pthread_mutex_unlock(&mMutex);
		BAIL_IF(err, "pthread_mutex_unlock returned %ld\n", err);

		mStarted = false;
		mFinished = false;
	}

	if (mQueue)
	{
		for (int i = 0; i < kBufferCount; i++)
		{
			if (mBuffers[i])
			{
				err = AudioQueueFreeBuffer(mQueue, mBuffers[i]);
				CARP_IF(err, "AudioQueueFreeBuffer returned %ld\n", err);
			}
		}

		err = AudioQueueDispose(mQueue, true);
		CARP_IF(err, "AudioQueueDispose returned %ld\n", err);

		mQueue = NULL;
	}

bail:
	return err;
}
void AudioStreamDecoder::PacketCallback(UInt32 byteCount, UInt32 packetCount, const void* data, AudioStreamPacketDescription* packetDescriptions)
{
	long err;

	// Constant bit rate audio arrives without packet descriptions.
	while (!packetDescriptions && !mFinished && byteCount)
	{
		unsigned int copyCount = byteCount;
		if (copyCount > (*mCurrentBuffer)->mAudioDataBytesCapacity - (*mCurrentBuffer)->mAudioDataByteSize)
			copyCount = (*mCurrentBuffer)->mAudioDataBytesCapacity - (*mCurrentBuffer)->mAudioDataByteSize;

		memcpy((unsigned char*)(*mCurrentBuffer)->mAudioData + (*mCurrentBuffer)->mAudioDataByteSize, data, copyCount);
		byteCount -= copyCount;
		(*mCurrentBuffer)->mAudioDataByteSize += copyCount;

		if ((*mCurrentBuffer)->mAudioDataByteSize == (*mCurrentBuffer)->mAudioDataBytesCapacity)
		{
			err = EnqueueBuffer();
			BAIL_IF(err, "EnqueueBuffer returned %ld\n", err);
		}
	}

	if (!packetDescriptions)
		return;

	// Variable bit rate audio has a description for every packet.
	for (unsigned int i = 0; !mFinished && i < packetCount; i++)
	{
		if (packetDescriptions[i].mDataByteSize > (*mCurrentBuffer)->mAudioDataBytesCapacity - (*mCurrentBuffer)->mAudioDataByteSize)
		{
			err = EnqueueBuffer();
			BAIL_IF(err, "EnqueueBuffer returned %ld\n", err);
		}

		if (mFinished)
			break;

		memcpy((unsigned char*)(*mCurrentBuffer)->mAudioData + (*mCurrentBuffer)->mAudioDataByteSize,
			   (const unsigned char*)data + packetDescriptions[i].mStartOffset,
			   packetDescriptions[i].mDataByteSize);
		(*mCurrentBuffer)->mPacketDescriptions[(*mCurrentBuffer)->mPacketDescriptionCount] = packetDescriptions[i];
		(*mCurrentBuffer)->mPacketDescriptions[(*mCurrentBuffer)->mPacketDescriptionCount].mStartOffset = (*mCurrentBuffer)->mAudioDataByteSize;
		(*mCurrentBuffer)->mAudioDataByteSize += packetDescriptions[i].mDataByteSize;
		(*mCurrentBuffer)->mPacketDescriptionCount++;

		if ((*mCurrentBuffer)->mPacketDescriptionCount == (*mCurrentBuffer)->mPacketDescriptionCapacity)
		{
			err = EnqueueBuffer();
			BAIL_IF(err, "EnqueueBuffer returned %ld\n", err);
		}
	}

bail:
	return;
}
long AudioStreamDecoder::Init()
{
	long err = pthread_mutex_init(&mMutex, NULL);
	BAIL_IF(err, "pthread_mutex_init returned %ld\n", err);

	err = pthread_cond_init(&mCond, NULL);
	BAIL_IF(err, "pthread_cond_init returned %ld\n", err);

bail:
	return err;
}
long AudioStreamDecoder::EnqueueBuffer()
{
	bool locked = false;

	if (mFinished)
		return 0;

	long err = AudioQueueEnqueueBuffer(mQueue, *mCurrentBuffer, 0, NULL);
	BAIL_IF(err, "AudioQueueEnqueueBuffer returned %ld\n", err);

	if (++mCurrentBuffer == mBuffers + kBufferCount)
		mCurrentBuffer = mBuffers;

	if (!mStarted && !mFinished)
	{
		mStarted = true;

		err = AudioQueueStart(mQueue, NULL);
		BAIL_IF(err, "AudioQueueStart returned %ld\n", err);
	}

	err = pthread_mutex_lock(&mMutex);
	BAIL_IF(err, "pthread_mutex_lock returned %ld\n", err);

	locked = true;

	while ((*mCurrentBuffer)->mUserData && !mFinished)
	{
		err = pthread_cond_wait(&mCond, &mMutex);
		BAIL_IF(err, "pthread_cond_wait returned %ld\n", err);
	}

	(*mCurrentBuffer)->mUserData = this;
	(*mCurrentBuffer)->mAudioDataByteSize = 0;
	(*mCurrentBuffer)->mPacketDescriptionCount = 0;

bail:
	long err2;

	if (locked)
	{
		err2 = pthread_mutex_unlock(&mMutex);
		CARP_IF(err2, "pthread_mutex_unlock returned %ld\n", err2);
	}

	if (err && mStarted)
	{
		err2 = SetFinished();
		CARP_IF(err2, "SetFinished returned %ld\n", err2);
	}

	return err;
}
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
{
    image_info info;
    int32 cookie = 0;

    while (get_next_image_info(0, &cookie, &info) == B_OK)
    {
        if (info.type == B_APP_IMAGE)
            break;
    } /* while */

    BEntry entry(info.name, true);
    BPath path;
    status_t rc = entry.GetPath(&path);  /* (path) now has binary's path. */
    assert(rc == B_OK);
    rc = path.GetParent(&path); /* chop filename, keep directory. */
    assert(rc == B_OK);
    const char *str = path.Path();
    assert(str != NULL);
    const size_t len = strlen(str);
    char *retval = (char *) allocator.Malloc(len + 2);
    BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
    strcpy(retval, str);
    retval[len] = '/';
    retval[len+1] = '\0';
    return retval;
} /* __PHYSFS_platformCalcBaseDir */
void AudioStreamDecoder::StaticBufferCompleteCallback(void* context, AudioQueueRef queue, AudioQueueBufferRef buffer)
{
	BAIL_IF(!context, "Invalid context pointer\n", context);
	((AudioStreamDecoder*)context)->BufferCompleteCallback(queue, buffer);

bail:
	return;
}
void AudioStreamDecoder::StaticQueueRunningCallback(void* context, AudioQueueRef queue, AudioQueuePropertyID property)
{
	BAIL_IF(!context, "Invalid context pointer\n", context);
	((AudioStreamDecoder*)context)->QueueRunningCallback(queue, property);

bail:
	return;
}
void AudioStreamDecoder::StaticPropertyCallback(void* context, AudioFileStreamID stream, AudioFileStreamPropertyID property, UInt32* flags)
{
	BAIL_IF(!context, "Invalid context pointer\n", context);
	((AudioStreamDecoder*)context)->PropertyCallback(stream, property, flags);

bail:
	return;
}
void AudioStreamDecoder::StaticPacketCallback(void* context, UInt32 byteCount, UInt32 packetCount, const void* data, AudioStreamPacketDescription* packetDescriptions)
{
	BAIL_IF(!context, "Invalid context pointer\n", context);
	((AudioStreamDecoder*)context)->PacketCallback(byteCount, packetCount, data, packetDescriptions);

bail:
	return;
}
long AudioStreamDecoder::Start()
{
	long err = AudioFileStreamOpen(this, StaticPropertyCallback, StaticPacketCallback, kAudioFileAAC_ADTSType, &mStream);
	BAIL_IF(err, "AudioFileStreamOpen returned %ld\n", err);

bail:
	return err;
}
long AudioStreamDecoder::EnqueueData(const void* data, unsigned int length, bool discontinuous)
{
	unsigned int flags = discontinuous ? kAudioFileStreamParseFlag_Discontinuity : 0;

	long err = mStream ? 0 : ENOENT;
	BAIL_IF(err, "AudioFileStream not initialised\n", err);

	err = data ? 0 : EINVAL;
	BAIL_IF(err, "Invalid data pointer\n");

	err = length ? 0 : EINVAL;
	BAIL_IF(err, "Invalid length\n");

	err = AudioFileStreamParseBytes(mStream, length, data, flags);
	BAIL_IF(err, "AudioFileStreamParseBytes returned %ld\n", err);

bail:
	return err;
}
Esempio n. 12
0
char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
{
    const char *userdir = __PHYSFS_getUserDir();
    const char *append = "config/settings/";
    const size_t len = strlen(userdir) + strlen(append) + strlen(app) + 2;
    char *retval = (char *) allocator.Malloc(len);
    BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
    snprintf(retval, len, "%s%s%s/", userdir, append, app);
    return retval;
} /* __PHYSFS_platformCalcPrefDir */
void AudioStreamDecoder::QueueRunningCallback(AudioQueueRef queue, AudioQueuePropertyID property)
{
	long err;

	BAIL_IF(!queue || queue != mQueue, "Invalid queue %p\n", queue);
	BAIL_IF(!mStarted, "Queue not started\n");

	UInt32 running, size;
	err = AudioQueueGetProperty(mQueue, kAudioQueueProperty_IsRunning, &running, &size);
	BAIL_IF(err, "AudioQueueGetProperty returned %ld\n", err);

	if (!running)
	{
		err = SetFinished();
		BAIL_IF(err, "Finished returned %ld\n", err);
	}

bail:
	return;
}
void AudioStreamDecoder::PropertyCallback(AudioFileStreamID stream, AudioFileStreamPropertyID property, UInt32* flags)
{
	if (property != kAudioFileStreamProperty_ReadyToProducePackets)
		return;

	long err;
	void* buffer = NULL;
	unsigned char writable;
	AudioStreamBasicDescription desc = {0};
	UInt32 size = sizeof(desc);

	BAIL_IF(!stream || stream != mStream, "Invalid stream %p\n", stream);

	err = AudioFileStreamGetProperty(mStream, kAudioFileStreamProperty_DataFormat, &size, &desc);
	BAIL_IF(err, "AudioFileStreamGetProperty returned %ld\n", err);

	err = AudioQueueNewOutput(&desc, StaticBufferCompleteCallback, this, NULL, NULL, 0, &mQueue);
	BAIL_IF(err, "AudioQueueNewOutput returned %ld\n", err);

	err = AudioQueueAddPropertyListener(mQueue, kAudioQueueProperty_IsRunning, StaticQueueRunningCallback, this);
	BAIL_IF(err, "AudioQueueAddPropertyListener returned %ld\n", err);

	for (int i = 0; i < kBufferCount; i++)
	{
		err = AudioQueueAllocateBufferWithPacketDescriptions(mQueue, kBufferSize, kBufferPacketDescs, mBuffers + i);
		BAIL_IF(err, "AudioQueueAllocateBuffer returned %ld\n", err);
	}

	mCurrentBuffer = mBuffers;
	(*mCurrentBuffer)->mUserData = this;

	err = AudioFileStreamGetPropertyInfo(mStream, kAudioFileStreamProperty_MagicCookieData, &size, &writable);
	BAIL_IF(err, "AudioFileStreamGetPropertyInfo returned %ld\n", err);

	buffer = malloc(size);
	BAIL_IF(!buffer, "Failed to allocate %u byte buffer for cookie\n", (unsigned int)size);

	err = AudioFileStreamGetProperty(mStream, kAudioFileStreamProperty_MagicCookieData, &size, buffer);
	BAIL_IF(err, "AudioFileStreamGetProperty returned %ld\n", err);

	err = AudioQueueSetProperty(mQueue, kAudioQueueProperty_MagicCookie, buffer, size);
	BAIL_IF(err, "AudioQueueSetProperty returned %ld\n", err);

bail:
	free(buffer);
}
long AudioStreamDecoder::SetFinished()
{
	bool locked = false;

	long err = pthread_mutex_lock(&mMutex);
	BAIL_IF(err, "pthread_mutex_lock returned %ld\n", err);

	locked = true;
	mFinished = true;

	err = pthread_cond_signal(&mCond);
	BAIL_IF(err, "pthread_cond_signal returned %ld\n", err);

bail:
	if (locked)
	{
		long err2 = pthread_mutex_unlock(&mMutex);
		CARP_IF(err2, "pthread_mutex_unlock returned %ld\n", err2);
	}

	return err;
}
void AudioStreamDecoder::BufferCompleteCallback(AudioQueueRef queue, AudioQueueBufferRef buffer)
{
	long err;
	bool locked = false;

	BAIL_IF(!queue, "Invalid queue\n");
	BAIL_IF(!buffer, "Invalid buffer\n");

	err = pthread_mutex_lock(&mMutex);
	BAIL_IF(err, "pthread_mutex_lock returned %ld\n", err);

	locked = true;
	buffer->mUserData = NULL;

	err = pthread_cond_signal(&mCond);
	BAIL_IF(err, "pthread_cond_signal returned %ld\n", err);

bail:
	if (locked)
	{
		err = pthread_mutex_unlock(&mMutex);
		CARP_IF(err, "pthread_mutex_unlock returned %ld\n", err);
	}
}
Esempio n. 17
0
static void *MPQ_openArchive(PHYSFS_Io *io, const char *name,
                             int forWriting, int *claimed)
{
    HANDLE hMpq = NULL;
    DWORD dwFlags = MPQ_OPEN_READ_ONLY;
    MPQHandle *handle = NULL;

    assert(io != NULL);  /* shouldn't ever happen. */

    BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL);

    if (!SFileOpenArchive(name, 0, dwFlags, &hMpq))
        return NULL;

    *claimed = 1;

    handle = (MPQHandle *)allocator.Malloc(sizeof(MPQHandle));
    if (handle)
    {
        handle->io = io;
        handle->mpqHandle = hMpq;
    }
    return handle;
}
Esempio n. 18
0
int main(int argc, char *argv[])
{
    if (argc < 2) {
        printf(usage, argv[0]);
        return -1;
    }

    bool fixup = false;
    for (int i = 1; i < argc; ++i) {
        if (strcmp("--fixup", argv[i]) == 0)
            fixup = true;
    }

    int fd = open(argv[1], O_RDWR);
    BAIL_IF(fd == -1);
    void * addr = mmap(NULL, file_get_size(fd), 
                       PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED,
                       fd, 0);
    BAIL_IF(addr == MAP_FAILED);

    activite_img_t * img = addr;

    // In all images encountered so far, there were exactly two separate images
    for (int i = 0; i < 2; ++i) {
        uint32_t img_crc = crc32(((uint8_t *)addr) + img->images[i].img.offset,
                             img->images[i].img.len);

        if (img->images[i].img.checksum == img_crc) {
            switch((IMG_IDENTIFIER)img->images[i].identifier) {
                case FIRMWARE:
                    puts("Verified firmware checksum");
                    break;
                case BOOTLOADER:
                    puts("Verified bootloader checksum");
                    break;
            }
        } else {
            if (fixup) {
                img->images[i].img.checksum = img_crc;
                puts("Recalculated checksum");
            } else {
                puts("One checksum invalid. Did not fix");
            }
        }    
    }

    const uint32_t header_crc = crc32(img, sizeof(activite_img_t) - sizeof(uint32_t));
    if (img->table_checksum == header_crc) {
        puts("Header checksum verified");
    } else {
        if (fixup) {
            img->table_checksum = header_crc;
            puts("Recalculated header checksum");
        } else {
            puts("Header checksum invalid. Did not fix.");
        }
    }

    munmap(addr, file_get_size(fd));
    close(fd);

    return EXIT_SUCCESS;
}