예제 #1
0
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;
}
예제 #2
0
파일: ape.c 프로젝트: claymodel/rockbox
/* 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, 
                   &currentframe, &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),
                    &currentframe,
                    &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;
}
예제 #3
0
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;
}