int ms_pack_steim (DATA_HDR *hdr0, /* ptr to initial data hdr. */ BS *init_bs, /* ptr to onetime blockettes. */ int *data, /* ptr to data buffer. */ int *diff, /* ptr to diff buffer (optional) */ int num_samples, /* number of data samples. */ int *n_blocks, /* # miniSEED blocks (returned). */ char **pp_ms, /* ptr **miniSEED (returned). */ int ms_len, /* miniSEED buffer len (if supplied). */ char *p_errmsg) /* ptr to error msg buffer. */ { DATA_HDR *hdr; /* data_hdr used for writing Mini-SEED */ char *p_ms; /* ptr to current Mini-SEED block. */ SDF *p_sdf; /* ptr to STEIM data frame. */ char errmsg[256]; /* error msg buffer. */ unsigned char *minbits; /* min # of bits required to pack data. */ int free_diff = 0; /* flag to remind whether we free diff. */ int ipt; /* index of data to pack. */ int nblks_malloced; /* # Mini-SEED output blocks malloced. */ int num_blocks; /* # Mini-SEED block created. */ int samples_remaining; /* # samples left to cvt to Mini-seed. */ int frames_per_block; /* # of steim compressed framed per blk.*/ int nframes; /* # of steim frames in Mini-SEED block.*/ int nsamples; /* # of samples in Mini-SEED block. */ int seconds, usecs; /* seconds and usecs for time calcs. */ int pad; /* flag to indicate padding of frames. */ int status; /* status from data packing routine. */ int i; /* loop indices. */ int blksize = hdr0->blksize;/* output blksize. */ /* Initialization. */ *n_blocks = 0; minbits = NULL; /* Check for invalid arguments. */ if (num_samples <= 0) return(MS_ERROR); if (blksize < 128 || (blksize != (int)pow(2.0,rint(log2((double)blksize))))) { sprintf (errmsg, "Warning: invalid blksize: %d\n", blksize); if (p_errmsg) strcpy(p_errmsg, errmsg); else fprintf (stderr, errmsg); return (MS_ERROR); } /* If no diff buffer provided, create one and compute differences. */ if (diff == NULL) { if ((diff = (int *)malloc(num_samples * sizeof(int))) == NULL) { sprintf (errmsg, "Error mallocing diff buffer\n"); if (p_errmsg) strcpy(p_errmsg, errmsg); else fprintf (stderr, errmsg); return (QLIB2_MALLOC_ERROR); } free_diff = 1; diff[0] = data[0] - hdr0->xm1; for (i=1; i<num_samples; i++) { diff[i] = data[i] - data[i-1]; } } /* If *pp_ms != NULL, assume that the caller is providing sufficient*/ /* memory to hold all of the resulting Mini-SEED records. */ /* If it is NULL, we allocate the space, and set it to point to the */ /* allocated Mini-SEED records. */ /* If we allocated the space for the Mini-SEED, the caller is */ /* responsible for freeing the space. */ if (*pp_ms) nblks_malloced = -1; else nblks_malloced = 0; /* Create a copy of the initial data_hdr for our use. */ /* We will update this each time we create a Mini-SEED block. */ hdr = dup_data_hdr (hdr0); if (hdr == NULL) { if (free_diff) free(diff); return (MS_ERROR); } /* Start compressor. */ num_blocks = 0; samples_remaining = num_samples; ipt = 0; pad = 1; while (samples_remaining) { /* Check for available space. */ /* Allocate more space for Mini-SEED blocks if necessary. */ if (nblks_malloced < 0) { if (ms_len < blksize) { *n_blocks = num_blocks; if(free_diff) free( (char *) diff); free_data_hdr(hdr); return (num_samples - samples_remaining); } ms_len -= blksize; } if (nblks_malloced >= 0 && num_blocks == nblks_malloced) { *pp_ms = (*pp_ms == NULL) ? (char *)malloc((nblks_malloced+MALLOC_INCREMENT)*blksize) : (char *)realloc(*pp_ms,(nblks_malloced+MALLOC_INCREMENT)*blksize); if (*pp_ms == NULL) { sprintf (errmsg, "Error mallocing Mini-SEED buffer\n"); if (p_errmsg) strcpy(p_errmsg, errmsg); else fprintf (stderr, errmsg); if (free_diff) free ((char *)diff); free_data_hdr (hdr); return (QLIB2_MALLOC_ERROR); } nblks_malloced += MALLOC_INCREMENT; } /* Initialize the next fixed data header. */ p_ms = *pp_ms + (num_blocks * blksize); if (init_miniseed_hdr ((SDR_HDR *)p_ms, hdr, init_bs) < 0) { sprintf (errmsg, "Error: initializing MiniSEED header"); if (p_errmsg) strcpy(p_errmsg, errmsg); else fprintf (stderr, errmsg); if (free_diff) free ((char *)diff); free_data_hdr (hdr); if (nblks_malloced > 0) free(*pp_ms); return (MS_ERROR); } init_bs = NULL; frames_per_block = (blksize-hdr->first_data) / 64; p_sdf = (SDF *)(p_ms + hdr->first_data); /* Pack data into the next Mini-SEED block. */ switch (hdr->data_type) { case STEIM1: status = pack_steim1 (p_sdf, &data[ipt], &diff[ipt], samples_remaining, frames_per_block, pad, hdr->data_wordorder, &nframes, &nsamples); break; case STEIM2: status = pack_steim2 (p_sdf, &data[ipt], &diff[ipt], samples_remaining, frames_per_block, pad, hdr->data_wordorder, &nframes, &nsamples); break; default: sprintf (errmsg, "Error: invalid format %d for ms_pack_steim\n", hdr->data_type); if (p_errmsg) strcpy(p_errmsg, errmsg); else fprintf (stderr, errmsg); fflush (stderr); if (QLIB2_CLASSIC) exit (1); if (free_diff) free ((char *)diff); free_data_hdr (hdr); if (nblks_malloced > 0) free(*pp_ms); return (MS_ERROR); break; } if (status != 0) { sprintf (errmsg, "Error packing %s data\n", (hdr->data_type == STEIM1) ? "STEIM1" : "STEIM2"); if (p_errmsg) strcpy(p_errmsg, errmsg); else fprintf (stderr, errmsg); if (free_diff) free ((char *)diff); free_data_hdr (hdr); *n_blocks = num_blocks; return (status); } /* End of data or Mini-SEED block is full. */ /* Update Mini-SEED header with: */ /* final sample count. */ /* Update hdr for the next record. */ hdr->num_samples = nsamples; update_miniseed_hdr ((SDR_HDR *)p_ms, hdr); ms_pack_update_hdr (hdr, 1, nsamples, &data[ipt]); ipt += nsamples; samples_remaining -= nsamples; ++num_blocks; hdr->num_samples = 0; } /* Cleanup. */ free ((char *)minbits); free_data_hdr (hdr); if (free_diff) free ((char *)diff); *n_blocks = num_blocks; ms_pack_update_return_hdr (hdr0, num_blocks, num_samples, data); return(num_samples); }
int ms_pack_int (DATA_HDR *hdr0, /* ptr to initial data hdr. */ BS *init_bs, /* ptr to onetime blockettes. */ int *data, /* ptr to data buffer. */ int num_samples, /* number of data samples. */ int *n_blocks, /* # miniSEED blocks (returned). */ char **pp_ms, /* ptr **miniSEED (returned). */ int ms_len, /* miniSEED buffer len (if supplied). */ char *p_errmsg) /* ptr to error msg buffer. */ { DATA_HDR *hdr; /* data header used for writing miniSEED*/ char *p_ms; /* ptr to current miniSEED block. */ void *p_packed; /* ptr to packed output data. */ char errmsg[256]; /* error msg buffer. */ int ipt; /* index of data to pack. */ int nblks_malloced; /* # of miniSEED output blocks malloced.*/ int num_blocks; /* # of miniSEED block created. */ int samples_remaining; /* # samples left to cvt to miniseed. */ int nsamples; /* # of samples in miniSEED block. */ int max_bytes; /* max # of data bytes in record. */ int nbytes; /* # of bytes packed into record. */ int seconds, usecs; /* seconds and usecs for time calcs. */ int pad; /* flag to indicate padding of frames. */ int blksize = hdr0->blksize;/* output blksize. */ /* Initialization. */ *n_blocks = 0; /* Check for invalid arguments. */ if (num_samples <= 0) return(MS_ERROR); if (blksize < 128 || (blksize != (int)pow(2.0,rint(log2((double)blksize))))) { sprintf (errmsg, "Warning: invalid blksize: %d\n", blksize); if (p_errmsg) strcpy(p_errmsg, errmsg); else fprintf (stderr, errmsg); return (MS_ERROR); } /* If *pp_ms != NULL, assume that the caller is providing sufficient*/ /* memory to hold all of the resulting miniSEED records. */ /* If it is NULL, we allocate the space, and set it to point to the */ /* allocated miniSEED records. */ /* If we allocated the space for the miniSEED, the caller is */ /* responsible for freeing the space. */ if (*pp_ms) nblks_malloced = -1; else nblks_malloced = 0; /* Create a copy of the initial data_hdr for our use. */ /* We will update this each time we create a miniSEED block. */ hdr = dup_data_hdr (hdr0); if (hdr == NULL) { return (MS_ERROR); } /* Start compressor. */ num_blocks = 0; samples_remaining = num_samples; ipt = 0; pad = 1; while (samples_remaining) { /* Check for available space. */ /* Allocate more space for Mini-SEED blocks if necessary. */ if (nblks_malloced < 0) { if (ms_len < blksize) { *n_blocks = num_blocks; free_data_hdr (hdr); return (num_samples - samples_remaining); } ms_len -= blksize; } if (nblks_malloced >= 0 && num_blocks == nblks_malloced) { *pp_ms = (*pp_ms == NULL) ? (char *)malloc((nblks_malloced+MALLOC_INCREMENT)*blksize) : (char *)realloc(*pp_ms,(nblks_malloced+MALLOC_INCREMENT)*blksize); if (*pp_ms == NULL) { sprintf (errmsg, "Error mallocing miniSEED buffer\n"); if (p_errmsg) strcpy(p_errmsg, errmsg); else fprintf (stderr, errmsg); free_data_hdr (hdr); return (QLIB2_MALLOC_ERROR); } nblks_malloced += MALLOC_INCREMENT; } /* Initialize the next fixed data header. */ p_ms = *pp_ms + (num_blocks * blksize); if (init_miniseed_hdr ((SDR_HDR *)p_ms, hdr, init_bs) < 0) { sprintf (errmsg, "Error: initializing MiniSEED header"); if (p_errmsg) strcpy(p_errmsg, errmsg); else fprintf (stderr, errmsg); free_data_hdr (hdr); if (nblks_malloced > 0) free(*pp_ms); return (MS_ERROR); } init_bs = NULL; p_packed = (void *)(p_ms + hdr->first_data); max_bytes = blksize + 1 - hdr->first_data; /* Pack the rest of the miniSEED record with data. */ switch (hdr->data_type) { case INT_32: pack_int_32 ((int *)p_packed, &data[ipt], samples_remaining, max_bytes, pad, hdr->data_wordorder, &nbytes, &nsamples); break; case INT_24: pack_int_24 ((unsigned char *)p_packed, &data[ipt], samples_remaining, max_bytes, pad, hdr->data_wordorder, &nbytes, &nsamples); break; case INT_16: pack_int_16 ((short int *)p_packed, &data[ipt], samples_remaining, max_bytes, pad, hdr->data_wordorder, &nbytes, &nsamples); break; } /* End of data or Mini-SEED block is full. */ /* Update Mini-SEED header with: */ /* final sample count. */ /* Update hdr for the next record. */ hdr->num_samples = nsamples; update_miniseed_hdr ((SDR_HDR *)p_ms, hdr); ms_pack_update_hdr (hdr, 1, nsamples, &data[ipt]); ipt += nsamples; samples_remaining -= nsamples; ++num_blocks; hdr->num_samples = 0; } /* Cleanup. */ free_data_hdr (hdr); *n_blocks = num_blocks; ms_pack_update_return_hdr (hdr0, num_blocks, num_samples, data); return(num_samples); }
static void dp_set_variables(Display * dpy, XDevice * dev, int argc, char *argv[], int first_cmd) { int i; double val; struct Parameter *par; Atom prop, type, float_type; int format; unsigned char *data; unsigned long nitems, bytes_after; union flong *f; long *n; char *b; float_type = XInternAtom(dpy, XATOM_FLOAT, True); if (!float_type) fprintf(stderr, "Float properties not available.\n"); for (i = first_cmd; i < argc; i++) { val = parse_cmd(argv[i], &par); if (!par) continue; prop = XInternAtom(dpy, par->prop_name, True); if (!prop) { fprintf(stderr, "Property for '%s' not available. Skipping.\n", par->name); continue; } XGetDeviceProperty(dpy, dev, prop, 0, 1000, False, AnyPropertyType, &type, &format, &nitems, &bytes_after, &data); if (type == None) { fprintf(stderr, "Property for '%s' not available. Skipping.\n", par->name); continue; } switch (par->prop_format) { case 8: if (format != par->prop_format || type != XA_INTEGER) { fprintf(stderr, " %-23s = format mismatch (%d)\n", par->name, format); break; } b = (char *) data; b[par->prop_offset] = rint(val); break; case 32: if (format != par->prop_format || (type != XA_INTEGER && type != XA_CARDINAL)) { fprintf(stderr, " %-23s = format mismatch (%d)\n", par->name, format); break; } n = (long *) data; n[par->prop_offset] = rint(val); break; case 0: /* float */ if (!float_type) continue; if (format != 32 || type != float_type) { fprintf(stderr, " %-23s = format mismatch (%d)\n", par->name, format); break; } f = (union flong *) data; f[par->prop_offset].f = val; break; } XChangeDeviceProperty(dpy, dev, prop, type, format, PropModeReplace, data, nitems); XFlush(dpy); } }
void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi, vorbis_info_psy_global *gi,int n,long rate){ long i,j,lo=-99,hi=1; long maxoc; memset(p,0,sizeof(*p)); p->eighth_octave_lines=gi->eighth_octave_lines; p->shiftoc=rint(log(gi->eighth_octave_lines*8.f)/log(2.f))-1; p->firstoc=toOC(.25f*rate*.5/n)*(1<<(p->shiftoc+1))-gi->eighth_octave_lines; maxoc=toOC((n+.25f)*rate*.5/n)*(1<<(p->shiftoc+1))+.5f; p->total_octave_lines=maxoc-p->firstoc+1; p->ath=_ogg_malloc(n*sizeof(*p->ath)); p->octave=_ogg_malloc(n*sizeof(*p->octave)); p->bark=_ogg_malloc(n*sizeof(*p->bark)); p->vi=vi; p->n=n; p->rate=rate; /* AoTuV HF weighting */ p->m_val = 1.; if(rate < 26000) p->m_val = 0; else if(rate < 38000) p->m_val = .94; /* 32kHz */ else if(rate > 46000) p->m_val = 1.275; /* 48kHz */ /* set up the lookups for a given blocksize and sample rate */ for(i=0,j=0;i<MAX_ATH-1;i++){ int endpos=rint(fromOC((i+1)*.125-2.)*2*n/rate); float base=ATH[i]; if(j<endpos){ float delta=(ATH[i+1]-base)/(endpos-j); for(;j<endpos && j<n;j++){ p->ath[j]=base+100.; base+=delta; } } } for(i=0;i<n;i++){ float bark=toBARK(rate/(2*n)*i); for(;lo+vi->noisewindowlomin<i && toBARK(rate/(2*n)*lo)<(bark-vi->noisewindowlo);lo++); for(;hi<=n && (hi<i+vi->noisewindowhimin || toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++); p->bark[i]=((lo-1)<<16)+(hi-1); } for(i=0;i<n;i++) p->octave[i]=toOC((i+.25f)*.5*rate/n)*(1<<(p->shiftoc+1))+.5f; p->tonecurves=setup_tone_curves(vi->toneatt,rate*.5/n,n, vi->tone_centerboost,vi->tone_decay); /* set up rolling noise median */ p->noiseoffset=_ogg_malloc(P_NOISECURVES*sizeof(*p->noiseoffset)); for(i=0;i<P_NOISECURVES;i++) p->noiseoffset[i]=_ogg_malloc(n*sizeof(**p->noiseoffset)); for(i=0;i<n;i++){ float halfoc=toOC((i+.5)*rate/(2.*n))*2.; int inthalfoc; float del; if(halfoc<0)halfoc=0; if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1; inthalfoc=(int)halfoc; del=halfoc-inthalfoc; for(j=0;j<P_NOISECURVES;j++) p->noiseoffset[j][i]= p->vi->noiseoff[j][inthalfoc]*(1.-del) + p->vi->noiseoff[j][inthalfoc+1]*del; } #if 0 { static int ls=0; _analysis_output_always("noiseoff0",ls,p->noiseoffset[0],n,1,0,0); _analysis_output_always("noiseoff1",ls,p->noiseoffset[1],n,1,0,0); _analysis_output_always("noiseoff2",ls++,p->noiseoffset[2],n,1,0,0); } #endif }
/****************************************************************************** MODULE: prctile2 PURPOSE: Calculate Percentile of a floating point array RETURN: SUCCESS FAILURE HISTORY: Date Programmer Reason -------- --------------- ------------------------------------- 3/15/2013 Song Guo Original Development Nov/2014 Ron Dilley Speed improvements by removing divisions NOTES: ******************************************************************************/ int prctile2 ( float *array, /*I: input data pointer */ int nums, /*I: number of input data array */ float min, /*I: minimum value in the input data array */ float max, /*I: maximum value in the input data array */ float prct, /*I: percentage threshold */ float *result /*O: percentile calculated */ ) { int *interval; /* array to store data in an interval */ int i, j; /* loop variables */ int start, end; /* start/end variables */ int loops; /* data range of input data */ float inv_nums_100; /* inverse of the nums value * 100 */ int sum; /* Just return 0 if no input value */ if (nums == 0) { *result = 0.0; return SUCCESS; } else { *result = max; } start = (int) rint (min); end = (int) rint (max); loops = end - start + 2; interval = calloc (loops, sizeof (int)); if (interval == NULL) { RETURN_ERROR ("Invalid memory allocation", "prctile2", FAILURE); } for (i = 0; i < nums; i++) { interval[(int) rint (array[i]) - start]++; } inv_nums_100 = (1.0/((float) nums)) * 100.0; sum = 0; for (j = 0; j < loops; j++) { sum += interval[j]; if (((float) sum * inv_nums_100) >= prct) { *result = (float) (start + j); break; } else { continue; } } free (interval); return SUCCESS; }
int main(int argc,char *argv[]){ int c,long_option_index,ret; ogg_stream_state to; /* take physical pages, weld into a logical stream of packets */ ogg_stream_state vo; /* take physical pages, weld into a logical stream of packets */ ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */ ogg_packet op; /* one raw packet of data for decode */ theora_state td; theora_info ti; theora_comment tc; vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */ vorbis_comment vc; /* struct that stores all the user comments */ vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ vorbis_block vb; /* local working space for packet->PCM decode */ int audioflag=0; int videoflag=0; int akbps=0; int vkbps=0; ogg_int64_t audio_bytesout=0; ogg_int64_t video_bytesout=0; double timebase; FILE* outfile = stdout; #ifdef _WIN32 # ifdef THEORA_PERF_DATA LARGE_INTEGER start_time; LARGE_INTEGER final_time; LONGLONG elapsed_ticks; LARGE_INTEGER ticks_per_second; LONGLONG elapsed_secs; LONGLONG elapsed_sec_mod; double elapsed_secs_dbl ; # endif /* We need to set stdin/stdout to binary mode. Damn windows. */ /* if we were reading/writing a file, it would also need to in binary mode, eg, fopen("file.wav","wb"); */ /* Beware the evil ifdef. We avoid these where we can, but this one we cannot. Don't add any more, you'll probably go to hell if you do. */ _setmode( _fileno( stdin ), _O_BINARY ); _setmode( _fileno( stdout ), _O_BINARY ); #endif while((c=getopt_long(argc,argv,optstring,options,&long_option_index))!=EOF){ switch(c){ case 'o': outfile=fopen(optarg,"wb"); if(outfile==NULL){ fprintf(stderr,"Unable to open output file '%s'\n", optarg); exit(1); } break;; case 'a': audio_q=atof(optarg)*.099; if(audio_q<-.1 || audio_q>1){ fprintf(stderr,"Illegal audio quality (choose -1 through 10)\n"); exit(1); } audio_r=-1; break; case 'v': video_q=rint(atof(optarg)*6.3); if(video_q<0 || video_q>63){ fprintf(stderr,"Illegal video quality (choose 0 through 10)\n"); exit(1); } video_r=0; break; case 'A': audio_r=atof(optarg)*1000; if(audio_q<0){ fprintf(stderr,"Illegal audio quality (choose > 0 please)\n"); exit(1); } audio_q=-99; break; case 'V': video_r=rint(atof(optarg)*1000); if(video_r<45000 || video_r>2000000){ fprintf(stderr,"Illegal video bitrate (choose 45kbps through 2000kbps)\n"); exit(1); } video_q=0; break; case 's': video_an=rint(atof(optarg)); break; case 'S': video_ad=rint(atof(optarg)); break; case 'f': video_hzn=rint(atof(optarg)); break; case 'F': video_hzd=rint(atof(optarg)); break; default: usage(); } } while(optind<argc){ /* assume that anything following the options must be a filename */ id_file(argv[optind]); optind++; } #ifdef THEORA_PERF_DATA # ifdef WIN32 QueryPerformanceCounter(&start_time); # endif #endif /* yayness. Set up Ogg output stream */ srand(time(NULL)); { /* need two inequal serial numbers */ int serial1, serial2; serial1 = rand(); serial2 = rand(); if (serial1 == serial2) serial2++; ogg_stream_init(&to,serial1); ogg_stream_init(&vo,serial2); } /* Set up Theora encoder */ if(!video){ fprintf(stderr,"No video files submitted for compression?\n"); exit(1); } /* Theora has a divisible-by-sixteen restriction for the encoded video size */ /* scale the frame size up to the nearest /16 and calculate offsets */ video_x=((frame_x + 15) >>4)<<4; video_y=((frame_y + 15) >>4)<<4; /* We force the offset to be even. This ensures that the chroma samples align properly with the luma samples. */ frame_x_offset=((video_x-frame_x)/2)&~1; frame_y_offset=((video_y-frame_y)/2)&~1; theora_info_init(&ti); ti.width=video_x; ti.height=video_y; ti.frame_width=frame_x; ti.frame_height=frame_y; ti.offset_x=frame_x_offset; ti.offset_y=frame_y_offset; ti.fps_numerator=video_hzn; ti.fps_denominator=video_hzd; ti.aspect_numerator=video_an; ti.aspect_denominator=video_ad; ti.colorspace=OC_CS_UNSPECIFIED; ti.pixelformat=OC_PF_420; ti.target_bitrate=video_r; ti.quality=video_q; ti.dropframes_p=0; ti.quick_p=1; ti.keyframe_auto_p=1; ti.keyframe_frequency=64; ti.keyframe_frequency_force=64; ti.keyframe_data_target_bitrate=video_r*1.5; ti.keyframe_auto_threshold=80; ti.keyframe_mindistance=8; ti.noise_sensitivity=1; theora_encode_init(&td,&ti); theora_info_clear(&ti); /* initialize Vorbis too, assuming we have audio to compress. */ if(audio){ vorbis_info_init(&vi); if(audio_q>-99) ret = vorbis_encode_init_vbr(&vi,audio_ch,audio_hz,audio_q); else ret = vorbis_encode_init(&vi,audio_ch,audio_hz,-1,audio_r,-1); if(ret){ fprintf(stderr,"The Vorbis encoder could not set up a mode according to\n" "the requested quality or bitrate.\n\n"); exit(1); } vorbis_comment_init(&vc); vorbis_analysis_init(&vd,&vi); vorbis_block_init(&vd,&vb); } /* write the bitstream header packets with proper page interleave */ /* first packet will get its own page automatically */ theora_encode_header(&td,&op); ogg_stream_packetin(&to,&op); if(ogg_stream_pageout(&to,&og)!=1){ fprintf(stderr,"Internal Ogg library error.\n"); exit(1); } fwrite(og.header,1,og.header_len,outfile); fwrite(og.body,1,og.body_len,outfile); /* create the remaining theora headers */ theora_comment_init(&tc); theora_encode_comment(&tc,&op); ogg_stream_packetin(&to,&op); /*theora_encode_comment() doesn't take a theora_state parameter, so it has to allocate its own buffer to pass back the packet data. If we don't free it here, we'll leak. libogg2 makes this much cleaner: the stream owns the buffer after you call packetin in libogg2, but this is not true in libogg1.*/ free(op.packet); theora_encode_tables(&td,&op); ogg_stream_packetin(&to,&op); if(audio){ ogg_packet header; ogg_packet header_comm; ogg_packet header_code; vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code); ogg_stream_packetin(&vo,&header); /* automatically placed in its own page */ if(ogg_stream_pageout(&vo,&og)!=1){ fprintf(stderr,"Internal Ogg library error.\n"); exit(1); } fwrite(og.header,1,og.header_len,outfile); fwrite(og.body,1,og.body_len,outfile); /* remaining vorbis header packets */ ogg_stream_packetin(&vo,&header_comm); ogg_stream_packetin(&vo,&header_code); } /* Flush the rest of our headers. This ensures the actual data in each stream will start on a new page, as per spec. */ while(1){ int result = ogg_stream_flush(&to,&og); if(result<0){ /* can't get here */ fprintf(stderr,"Internal Ogg library error.\n"); exit(1); } if(result==0)break; fwrite(og.header,1,og.header_len,outfile); fwrite(og.body,1,og.body_len,outfile); } if(audio){ while(1){ int result=ogg_stream_flush(&vo,&og); if(result<0){ /* can't get here */ fprintf(stderr,"Internal Ogg library error.\n"); exit(1); } if(result==0)break; fwrite(og.header,1,og.header_len,outfile); fwrite(og.body,1,og.body_len,outfile); } } /* setup complete. Raw processing loop */ fprintf(stderr,"Compressing....\n"); while(1){ ogg_page audiopage; ogg_page videopage; /* is there an audio page flushed? If not, fetch one if possible */ audioflag=fetch_and_process_audio(audio,&audiopage,&vo,&vd,&vb,audioflag); /* is there a video page flushed? If not, fetch one if possible */ videoflag=fetch_and_process_video(video,&videopage,&to,&td,videoflag); /* no pages of either? Must be end of stream. */ if(!audioflag && !videoflag)break; /* which is earlier; the end of the audio page or the end of the video page? Flush the earlier to stream */ { int audio_or_video=-1; double audiotime= audioflag?vorbis_granule_time(&vd,ogg_page_granulepos(&audiopage)):-1; double videotime= videoflag?theora_granule_time(&td,ogg_page_granulepos(&videopage)):-1; if(!audioflag){ audio_or_video=1; } else if(!videoflag) { audio_or_video=0; } else { if(audiotime<videotime) audio_or_video=0; else audio_or_video=1; } if(audio_or_video==1){ /* flush a video page */ video_bytesout+=fwrite(videopage.header,1,videopage.header_len,outfile); video_bytesout+=fwrite(videopage.body,1,videopage.body_len,outfile); videoflag=0; timebase=videotime; }else{ /* flush an audio page */ audio_bytesout+=fwrite(audiopage.header,1,audiopage.header_len,outfile); audio_bytesout+=fwrite(audiopage.body,1,audiopage.body_len,outfile); audioflag=0; timebase=audiotime; } { int hundredths=timebase*100-(long)timebase*100; int seconds=(long)timebase%60; int minutes=((long)timebase/60)%60; int hours=(long)timebase/3600; if(audio_or_video) vkbps=rint(video_bytesout*8./timebase*.001); else akbps=rint(audio_bytesout*8./timebase*.001); fprintf(stderr, "\r %d:%02d:%02d.%02d audio: %dkbps video: %dkbps ", hours,minutes,seconds,hundredths,akbps,vkbps); } } } /* clear out state */ if(audio){ ogg_stream_clear(&vo); vorbis_block_clear(&vb); vorbis_dsp_clear(&vd); vorbis_comment_clear(&vc); vorbis_info_clear(&vi); } if(video){ ogg_stream_clear(&to); theora_clear(&td); } if(outfile && outfile!=stdout)fclose(outfile); fprintf(stderr,"\r \ndone.\n\n"); #ifdef THEORA_PERF_DATA # ifdef WIN32 QueryPerformanceCounter(&final_time); elapsed_ticks = final_time.QuadPart - start_time.QuadPart; ticks_per_second; QueryPerformanceFrequency(&ticks_per_second); elapsed_secs = elapsed_ticks / ticks_per_second.QuadPart; elapsed_sec_mod = elapsed_ticks % ticks_per_second.QuadPart; elapsed_secs_dbl = elapsed_secs; elapsed_secs_dbl += ((double)elapsed_sec_mod / (double)ticks_per_second.QuadPart); printf("Encode time = %lld ticks\n", elapsed_ticks); printf("~%lld and %lld / %lld seconds\n", elapsed_secs, elapsed_sec_mod, ticks_per_second.QuadPart); printf("~%Lf seconds\n", elapsed_secs_dbl); # endif #endif return(0); }
int minval=book->minval; int del=book->delta; int qv=book->quantvals; int ze=(qv>>1); int index=0; /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */ if(del!=1){ for(i=0,o=step*(dim-1);i<dim;i++,o-=step){ int v = ((int)rint(a[o])-minval+(del>>1))/del; int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1)); index = index*qv+ (m<0?0:(m>=qv?qv-1:m)); } }else{ for(i=0,o=step*(dim-1);i<dim;i++,o-=step){ int v = (int)rint(a[o])-minval; int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1)); index = index*qv+ (m<0?0:(m>=qv?qv-1:m)); } } if(book->c->lengthlist[index]<=0){ const static_codebook *c=book->c; int best=-1; /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */ int e[8]={0,0,0,0,0,0,0,0}; int maxval = book->minval + book->delta*(book->quantvals-1); for(i=0;i<book->entries;i++){ if(c->lengthlist[i]>0){ float this=0; for(j=0;j<dim;j++){
int ltc_encoder_dec_timecode(LTCEncoder *e) { return ltc_frame_decrement (&e->f, rint(e->fps), e->standard, e->flags); }
int main(int argc,char *argv[]){ vqgen v; int entries=-1,dim=-1; int start=0,num=-1; float desired=.05f,mindist=0.f; int iter=1000; int biasp=1; int centroid=0; FILE *out=NULL; char *line; long i,j,k; int init=0; q.quant=-1; argv++; if(!*argv){ usage(); exit(0); } /* get the book name, a preexisting book to continue training */ { FILE *in=NULL; char *filename=alloca(strlen(*argv)+30),*ptr; strcpy(filename,*argv); in=fopen(filename,"r"); ptr=strrchr(filename,'-'); if(ptr){ int num; ptr++; num=atoi(ptr); sprintf(ptr,"%d.vqi",num+1); }else strcat(filename,"-0.vqi"); out=fopen(filename,"w"); if(out==NULL){ fprintf(stderr,"Unable to open %s for writing\n",filename); exit(1); } if(in){ /* we wish to suck in a preexisting book and continue to train it */ float a; line=rline(in,out,1); if(strcmp(line,vqext_booktype)){ fprintf(stderr,"wrong book type; %s!=%s\n",line,vqext_booktype); exit(1); } line=rline(in,out,1); if(sscanf(line,"%d %d %d",&entries,&dim,&vqext_aux)!=3){ fprintf(stderr,"Syntax error reading book file\n"); exit(1); } vqgen_init(&v,dim,vqext_aux,entries,mindist, vqext_metric,vqext_weight,centroid); init=1; /* quant setup */ line=rline(in,out,1); if(sscanf(line,"%ld %ld %d %d",&q.min,&q.delta, &q.quant,&q.sequencep)!=4){ fprintf(stderr,"Syntax error reading book file\n"); exit(1); } /* quantized entries */ i=0; for(j=0;j<entries;j++){ for(k=0;k<dim;k++){ line=rline(in,out,0); sscanf(line,"%f",&a); v.entrylist[i++]=a; } } vqgen_unquantize(&v,&q); /* bias */ i=0; for(j=0;j<entries;j++){ line=rline(in,out,0); sscanf(line,"%f",&a); v.bias[i++]=a; } v.seeded=1; { float *b=alloca((dim+vqext_aux)*sizeof(float)); i=0; while(1){ for(k=0;k<dim+vqext_aux;k++){ line=rline(in,out,0); if(!line)break; sscanf(line,"%f",b+k); } if(feof(in))break; vqgen_addpoint(&v,b,b+dim); } } fclose(in); } } /* get the rest... */ argv=argv++; while(*argv){ if(argv[0][0]=='-'){ /* it's an option */ if(!argv[1]){ fprintf(stderr,"Option %s missing argument.\n",argv[0]); exit(1); } switch(argv[0][1]){ case 'p': if(sscanf(argv[1],"%d,%d,%d",&entries,&dim,&q.quant)!=3) goto syner; break; case 's': if(sscanf(argv[1],"%d,%d",&start,&num)!=2){ num= -1; if(sscanf(argv[1],"%d",&start)!=1) goto syner; } break; case 'e': if(sscanf(argv[1],"%f",&desired)!=1) goto syner; break; case 'd': if(sscanf(argv[1],"%f",&mindist)!=1) goto syner; if(init)v.mindist=mindist; break; case 'i': if(sscanf(argv[1],"%d",&iter)!=1) goto syner; break; case 'b': biasp=0; break; case 'c': centroid=1; break; default: fprintf(stderr,"Unknown option %s\n",argv[0]); exit(1); } argv+=2; }else{ /* it's an input file */ char *file=strdup(*argv++); FILE *in; int cols=-1; if(!init){ if(dim==-1 || entries==-1 || q.quant==-1){ fprintf(stderr,"-p required when training a new set\n"); exit(1); } vqgen_init(&v,dim,vqext_aux,entries,mindist, vqext_metric,vqext_weight,centroid); init=1; } in=fopen(file,"r"); if(in==NULL){ fprintf(stderr,"Could not open input file %s\n",file); exit(1); } fprintf(out,"# training file entry: %s\n",file); while((line=rline(in,out,0))){ if(cols==-1){ char *temp=line; while(*temp==' ')temp++; for(cols=0;*temp;cols++){ while(*temp>32)temp++; while(*temp==' ')temp++; } fprintf(stderr,"%d colums per line in file %s\n",cols,file); } { int i; float b[cols]; if(start+num*dim>cols){ fprintf(stderr,"ran out of columns reading %s\n",file); exit(1); } while(*line==' ')line++; for(i=0;i<cols;i++){ /* static length buffer bug workaround */ char *temp=line; char old; while(*temp>32)temp++; old=temp[0]; temp[0]='\0'; b[i]=atof(line); temp[0]=old; while(*line>32)line++; while(*line==' ')line++; } if(num<=0)num=(cols-start)/dim; for(i=0;i<num;i++) vqext_addpoint_adj(&v,b,start+i*dim,dim,cols,num); } } fclose(in); } } if(!init){ fprintf(stderr,"No input files!\n"); exit(1); } vqext_preprocess(&v); /* train the book */ signal(SIGTERM,setexit); signal(SIGINT,setexit); for(i=0;i<iter && !exiting;i++){ float result; if(i!=0){ vqgen_unquantize(&v,&q); vqgen_cellmetric(&v); } result=vqgen_iterate(&v,biasp); vqext_quantize(&v,&q); if(result<desired)break; } /* save the book */ fprintf(out,"# OggVorbis VQ codebook trainer, intermediate file\n"); fprintf(out,"%s\n",vqext_booktype); fprintf(out,"%d %d %d\n",entries,dim,vqext_aux); fprintf(out,"%ld %ld %d %d\n", q.min,q.delta,q.quant,q.sequencep); /* quantized entries */ fprintf(out,"# quantized entries---\n"); i=0; for(j=0;j<entries;j++) for(k=0;k<dim;k++) fprintf(out,"%d\n",(int)(rint(v.entrylist[i++]))); fprintf(out,"# biases---\n"); i=0; for(j=0;j<entries;j++) fprintf(out,"%f\n",v.bias[i++]); /* we may have done the density limiting mesh trick; refetch the training points from the temp file */ rewind(v.asciipoints); fprintf(out,"# points---\n"); { /* sloppy, no error handling */ long bytes; char buff[4096]; while((bytes=fread(buff,1,4096,v.asciipoints))) while(bytes)bytes-=fwrite(buff,1,bytes,out); } fclose(out); fclose(v.asciipoints); vqgen_unquantize(&v,&q); vqgen_cellmetric(&v); exit(0); syner: fprintf(stderr,"Syntax error in argument '%s'\n",*argv); exit(1); }