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; }
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); } }
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; }
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; }