/* ** configure a new audio tap */ static void *_configure_impl(_t *data) { int b_size = sdrkit_buffer_size(data); /* size of jack buffer (samples) */ data->buff_n = 1<<data->opts.log2_buff_n; /* number of buffers (n) */ data->buff_size = 1<<data->opts.log2_buff_size; /* number of sample pairs in each buffer (samples) */ if (data->buff_size < b_size) return "audio-tap buffer size must as large as jack buffer size"; data->buffs = (buffer_t *)Tcl_Alloc(data->buff_n*sizeof(buffer_t)); if (data->buffs == NULL) { return "allocation failed: buff array"; } for (int i = 0; i < data->buff_n; i += 1) { data->buffs[i].bread = 1; data->buffs[i].bframe = 0; data->buffs[i].buff = Tcl_NewObj(); if (data->buffs[i].buff == NULL || Tcl_SetByteArrayLength(data->buffs[i].buff, data->buff_size*2*sizeof(float)) == NULL) { _delete_impl(data); return "allocation failed: byte array"; } Tcl_IncrRefCount(data->buffs[i].buff); } data->current = &data->buffs[0]; return data; }
/* * ZlibDecompressObj * * Decompresses Zlib compressed data. * * Arguments: * sourceObj - Pointer to a Tcl object containing the data to be decompressed. * destObj - Pointer to a Tcl object to receive the decompressed data. * window - Maximum window size for Zlib. * * Return Value: * A Zlib status code; Z_OK is returned if successful. */ static int ZlibDecompressObj( Tcl_Obj *sourceObj, Tcl_Obj *destObj, int window ) { int status; uInt destLength; uInt factor; uInt sourceLength; unsigned char *dest; z_stream stream; assert(sourceObj != NULL); assert(destObj != NULL); /* * The avail_in, next_in, opaque, zalloc, and zfree data structure * members must be initialised prior to calling inflateInit2(). */ stream.next_in = Tcl_GetByteArrayFromObj(sourceObj, (int *)&sourceLength); if (sourceLength < 1) { return Z_DATA_ERROR; } stream.avail_in = sourceLength; stream.opaque = NULL; stream.zalloc = ZlibAlloc; stream.zfree = ZlibFree; status = inflateInit2(&stream, window); if (status != Z_OK) { return status; } /* Double the destination buffer size each attempt. */ for (factor = 1; factor < 20; factor++) { destLength = sourceLength * (1 << factor); dest = Tcl_SetByteArrayLength(destObj, (int)destLength); stream.next_out = dest + stream.total_out; stream.avail_out = destLength - stream.total_out; /* * inflate() returns: * - Z_STREAM_END if all input data has been exhausted. * - Z_OK if the inflation was successful but there is remaining input data. * - Otherwise an error has occurred while inflating the data. */ status = inflate(&stream, Z_SYNC_FLUSH); if (status != Z_OK) { break; } /* * If inflate() returns Z_OK without exhausting the output buffer, * it's assumed we've unexpectedly reached the stream's end. */ if (stream.avail_out > 0) { status = Z_STREAM_ERROR; break; } /* Increase the destination buffer size and try again. */ status = Z_BUF_ERROR; } inflateEnd(&stream); if (status == Z_STREAM_END) { /* Update the object's length. */ Tcl_SetByteArrayLength(destObj, (int)stream.total_out); return Z_OK; } return status; }
/*++ BzipDecompressObj Decompresses Bzip2 compressed data. Arguments: sourceObj - Pointer to a Tcl object containing the data to be decompressed. destObj - Pointer to a Tcl object to receive the decompressed data. Return Value: A Bzip2 status code; BZ_OK is returned if successful. --*/ static int BzipDecompressObj( Tcl_Obj *sourceObj, Tcl_Obj *destObj ) { bz_stream stream; char *dest; int status; unsigned int destLength; unsigned int factor; unsigned int sourceLength; Tcl_WideUInt totalOut; stream.next_in = (char *)Tcl_GetByteArrayFromObj(sourceObj, (int *)&sourceLength); if (sourceLength < 3) { // The Bzip2 header is at least 3 characters in length, 'BZh'. return BZ_DATA_ERROR_MAGIC; } // // The bzalloc, bzfree, and opaque data structure members // must be initialised prior to calling BZ2_bzDecompressInit(). // stream.bzalloc = BzipAlloc; stream.bzfree = BzipFree; stream.opaque = NULL; status = BZ2_bzDecompressInit(&stream, 0, 0); if (status != BZ_OK) { return status; } stream.avail_in = sourceLength; for (factor = 1; factor < 20; factor++) { // Double the destination buffer size each attempt. destLength = sourceLength * (1 << factor); dest = (char *)Tcl_SetByteArrayLength(destObj, (int)destLength); totalOut = ((Tcl_WideUInt)stream.total_out_hi32 << 32) + stream.total_out_lo32; stream.next_out = dest + totalOut; stream.avail_out = destLength - (unsigned int)totalOut; // // BZ2_bzDecompress() returns: // - BZ_STREAM_END if the logical end of the stream has been reached. // - BZ_OK if the decompression was successful but there is remaining input data. // - Otherwise an error has occurred while decompressing the data. // status = BZ2_bzDecompress(&stream); if (status != BZ_OK) { break; } // // If BZ2_bzDecompress() returns BZ_OK without exhausting the output // buffer, it's assumed we've unexpectedly reached the stream's end. // if (stream.avail_out > 0) { status = BZ_UNEXPECTED_EOF; break; } // Increase the destination buffer size and try again. status = BZ_OUTBUFF_FULL; } BZ2_bzDecompressEnd(&stream); if (status == BZ_STREAM_END) { // Update the object's length. destLength -= stream.avail_out; Tcl_SetByteArrayLength(destObj, (int)destLength); return BZ_OK; } return status; }