mirror of
https://github.com/cookiengineer/audacity
synced 2025-04-30 07:39:42 +02:00
283 lines
6.7 KiB
C
283 lines
6.7 KiB
C
/********************************************************************
|
|
* *
|
|
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
|
|
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
|
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
|
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
|
* *
|
|
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
|
|
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
|
* *
|
|
********************************************************************
|
|
|
|
function: residue backend 0 partitioner/classifier
|
|
last mod: $Id: residuesplit.c,v 1.4 2008-02-02 15:54:09 richardash1981 Exp $
|
|
|
|
********************************************************************/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include "bookutil.h"
|
|
|
|
/* does not guard against invalid settings; eg, a subn of 16 and a
|
|
subgroup request of 32. Max subn of 128 */
|
|
static float _testhack(float *vec,int n){
|
|
int i,j=0;
|
|
float max=0.f;
|
|
float temp[128];
|
|
float entropy=0.;
|
|
|
|
/* setup */
|
|
for(i=0;i<n;i++)temp[i]=fabs(vec[i]);
|
|
|
|
/* handle case subgrp==1 outside */
|
|
for(i=0;i<n;i++)
|
|
if(temp[i]>max)max=temp[i];
|
|
|
|
for(i=0;i<n;i++)temp[i]=rint(temp[i]);
|
|
|
|
for(i=0;i<n;i++)
|
|
entropy+=temp[i];
|
|
return entropy;
|
|
|
|
/*while(1){
|
|
entropy[j]=max;
|
|
n>>=1;
|
|
j++;
|
|
|
|
if(n<=0)break;
|
|
for(i=0;i<n;i++){
|
|
temp[i]+=temp[i+n];
|
|
}
|
|
max=0.f;
|
|
for(i=0;i<n;i++)
|
|
if(temp[i]>max)max=temp[i];
|
|
}*/
|
|
}
|
|
|
|
static FILE *of;
|
|
static FILE **or;
|
|
|
|
/* we evaluate the the entropy measure for each interleaved subgroup */
|
|
/* This is currently a bit specific to/hardwired for mapping 0; things
|
|
will need to change in the future when we get real multichannel
|
|
mappings */
|
|
int quantaux(float *res,int n,float *ebound,float *mbound,int *subgrp,int parts, int subn,
|
|
int *class){
|
|
long i,j,part=0;
|
|
int aux;
|
|
|
|
for(i=0;i<=n-subn;i+=subn,part++){
|
|
float max=0.f;
|
|
float lentropy=0.f;
|
|
|
|
lentropy=_testhack(res+i,subn);
|
|
|
|
for(j=0;j<subn;j++)
|
|
if(fabs(res[i+j])>max)max=fabs(res[i+j]);
|
|
|
|
for(j=0;j<parts-1;j++)
|
|
if(lentropy<=ebound[j] &&
|
|
max<=mbound[j] &&
|
|
part<subgrp[j])
|
|
break;
|
|
class[part]=aux=j;
|
|
|
|
fprintf(of,"%d, ",aux);
|
|
}
|
|
fprintf(of,"\n");
|
|
|
|
return(0);
|
|
}
|
|
|
|
int quantwrite(float *res,int n,int subn, int *class,int offset){
|
|
long i,j,part=0;
|
|
int aux;
|
|
|
|
for(i=0;i<=n-subn;i+=subn,part++){
|
|
aux=class[part];
|
|
|
|
for(j=0;j<subn;j++)
|
|
fprintf(or[aux+offset],"%g, ",res[j+i]);
|
|
|
|
fprintf(or[aux+offset],"\n");
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
static int getline(FILE *in,float *vec,int begin,int n){
|
|
int i,next=0;
|
|
|
|
reset_next_value();
|
|
if(get_next_value(in,vec))return(0);
|
|
if(begin){
|
|
for(i=1;i<begin;i++)
|
|
get_line_value(in,vec);
|
|
next=0;
|
|
}else{
|
|
next=1;
|
|
}
|
|
|
|
for(i=next;i<n;i++)
|
|
if(get_line_value(in,vec+i)){
|
|
fprintf(stderr,"ran out of columns in input data\n");
|
|
exit(1);
|
|
}
|
|
|
|
return(1);
|
|
}
|
|
|
|
static void usage(){
|
|
fprintf(stderr,
|
|
"usage:\n"
|
|
"residuesplit <res> [<res>] <begin,n,group> <baseout> <ent,peak,sub> [<ent,peak,sub>]...\n"
|
|
" where begin,n,group is first scalar, \n"
|
|
" number of scalars of each in line,\n"
|
|
" number of scalars in a group\n"
|
|
" ent is the maximum entropy value allowed for membership in a group\n"
|
|
" peak is the maximum amplitude value allowed for membership in a group\n"
|
|
" subn is the maximum subpartiton number allowed in the group\n\n");
|
|
exit(1);
|
|
}
|
|
|
|
int main(int argc, char *argv[]){
|
|
char *buffer;
|
|
char *base;
|
|
int i,j,parts,begin,n,subn,*subgrp,*class;
|
|
FILE **res;
|
|
int resfiles=0;
|
|
float *ebound,*mbound,*vec;
|
|
long c=0;
|
|
if(argc<5)usage();
|
|
|
|
/* count the res file names, open the files */
|
|
while(!strcmp(argv[resfiles+1]+strlen(argv[resfiles+1])-4,".vqd"))
|
|
resfiles++;
|
|
if(resfiles<1)usage();
|
|
|
|
res=alloca(sizeof(*res)*resfiles);
|
|
for(i=0;i<resfiles;i++){
|
|
res[i]=fopen(argv[i+1],"r");
|
|
if(!(res+i)){
|
|
fprintf(stderr,"Could not open file %s\n",argv[1+i]);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
base=strdup(argv[2+resfiles]);
|
|
buffer=alloca(strlen(base)+20);
|
|
{
|
|
char *pos=strchr(argv[1+resfiles],',');
|
|
begin=atoi(argv[1+resfiles]);
|
|
if(!pos)
|
|
usage();
|
|
else
|
|
n=atoi(pos+1);
|
|
pos=strchr(pos+1,',');
|
|
if(!pos)
|
|
usage();
|
|
else
|
|
subn=atoi(pos+1);
|
|
if(n/subn*subn != n){
|
|
fprintf(stderr,"n must be divisible by group\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
/* how many parts?... */
|
|
parts=argc-resfiles-2;
|
|
|
|
ebound=_ogg_malloc(sizeof(float)*parts);
|
|
mbound=_ogg_malloc(sizeof(float)*parts);
|
|
subgrp=_ogg_malloc(sizeof(int)*parts);
|
|
|
|
for(i=0;i<parts-1;i++){
|
|
char *pos=strchr(argv[3+i+resfiles],',');
|
|
subgrp[i]=0;
|
|
if(*argv[3+i+resfiles]==',')
|
|
ebound[i]=1e50f;
|
|
else
|
|
ebound[i]=atof(argv[3+i+resfiles]);
|
|
|
|
if(!pos){
|
|
mbound[i]=1e50f;
|
|
}else{
|
|
if(*(pos+1)==',')
|
|
mbound[i]=1e50f;
|
|
else
|
|
mbound[i]=atof(pos+1);
|
|
pos=strchr(pos+1,',');
|
|
|
|
if(pos)
|
|
subgrp[i]=atoi(pos+1);
|
|
|
|
}
|
|
if(subgrp[i]<=0)subgrp[i]=99999;
|
|
}
|
|
|
|
ebound[i]=1e50f;
|
|
mbound[i]=1e50f;
|
|
subgrp[i]=9999999;
|
|
|
|
or=alloca(parts*resfiles*sizeof(FILE*));
|
|
sprintf(buffer,"%saux.vqd",base);
|
|
of=fopen(buffer,"w");
|
|
if(!of){
|
|
fprintf(stderr,"Could not open file %s for writing\n",buffer);
|
|
exit(1);
|
|
}
|
|
|
|
for(j=0;j<resfiles;j++){
|
|
for(i=0;i<parts;i++){
|
|
sprintf(buffer,"%s_%d%c.vqd",base,i,j+65);
|
|
or[i+j*parts]=fopen(buffer,"w");
|
|
if(!or[i+j*parts]){
|
|
fprintf(stderr,"Could not open file %s for writing\n",buffer);
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
vec=_ogg_malloc(sizeof(float)*n);
|
|
class=_ogg_malloc(sizeof(float)*n);
|
|
/* get the input line by line and process it */
|
|
while(1){
|
|
if(getline(res[0],vec,begin,n)){
|
|
quantaux(vec,n,ebound,mbound,subgrp,parts,subn,class);
|
|
quantwrite(vec,n,subn,class,0);
|
|
|
|
for(i=1;i<resfiles;i++){
|
|
if(getline(res[i],vec,begin,n)){
|
|
quantwrite(vec,n,subn,class,parts*i);
|
|
}else{
|
|
fprintf(stderr,"Getline loss of sync (%d).\n\n",i);
|
|
exit(1);
|
|
}
|
|
}
|
|
}else{
|
|
if(feof(res[0]))break;
|
|
fprintf(stderr,"Getline loss of sync (0).\n\n");
|
|
exit(1);
|
|
}
|
|
|
|
c++;
|
|
if(!(c&0xf)){
|
|
spinnit("kB so far...",(int)(ftell(res[0])/1024));
|
|
}
|
|
}
|
|
for(i=0;i<resfiles;i++)
|
|
fclose(res[i]);
|
|
fclose(of);
|
|
for(i=0;i<parts*resfiles;i++)
|
|
fclose(or[i]);
|
|
fprintf(stderr,"\rDone \n");
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
|