message *decode_message(unsigned char *data, unsigned int total_len) { int pos = 0; unsigned int len; unsigned char type; struct chunk *head; struct chunk **cur; if (data[0] != 1 || data[1] != DiscoverMessage) { printf("oops, got id %d\n", data[1]); return(0); } pos = 4; head = malloc(sizeof(struct chunk)); head->type = 0; head->u.down = 0; cur = &head->u.down; for (pos=4;pos<total_len;pos+=len) { type = data[pos]; len = get_number(data + pos + 1, 2); pos += 3; (*cur) = malloc(sizeof(struct chunk)); (*cur)->type = type; decode_chunk(*cur, type, data+pos, len); cur = &((*cur)->next); } *cur = 0; return head; }
/* this is the codec entry point */ enum codec_status codec_main(void) { struct ape_ctx_t ape_ctx; uint32_t samplesdone; uint32_t elapsedtime; size_t bytesleft; int retval; uint32_t currentframe; uint32_t newfilepos; uint32_t samplestoskip; int nblocks; int bytesconsumed; unsigned char* inbuffer; uint32_t blockstodecode; int res; int firstbyte; size_t resume_offset; /* Generic codec initialisation */ ci->configure(DSP_SET_SAMPLE_DEPTH, APE_OUTPUT_DEPTH-1); next_track: retval = CODEC_OK; if (codec_init()) { LOGF("APE: Error initialising codec\n"); retval = CODEC_ERROR; goto exit; } if (codec_wait_taginfo() != 0) goto done; /* Remember the resume position - when the codec is opened, the playback engine will reset it. */ resume_offset = ci->id3->offset; inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE); /* Read the file headers to populate the ape_ctx struct */ if (ape_parseheaderbuf(inbuffer,&ape_ctx) < 0) { LOGF("APE: Error reading header\n"); retval = CODEC_ERROR; goto exit; } /* Initialise the seektable for this file */ ape_ctx.seektable = seektablebuf; ape_ctx.numseekpoints = MIN(MAX_SEEKPOINTS,ape_ctx.numseekpoints); ci->advance_buffer(ape_ctx.seektablefilepos); /* The seektable may be bigger than the guard buffer (32KB), so we do a read() */ ci->read_filebuf(ape_ctx.seektable, ape_ctx.numseekpoints * sizeof(uint32_t)); #ifdef ROCKBOX_BIG_ENDIAN /* Byte-swap the little-endian seekpoints */ { uint32_t i; for(i = 0; i < ape_ctx.numseekpoints; i++) ape_ctx.seektable[i] = swap32(ape_ctx.seektable[i]); } #endif /* Now advance the file position to the first frame */ ci->advance_buffer(ape_ctx.firstframe - (ape_ctx.seektablefilepos + ape_ctx.numseekpoints * sizeof(uint32_t))); ci->configure(DSP_SWITCH_FREQUENCY, ape_ctx.samplerate); ci->configure(DSP_SET_STEREO_MODE, ape_ctx.channels == 1 ? STEREO_MONO : STEREO_NONINTERLEAVED); codec_set_replaygain(ci->id3); /* The main decoding loop */ if (resume_offset) { /* The resume offset is a value in bytes - we need to turn it into a frame number and samplestoskip value */ ape_resume(&ape_ctx, resume_offset, ¤tframe, &samplesdone, &samplestoskip, &firstbyte); } else { currentframe = 0; samplesdone = 0; samplestoskip = 0; firstbyte = 3; /* Take account of the little-endian 32-bit byte ordering */ } /* Initialise the buffer */ inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE); /* The main decoding loop - we decode the frames a small chunk at a time */ while (currentframe < ape_ctx.totalframes) { frame_start: /* Calculate how many blocks there are in this frame */ if (currentframe == (ape_ctx.totalframes - 1)) nblocks = ape_ctx.finalframeblocks; else nblocks = ape_ctx.blocksperframe; ape_ctx.currentframeblocks = nblocks; /* Initialise the frame decoder */ init_frame_decoder(&ape_ctx, inbuffer, &firstbyte, &bytesconsumed); ci->advance_buffer(bytesconsumed); inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE); /* Decode the frame a chunk at a time */ while (nblocks > 0) { ci->yield(); if (ci->stop_codec || ci->new_track) { goto done; } /* Deal with any pending seek requests */ if (ci->seek_time) { if (ape_calc_seekpos(&ape_ctx, ((ci->seek_time-1)/10) * (ci->id3->frequency/100), ¤tframe, &newfilepos, &samplestoskip)) { samplesdone = currentframe * ape_ctx.blocksperframe; /* APE's bytestream is weird... */ firstbyte = 3 - (newfilepos & 3); newfilepos &= ~3; ci->seek_buffer(newfilepos); inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE); ci->seek_complete(); goto frame_start; /* Sorry... */ } ci->seek_complete(); } blockstodecode = MIN(BLOCKS_PER_LOOP, nblocks); if ((res = decode_chunk(&ape_ctx, inbuffer, &firstbyte, &bytesconsumed, decoded0, decoded1, blockstodecode)) < 0) { /* Frame decoding error, abort */ LOGF("APE: Frame %lu, error %d\n",(unsigned long)currentframe,res); retval = CODEC_ERROR; goto done; } ci->yield(); if (samplestoskip > 0) { if (samplestoskip < blockstodecode) { ci->pcmbuf_insert(decoded0 + samplestoskip, decoded1 + samplestoskip, blockstodecode - samplestoskip); samplestoskip = 0; } else { samplestoskip -= blockstodecode; } } else { ci->pcmbuf_insert(decoded0, decoded1, blockstodecode); } samplesdone += blockstodecode; if (!samplestoskip) { /* Update the elapsed-time indicator */ elapsedtime = (samplesdone*10)/(ape_ctx.samplerate/100); ci->set_elapsed(elapsedtime); } ci->advance_buffer(bytesconsumed); inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE); /* Decrement the block count */ nblocks -= blockstodecode; } currentframe++; } done: LOGF("APE: Decoded %lu samples\n",(unsigned long)samplesdone); if (ci->request_next_track()) goto next_track; exit: return retval; }
void decode_file(char *confFile, char *outFile, int nativeBlockNum, int parityBlockNum) { int chunkSize = 1; int totalSize; uint8_t *dataBuf; uint8_t *codeBuf; int dataSize; int codeSize; FILE *fp_in; FILE *fp_out; int totalMatrixSize; int matrixSize; uint8_t *totalEncodingMatrix; uint8_t *encodingMatrix; if( ( fp_in = fopen(".METADATA","rb") ) == NULL ) { printf("Can not open source file!\n"); exit(0); } fscanf(fp_in, "%d", &totalSize); fscanf(fp_in, "%d %d", &parityBlockNum, &nativeBlockNum); // chunkSize = (int) (ceil( (float) (totalSize / nativeBlockNum) )); chunkSize = (totalSize / nativeBlockNum) + ( totalSize%nativeBlockNum != 0 ); #ifdef DEBUG printf("chunk size: %d\n", chunkSize); #endif totalMatrixSize = nativeBlockNum * ( nativeBlockNum + parityBlockNum ); totalEncodingMatrix = (uint8_t*) malloc( totalMatrixSize ); matrixSize = nativeBlockNum * nativeBlockNum; encodingMatrix = (uint8_t*) malloc( matrixSize ); int i; for(i =0; i<nativeBlockNum*(nativeBlockNum+parityBlockNum); i++) { fscanf(fp_in, "%d", totalEncodingMatrix+i); } dataSize = nativeBlockNum*chunkSize*sizeof(uint8_t); codeSize = nativeBlockNum*chunkSize*sizeof(uint8_t); dataBuf = (uint8_t*) malloc( dataSize ); memset(dataBuf, 0, dataSize); codeBuf = (uint8_t*) malloc( codeSize); memset(codeBuf, 0, codeSize); if(confFile != NULL) { FILE *fp_conf; char input_file_name[100]; int index; fp_conf = fopen(confFile, "r"); for(i=0; i<nativeBlockNum; i++) { fscanf(fp_conf, "%s", input_file_name); index = atoi(input_file_name+1); copy_matrix(totalEncodingMatrix, encodingMatrix, index, i, nativeBlockNum); fp_in = fopen(input_file_name, "rb"); fseek(fp_in, 0L, SEEK_SET); // this part can be process in parallel with computing inversed matrix fread(codeBuf+i*chunkSize, sizeof(uint8_t), chunkSize, fp_in); fclose(fp_in); } fclose(fp_conf); } else { for(i=0; i<nativeBlockNum; i++) { char input_file_name[100]; int index; printf("Please enter the file name of fragment:\n"); scanf("%s", input_file_name); index = atoi(input_file_name+1); printf("#%dth fragment\n", index); copy_matrix(totalEncodingMatrix, encodingMatrix, index, i, nativeBlockNum); fp_in = fopen(input_file_name, "rb"); fseek(fp_in, 0L, SEEK_SET); // TODO: this part can be process in parallel with computing inversed matrix fread(codeBuf+i*chunkSize, sizeof(uint8_t), chunkSize, fp_in); fclose(fp_in); } } struct timespec start, end; double totalTime; clock_gettime(CLOCK_REALTIME,&start); uint8_t *decodingMatrix; decodingMatrix = (uint8_t*) malloc( matrixSize ); invert_matrix(encodingMatrix, decodingMatrix, nativeBlockNum); //#ifndef DEBUG // show_matrix(totalEncodingMatrix, nativeBlockNum+parityBlockNum, nativeBlockNum); //#endif //#ifndef DEBUG decode_chunk(dataBuf, decodingMatrix, codeBuf, nativeBlockNum, parityBlockNum, chunkSize); //#endif //#ifdef DEBUG // uint8_t test_DM[16] = {1,0,0,0, 2,1,3,7, 3,1,2,6, 0,0,0,1}; // decode_chunk(dataBuf, test_DM, codeBuf, nativeBlockNum, parityBlockNum, chunkSize); //#endif clock_gettime(CLOCK_REALTIME,&end); totalTime = (double)(end.tv_sec-start.tv_sec)*1000+(double)(end.tv_nsec-start.tv_nsec)/(double)1000000L; printf("Total CPU decoding time: %fms\n", totalTime); if(outFile == NULL) { char output_file_name[100]; printf("Enter the name of the decoded file:\n"); scanf("%s", output_file_name); fp_out = fopen(output_file_name, "wb"); } else { fp_out = fopen(outFile, "wb"); } fwrite(dataBuf, sizeof(uint8_t), totalSize, fp_out); fclose(fp_out); free(dataBuf); free(codeBuf); }
static struct ast_config *realtime_multi_pgsql(const char *database, const char *table, va_list ap) { PGresult *result = NULL; int num_rows = 0, pgerror; char sql[256], escapebuf[2049], semibuf[1024]; const char *initfield = NULL; char *stringp; char *chunk; char *op; const char *newparam, *newval; struct ast_realloca ra; struct ast_variable *var = NULL; struct ast_config *cfg = NULL; struct ast_category *cat = NULL; if (!table) { ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n"); return NULL; } memset(&ra, 0, sizeof(ra)); if (!(cfg = ast_config_new())) return NULL; /* Get the first parameter and first value in our list of passed paramater/value pairs */ newparam = va_arg(ap, const char *); newval = va_arg(ap, const char *); if (!newparam || !newval) { ast_log(LOG_WARNING, "Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n"); if (pgsqlConn) { PQfinish(pgsqlConn); pgsqlConn = NULL; }; return NULL; } initfield = ast_strdupa(newparam); if ((op = strchr(initfield, ' '))) { *op = '\0'; } /* Create the first part of the query using the first parameter/value pairs we just extracted If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */ if (!strchr(newparam, ' ')) op = " ="; else op = ""; PQescapeStringConn(pgsqlConn, escapebuf, encode_chunk(newval, semibuf, sizeof(semibuf)), (sizeof(escapebuf) - 1) / 2, &pgerror); if (pgerror) { ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval); va_end(ap); return NULL; } snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, escapebuf); while ((newparam = va_arg(ap, const char *))) { newval = va_arg(ap, const char *); if (!strchr(newparam, ' ')) op = " ="; else op = ""; PQescapeStringConn(pgsqlConn, escapebuf, encode_chunk(newval, semibuf, sizeof(semibuf)), (sizeof(escapebuf) - 1) / 2, &pgerror); if (pgerror) { ast_log(LOG_ERROR, "Postgres detected invalid input: '%s'\n", newval); va_end(ap); return NULL; } snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, escapebuf); } if (initfield) { snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield); } va_end(ap); /* We now have our complete statement; Lets connect to the server and execute it. */ ast_mutex_lock(&pgsql_lock); if (!pgsql_reconnect(database)) { ast_mutex_unlock(&pgsql_lock); return NULL; } if (!(result = PQexec(pgsqlConn, sql))) { ast_log(LOG_WARNING, "Postgresql RealTime: Failed to query database. Check debug for more info.\n"); ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql); ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn)); ast_mutex_unlock(&pgsql_lock); return NULL; } else { ExecStatusType result_status = PQresultStatus(result); if (result_status != PGRES_COMMAND_OK && result_status != PGRES_TUPLES_OK && result_status != PGRES_NONFATAL_ERROR) { ast_log(LOG_WARNING, "Postgresql RealTime: Failed to query database. Check debug for more info.\n"); ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql); ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n", PQresultErrorMessage(result), PQresStatus(result_status)); ast_mutex_unlock(&pgsql_lock); return NULL; } } ast_log(LOG_DEBUG, "2Postgresql RealTime: Result=%p Query: %s\n", result, sql); if ((num_rows = PQntuples(result)) > 0) { int numFields = PQnfields(result); int i = 0; int rowIndex = 0; char **fieldnames = NULL; ast_log(LOG_DEBUG, "Postgresql RealTime: Found %d rows.\n", num_rows); if (!(fieldnames = ast_calloc(1, numFields * sizeof(char *)))) { ast_mutex_unlock(&pgsql_lock); PQclear(result); return NULL; } for (i = 0; i < numFields; i++) fieldnames[i] = PQfname(result, i); for (rowIndex = 0; rowIndex < num_rows; rowIndex++) { var = NULL; if (!(cat = ast_category_new(""))) continue; for (i = 0; i < numFields; i++) { stringp = PQgetvalue(result, rowIndex, i); while (stringp) { chunk = strsep(&stringp, ";"); if (chunk && !ast_strlen_zero(decode_chunk(ast_strip(chunk)))) { if (initfield && !strcmp(initfield, fieldnames[i])) { ast_category_rename(cat, chunk); } var = ast_variable_new(fieldnames[i], chunk); ast_variable_append(cat, var); } } } ast_category_append(cfg, cat); } ast_free(fieldnames); } else { ast_log(LOG_DEBUG, "Postgresql RealTime: Could not find any rows in table %s.\n", table); } ast_mutex_unlock(&pgsql_lock); PQclear(result); return cfg; }