int st_wvestartwrite(ft_t ft) { wve_t p = (wve_t ) ft->priv; int rc; /* Needed for rawwrite() */ rc = st_rawstartwrite(ft); if (rc) return ST_EOF; /* wve is in big endian format. Swap whats read in * on little endian machines. */ if (ST_IS_LITTLEENDIAN) { ft->swap = ft->swap ? 0 : 1; } p->length = 0; if (p->repeats == 0) p->repeats = 1; if (ft->info.rate != 0) st_report("WVE must use 8000 sample rate. Overriding"); if (ft->info.channels != -1 && ft->info.channels != 1) st_report("WVE must only supports 1 channel. Overriding"); ft->info.encoding = ST_ENCODING_ALAW; ft->info.size = ST_SIZE_BYTE; ft->info.rate = 8000; wvewriteheader(ft); return ST_SUCCESS; }
/* * Process options */ int st_resample_getopts(eff_t effp, int n, char **argv) { resample_t r = (resample_t) effp->priv; /* These defaults are conservative with respect to aliasing. */ r->rolloff = 0.80; r->beta = 16; /* anything <=2 means Nutall window */ r->quadr = 0; r->Nmult = 45; /* This used to fail, but with sox-12.15 it works. AW */ if ((n >= 1)) { if (!strcmp(argv[0], "-qs")) { r->quadr = 1; n--; argv++; } else if (!strcmp(argv[0], "-q")) { r->rolloff = 0.875; r->quadr = 1; r->Nmult = 75; n--; argv++; } else if (!strcmp(argv[0], "-ql")) { r->rolloff = 0.94; r->quadr = 1; r->Nmult = 149; n--; argv++; } } if ((n >= 1) && (sscanf(argv[0], "%lf", &r->rolloff) != 1)) { st_fail("Usage: resample [ rolloff [ beta ] ]"); return (ST_EOF); } else if ((r->rolloff <= 0.01) || (r->rolloff >= 1.0)) { st_fail("resample: rolloff factor (%f) no good, should be 0.01<x<1.0", r->rolloff); return(ST_EOF); } if ((n >= 2) && !sscanf(argv[1], "%lf", &r->beta)) { st_fail("Usage: resample [ rolloff [ beta ] ]"); return (ST_EOF); } else if (r->beta <= 2.0) { r->beta = 0; st_report("resample opts: Nuttall window, cutoff %f\n", r->rolloff); } else { st_report("resample opts: Kaiser window, cutoff %f, beta %f\n", r->rolloff, r->beta); } return (ST_SUCCESS); }
/* * Prepare processing. */ int st_resample_start(eff_t effp) { resample_t r = (resample_t) effp->priv; long Xoff, gcdrate; int i; if (effp->ininfo.rate == effp->outinfo.rate) { st_fail("Input and Output rates must be different to use resample effect"); return(ST_EOF); } r->Factor = (double)effp->outinfo.rate / (double)effp->ininfo.rate; gcdrate = st_gcd((long)effp->ininfo.rate, (long)effp->outinfo.rate); r->a = effp->ininfo.rate / gcdrate; r->b = effp->outinfo.rate / gcdrate; if (r->a <= r->b && r->b <= NQMAX) { r->quadr = -1; /* exact coeff's */ r->Nq = r->b; /* MAX(r->a,r->b); */ } else { r->Nq = Nc; /* for now */ } /* Check for illegal constants */ # if 0 if (Lp >= 16) st_fail("Error: Lp>=16"); if (Nb+Nhg+NLpScl >= 32) st_fail("Error: Nb+Nhg+NLpScl>=32"); if (Nh+Nb > 32) st_fail("Error: Nh+Nb>32"); # endif /* Nwing: # of filter coeffs in right wing */ r->Nwing = r->Nq * (r->Nmult/2+1) + 1; r->Imp = (Float *)malloc(sizeof(Float) * (r->Nwing+2)) + 1; /* need Imp[-1] and Imp[Nwing] for quadratic interpolation */ /* returns error # <=0, or adjusted wing-len > 0 */ i = makeFilter(r->Imp, r->Nwing, r->rolloff, r->beta, r->Nq, 1); if (i <= 0) { st_fail("resample: Unable to make filter\n"); return (ST_EOF); } /*st_report("Nmult: %ld, Nwing: %ld, Nq: %ld\n",r->Nmult,r->Nwing,r->Nq);*/ if (r->quadr < 0) { /* exact coeff's method */ r->Xh = r->Nwing/r->b; st_report("resample: rate ratio %ld:%ld, coeff interpolation not needed\n", r->a, r->b); } else { r->dhb = Np; /* Fixed-point Filter sampling-time-increment */ if (r->Factor<1.0) r->dhb = r->Factor*Np + 0.5; r->Xh = (r->Nwing<<La)/r->dhb; /* (Xh * dhb)>>La is max index into Imp[] */ } /* reach of LP filter wings + some creeping room */ Xoff = r->Xh + 10; r->Xoff = Xoff; /* Current "now"-sample pointer for input to filter */ r->Xp = Xoff; /* Position in input array to read into */ r->Xread = Xoff; /* Current-time pointer for converter */ r->Time = Xoff; if (r->quadr < 0) { /* exact coeff's method */ r->t = Xoff*r->Nq; } i = BUFFSIZE - 2*Xoff; if (i < r->Factor + 1.0/r->Factor) /* Check input buffer size */ { st_fail("Factor is too small or large for BUFFSIZE"); return (ST_EOF); } r->Xsize = 2*Xoff + i/(1.0+r->Factor); r->Ysize = BUFFSIZE - r->Xsize; /* st_report("Xsize %d, Ysize %d, Xoff %d",r->Xsize,r->Ysize,r->Xoff); */ r->X = (Float *) malloc(sizeof(Float) * (BUFFSIZE)); r->Y = r->X + r->Xsize; /* Need Xoff zeros at beginning of sample */ for (i=0; i<Xoff; i++) r->X[i] = 0; return (ST_SUCCESS); }
int st_wvestartread(ft_t ft) { wve_t p = (wve_t ) ft->priv; char magic[16]; short version; int rc; uint16_t trash16; /* Needed for rawread() */ rc = st_rawstartread(ft); if (rc) return rc; /* WVE is in big endian format. Swap whats read in * on little endian machines. */ if (ST_IS_LITTLEENDIAN) { ft->swap = ft->swap ? 0 : 1; } /* Check the magic word (null-terminated) */ st_reads(ft, magic, 16); if (strncmp(magic, PSION_MAGIC, 15)==0) { st_report("Found Psion magic word"); } else { st_fail_errno(ft,ST_EHDR,"Psion header doesn't start with magic word\nTry the '.al' file type with '-t al -r 8000 filename'"); return (ST_EOF); } st_readw(ft, (unsigned short *)&version); /* Check for what type endian machine its read on */ if (version == PSION_INV_VERSION) { /* This is probably left over from a time before * testing for endianess was standardized. Leaving since * it doesn't hurt. */ ft->swap = ft->swap ? 0 : 1; st_report("Found inverted PSION magic word. Swapping bytes."); } else if (version == PSION_VERSION) { st_report("Found PSION magic word"); } else { st_fail_errno(ft,ST_EHDR,"Wrong version in Psion header"); return(ST_EOF); } st_readdw(ft, &(p->length)); st_readw(ft, (unsigned short *)&(p->padding)); st_readw(ft, (unsigned short *)&(p->repeats)); (void)st_readw(ft, (unsigned short *)&trash16); (void)st_readw(ft, (unsigned short *)&trash16); (void)st_readw(ft, (unsigned short *)&trash16); ft->info.encoding = ST_ENCODING_ALAW; ft->info.size = ST_SIZE_BYTE; if (ft->info.rate != 0) st_report("WVE must use 8000 sample rate. Overriding"); ft->info.rate = 8000; if (ft->info.channels != -1 && ft->info.channels != 1) st_report("WVE must only supports 1 channel. Overriding"); ft->info.channels = 1; p->dataStart = st_tell(ft); ft->length = p->length/ft->info.size; return (ST_SUCCESS); }