respec.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. /*
  2. * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <structures.h>
  25. #include <tkglobals.h>
  26. #include <pnames.h>
  27. #include <globcon.h>
  28. #include <cdpmain.h>
  29. #include <house.h>
  30. #include <modeno.h>
  31. #include <sfsys.h>
  32. #include <filetype.h>
  33. #include <srates.h>
  34. #include <flags.h>
  35. #ifdef unix
  36. #define round(x) lround((x))
  37. #endif
  38. static int create_convert_buffer(dataptr dz);
  39. static int create_reprop_buffer(dataptr dz);
  40. static int do_convert_process(dataptr dz);
  41. static int reprop_process(dataptr dz);
  42. static void strip_dir(char *str);
  43. static int create_cubic_spline_bufs(dataptr dz);
  44. static int cubic_spline(dataptr dz);
  45. /****************************** CREATE_RESPEC_BUFFERS ****************************/
  46. int create_respec_buffers(dataptr dz)
  47. {
  48. switch(dz->mode) {
  49. case(HOUSE_RESAMPLE): return create_cubic_spline_bufs(dz);
  50. case(HOUSE_CONVERT): return create_convert_buffer(dz);
  51. case(HOUSE_REPROP): return create_reprop_buffer(dz);
  52. }
  53. return(FINISHED);
  54. }
  55. /***************************** DO_RESPECIFICATION ******************************/
  56. int do_respecification(dataptr dz)
  57. {
  58. switch(dz->mode) {
  59. case(HOUSE_RESAMPLE): return cubic_spline(dz);
  60. case(HOUSE_CONVERT): return do_convert_process(dz);
  61. case(HOUSE_REPROP): return reprop_process(dz);
  62. }
  63. return(FINISHED);
  64. }
  65. /***************************** CREATE_CONVERT_BUFFER ******************************/
  66. int create_convert_buffer(dataptr dz)
  67. {
  68. int bigbufsize;
  69. int factor = (sizeof(short) + sizeof(float))/sizeof(short);
  70. bigbufsize = (int) (long)Malloc(-1);
  71. dz->buflen = bigbufsize/sizeof(float) / factor;
  72. if((dz->bigbuf = (float *)malloc((size_t)
  73. (dz->buflen * factor * sizeof(float))))==NULL) {
  74. sprintf(errstr,"Insufficient memory for sound.\n");
  75. return(MEMORY_ERROR);
  76. }
  77. dz->sampbuf[0] = dz->bigbuf;
  78. dz->flbufptr[0] = (float *)(dz->sampbuf[0] + dz->buflen);
  79. return(FINISHED);
  80. }
  81. /***************************** CREATE_REPROP_BUFFER ******************************/
  82. int create_reprop_buffer(dataptr dz)
  83. {
  84. size_t bigbufsize;
  85. bigbufsize = (size_t)Malloc(-1);
  86. dz->buflen = (int)(bigbufsize / sizeof(float));
  87. if((dz->bigbuf = (float *)malloc(dz->buflen* sizeof(float)))==NULL) {
  88. sprintf(errstr,"Insufficient memory for sound.\n");
  89. return(MEMORY_ERROR);
  90. }
  91. dz->sampbuf[0] = dz->bigbuf;
  92. return(FINISHED);
  93. }
  94. /************************** REPROP_PROCESS **************************/
  95. //RWD.1.99 modified to check that the iparams are active
  96. //RWD.1.99 modified to check that the iparams are active
  97. /*RWD Oct 2001: but does not support 24bit files, etc.... yet; need new cmdline flags for that */
  98. int reprop_process(dataptr dz)
  99. {
  100. int intype;
  101. SFPROPS props = {0};
  102. int exit_status;
  103. //TW modified: as infile->stype is now merely a flag for SOUND v NOT-SOUND DATA
  104. if(dz->infile->filetype != SNDFILE){
  105. sprintf(errstr,"This process only works with soundfiles.\n");
  106. return(DATA_ERROR);
  107. }
  108. if(!snd_headread(dz->ifd[0],&props)) {
  109. fprintf(stdout,"Failure to read sample type\n");
  110. fflush(stdout);
  111. return(DATA_ERROR);
  112. }
  113. switch(props.samptype) {
  114. case (2): /* FLOAT32 */ intype = SAMP_SHORT; break;
  115. case (1): /* SHORT16 */ intype = SAMP_FLOAT; break;
  116. default:
  117. sprintf(errstr,"This process only works with 16-bit or floating-point soundfiles.\n");
  118. return(DATA_ERROR);
  119. }
  120. if(dz->iparam[HSPEC_SRATE]==dz->infile->srate
  121. && dz->iparam[HSPEC_CHANS]==dz->infile->channels
  122. && dz->iparam[HSPEC_TYPE] == intype) {
  123. sprintf(errstr,"NO CHANGE to input file.\n");
  124. return(GOAL_FAILED);
  125. }
  126. /*RWD oct 2001: NB refuses 9-ch B-format files! */
  127. if((dz->iparam[HSPEC_CHANS] > 0) && (
  128. dz->iparam[HSPEC_CHANS] != 1
  129. && dz->iparam[HSPEC_CHANS] != 2
  130. && dz->iparam[HSPEC_CHANS] != 4
  131. && dz->iparam[HSPEC_CHANS] != 6
  132. && dz->iparam[HSPEC_CHANS] != 8
  133. && dz->iparam[HSPEC_CHANS] != 16
  134. )) {
  135. sprintf(errstr,"\nInvalid channel count [%d]",dz->iparam[HSPEC_CHANS]);
  136. return(DATA_ERROR);
  137. }
  138. if((dz->iparam[HSPEC_SRATE] > 0) && (!IS_LOSR(dz->iparam[HSPEC_SRATE]) && !IS_HISR(dz->iparam[HSPEC_SRATE]))) {
  139. sprintf(errstr,"\nInvalid sample rate [%d]",dz->iparam[HSPEC_SRATE]);
  140. return(DATA_ERROR);
  141. }
  142. if(dz->iparam[HSPEC_TYPE] >= SAMP_SHORT && (dz->iparam[HSPEC_TYPE]!=SAMP_SHORT
  143. && dz->iparam[HSPEC_TYPE]!=SAMP_FLOAT)) {
  144. sprintf(errstr,"\nInvalid sample type [%d]",dz->iparam[HSPEC_TYPE]);
  145. return(DATA_ERROR);
  146. }
  147. //RWD only update if the value is legal!
  148. if(dz->iparam[HSPEC_TYPE] >= SAMP_SHORT)
  149. dz->infile->stype = dz->iparam[HSPEC_TYPE];
  150. if(dz->iparam[HSPEC_SRATE] > 0)
  151. dz->infile->srate = dz->iparam[HSPEC_SRATE];
  152. if(dz->iparam[HSPEC_CHANS] > 0)
  153. dz->infile->channels = dz->iparam[HSPEC_CHANS];
  154. dz->ofd = sndcreat_formatted(dz->outfilename,-1,dz->infile->stype,dz->infile->channels,
  155. dz->infile->srate,CDP_CREATE_NORMAL);
  156. //TW ADDED : for peak chunk
  157. dz->outchans = dz->infile->channels;
  158. establish_peak_status(dz);
  159. //test!
  160. dz->outfilesize = 0;
  161. if(dz->ofd < 0) {
  162. sprintf(errstr,"Unable to open outfile %s\n",dz->outfilename);
  163. return SYSTEM_ERROR;
  164. }
  165. while(dz->samps_left) {
  166. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  167. return(exit_status);
  168. if(dz->ssampsread > 0) {
  169. if((exit_status = write_exact_samps(dz->sampbuf[0],dz->ssampsread,dz))<0)
  170. return(exit_status);
  171. }
  172. }
  173. return(FINISHED);
  174. }
  175. /************************** DO_CONVERT_PROCESS **************************/
  176. int do_convert_process(dataptr dz)
  177. {
  178. int exit_status;
  179. float *fbuf = dz->flbufptr[0];
  180. SFPROPS props = {0};
  181. int outtype; /*RWD*/
  182. //TW dz->infile->stype now merely flags whether we have a soundfile
  183. if(dz->infile->filetype != SNDFILE){
  184. sprintf(errstr,"This process only works with soundfiles.\n");
  185. return(DATA_ERROR);
  186. }
  187. if(!snd_headread(dz->ifd[0],&props)) {
  188. fprintf(stdout,"Failure to read sample type\n");
  189. fflush(stdout);
  190. return(DATA_ERROR);
  191. }
  192. switch(props.samptype) {
  193. case (2): /* FLOAT32 */ outtype = SAMP_SHORT; break;
  194. case (1): /* SHORT16 */ outtype = SAMP_FLOAT; break;
  195. default:
  196. sprintf(errstr,"This process only works with 16-bit or floating-point soundfiles.\n");
  197. return(DATA_ERROR);
  198. }
  199. dz->ofd = sndcreat_formatted(dz->outfilename,-1,
  200. outtype,dz->infile->channels,
  201. dz->infile->srate,CDP_CREATE_NORMAL);
  202. if(dz->ofd < 0) {
  203. sprintf(errstr,"Unable to open outfile %s\n",dz->outfilename);
  204. return SYSTEM_ERROR;
  205. }
  206. dz->outchans = dz->infile->channels;
  207. establish_peak_status(dz);
  208. dz->tempsize = dz->insams[0];
  209. while(dz->samps_left){
  210. if((exit_status = read_samps(fbuf,dz))<0)
  211. return(exit_status);
  212. if(dz->ssampsread) {
  213. if((exit_status = write_samps(fbuf,dz->ssampsread,dz)) < 0)
  214. return exit_status;
  215. }
  216. }
  217. return(FINISHED);
  218. }
  219. /********************** BATCH_EXPAND ****************************/
  220. int batch_expand(dataptr dz)
  221. {
  222. int total_wordcnt = 0;
  223. int n, m, k, linelen = dz->wordcnt[0];
  224. char temp[200], temp2[200], temp3[10];
  225. char **fname_wordstor = dz->wordstor + (dz->all_words - (dz->itemcnt * 2));
  226. char **param_wordstor = dz->wordstor + (dz->all_words - dz->itemcnt);
  227. int fq;
  228. if(dz->infilecnt - 1 <= 0) {
  229. sprintf(errstr,"No sound files entered.\n");
  230. return(DATA_ERROR);
  231. }
  232. switch(dz->mode) {
  233. case(ONE_PARAM):
  234. for(k = 0; k < dz->itemcnt; k++) {
  235. total_wordcnt = 0;
  236. for(n=0;n< dz->linecnt;n++) {
  237. for(m=0;m<linelen;m++) {
  238. if(m==0) {
  239. strcpy(temp,dz->wordstor[total_wordcnt]);
  240. } else if(total_wordcnt % linelen == dz->iparam[BE_INFILE]) {
  241. strcat(temp," ");
  242. strcat(temp,fname_wordstor[k]);
  243. } else if(total_wordcnt % linelen == dz->iparam[BE_OUTFILE]) {
  244. strcpy(temp3,"_b");
  245. sprintf(temp2,"%d",n);
  246. strcat(temp3,temp2);
  247. strcpy(temp2,fname_wordstor[k]);
  248. strip_dir(temp2);
  249. insert_new_chars_at_filename_end(temp2,temp3);
  250. strcat(temp," ");
  251. strcat(temp,temp2);
  252. if((fq = sndopenEx(temp,0,CDP_OPEN_RDONLY)) >= 0) {
  253. sndcloseEx(fq);
  254. fq = -1;
  255. sprintf(errstr,"File %s already exists: cannot use as outname in batchfile\n",temp);
  256. return(DATA_ERROR);
  257. }
  258. } else if(total_wordcnt % linelen == dz->iparam[BE_PARAM]) {
  259. strcat(temp," ");
  260. strcat(temp,param_wordstor[k]);
  261. } else {
  262. strcat(temp," ");
  263. strcat(temp,dz->wordstor[total_wordcnt]);
  264. }
  265. total_wordcnt++;
  266. }
  267. strcat(temp,"\n");
  268. if(fputs(temp,dz->fp)<0) {
  269. sprintf(errstr,"Failed to copy of original batchfile line %d to output file.\n",n+1);
  270. return(SYSTEM_ERROR);
  271. }
  272. }
  273. }
  274. break;
  275. case(MANY_PARAMS):
  276. total_wordcnt = 0;
  277. for(n=0,k=0;n< dz->linecnt;n++,k++) {
  278. if (k >= dz->itemcnt)
  279. break;
  280. for(m=0;m<linelen;m++) {
  281. if(m==0) {
  282. /*sprintf*/strcpy(temp,dz->wordstor[total_wordcnt]); // RWD 07 2010 see above
  283. } else if(total_wordcnt % linelen == dz->iparam[BE_INFILE]) {
  284. strcat(temp," ");
  285. strcat(temp,fname_wordstor[k]);
  286. } else if(total_wordcnt % linelen == dz->iparam[BE_OUTFILE]) {
  287. strcpy(temp2,fname_wordstor[k]);
  288. insert_new_chars_at_filename_end(temp2,"_b");
  289. strcat(temp," ");
  290. strcat(temp,temp2);
  291. if((fq = sndopenEx(temp,0,CDP_OPEN_RDONLY)) >= 0) {
  292. sndcloseEx(fq);
  293. fq = -1;
  294. sprintf(errstr,"File %s already exists: cannot use as outname in batchfile\n",temp);
  295. return(DATA_ERROR);
  296. }
  297. } else if(total_wordcnt % linelen == dz->iparam[BE_PARAM]) {
  298. strcat(temp," ");
  299. strcat(temp,param_wordstor[k]);
  300. } else {
  301. strcat(temp," ");
  302. strcat(temp,dz->wordstor[total_wordcnt]);
  303. }
  304. total_wordcnt++;
  305. }
  306. strcat(temp,"\n");
  307. if(fputs(temp,dz->fp)<0) {
  308. sprintf(errstr,"Failed to print new batchfile line %d to output file.\n",n+1);
  309. return(SYSTEM_ERROR);
  310. }
  311. }
  312. break;
  313. }
  314. return FINISHED;
  315. }
  316. /********************** STRIP_DIR ****************************/
  317. void strip_dir(char *str)
  318. {
  319. char *p, *q, *r = str;
  320. q = str + strlen(str);
  321. p = q - 1;
  322. while(p > str) {
  323. if(*p == '/') {
  324. p++;
  325. while(p <= q)
  326. *r++ = *p++;
  327. return;
  328. }
  329. p--;
  330. }
  331. }
  332. /********************** CREATE_CUBIC_SPLINE_BUFS ****************************/
  333. int create_cubic_spline_bufs(dataptr dz)
  334. {
  335. int dblratio = sizeof(double)/sizeof(float);
  336. int dbl_buflen;
  337. int k, chans = dz->infile->channels;
  338. int dbl_chans = chans * dblratio;
  339. size_t bigbuf_bigsize, bigbufsize;
  340. int fsecsize = SECSIZE/sizeof(float);
  341. int framesize = fsecsize * dz->infile->channels;
  342. bigbuf_bigsize = ((size_t) Malloc(-1))/sizeof(float);
  343. bigbufsize = (bigbuf_bigsize/framesize) * framesize;
  344. if(bigbufsize <= 0)
  345. bigbufsize = framesize;
  346. k = (3 * dblratio) + 2;
  347. bigbuf_bigsize = bigbufsize * k;
  348. bigbuf_bigsize += fsecsize;
  349. bigbuf_bigsize += (chans * dblratio * 3);
  350. if((dz->bigbuf = (float *)malloc((size_t)(bigbuf_bigsize * sizeof(float)))) == NULL) {
  351. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  352. return(MEMORY_ERROR);
  353. }
  354. memset((char *)dz->bigbuf,0,bigbuf_bigsize * sizeof(float));
  355. /* NB: wraparound points for both samples and derivatives are thus zeroed */
  356. dz->buflen = (int) bigbufsize;
  357. dbl_buflen = dz->buflen * dblratio;
  358. /* sampbuf[0] has chans samps store at start to read wraparound points */
  359. dz->sampbuf[0] = dz->bigbuf + fsecsize;
  360. dz->sampbuf[1] = dz->sampbuf[0] + dz->buflen;
  361. /* sampbufs[2][3][4] have additional chans samps store at start,and are doubles buffers */
  362. dz->sampbuf[2] = dz->sampbuf[1] + dz->buflen + dbl_chans;
  363. dz->sampbuf[3] = dz->sampbuf[2] + dbl_buflen + dbl_chans;
  364. dz->sampbuf[4] = dz->sampbuf[3] + dbl_buflen + dbl_chans;
  365. return(FINISHED);
  366. }
  367. /********************** CUBIC_SPLINE ****************************/
  368. int cubic_spline(dataptr dz)
  369. {
  370. int exit_status;
  371. int chans = dz->infile->channels;
  372. int fsecsize = SECSIZE/sizeof(float);
  373. /* Input and Output and Derivatives buffers */
  374. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
  375. double *y2 = (double *)dz->sampbuf[2];
  376. double *u = (double *)dz->sampbuf[3];
  377. double *y3 = (double *)dz->sampbuf[4];
  378. /* constants used in calculation */
  379. double incr = (double)dz->infile->srate/(double)dz->iparam[HSPEC_SRATE];
  380. double sig = 0.5;
  381. double sig_less_one = sig - 1.0;
  382. /* flags used in calculation */
  383. int all_read = 0, start = 1;
  384. /* other variables */
  385. double d = 0.0, p;
  386. int n,m,k,obufcnt = 0, samps_to_process;
  387. double kk, hi, lo, hidif, lodif, x1, x2, x3, x4;
  388. int lochan, hichan;
  389. double samp;
  390. int inlo, inhi;
  391. dz->tempsize = round((double)dz->insams[0]/incr);
  392. /* setup wraparound pointers */
  393. //create outfile here, now we have required format info
  394. if((dz->ofd = sndcreat_formatted(dz->outfilename,-1,dz->infile->stype,dz->infile->channels,
  395. /*dz->infile->srate*/
  396. dz->iparam[HSPEC_SRATE],
  397. CDP_CREATE_NORMAL)) < 0) {
  398. sprintf(errstr,"Unable to open outfile %s\n",dz->outfilename);
  399. return SYSTEM_ERROR;
  400. }
  401. dz->outchans = dz->infile->channels;
  402. establish_peak_status(dz);
  403. k = dz->buflen - fsecsize - chans;
  404. dz->sbufptr[0] = dz->sampbuf[0] - chans;
  405. dz->sbufptr[1] = dz->sampbuf[0] + k;
  406. dz->ptr[0] = y2 - chans;
  407. dz->ptr[1] = y2 + k;
  408. dz->ptr[2] = u - chans;
  409. dz->ptr[3] = u + k;
  410. dz->ptr[4] = y3 - chans;
  411. dz->ptr[5] = y3 + k;
  412. while(dz->samps_left > 0) {
  413. /* Read samps, leaving overlapping samps at end of buffer to do wraparound calculations */
  414. if((exit_status = read_samps(ibuf,dz))<0)
  415. return(exit_status);
  416. if(dz->total_samps_read < dz->insams[0]) {
  417. // APRIL 2005
  418. // sfseek(dz->ifd[0],(dz->total_samps_read - fsecsize) * sizeof(float),0);
  419. sndseekEx(dz->ifd[0],dz->total_samps_read - fsecsize,0);
  420. samps_to_process = dz->ssampsread - fsecsize;
  421. dz->total_samps_read -= fsecsize;
  422. dz->samps_left += fsecsize;
  423. } else {
  424. all_read = 1;
  425. k = dz->ssampsread;
  426. /* if at end of data, add buffering zeros after end */
  427. for(n=0;n<chans;n++) {
  428. dz->sampbuf[0][k] = 0.0f;
  429. k++;
  430. }
  431. samps_to_process = dz->ssampsread;
  432. }
  433. /* CALCULATE 2nd DERIVATIVE : STAGE 1 */
  434. for(n=0;n<samps_to_process;n+= chans) {
  435. for(m = 0;m <chans; m++) {
  436. k = n + m;
  437. p = sig * y2[k-chans] + 2.0;
  438. y2[k] = sig_less_one/p;
  439. // u[k] = (ibuf[k+chans] - ibuf[k]) - (ibuf[k] - ibuf[k-chans]);
  440. u[k] = (round(32767 * ibuf[k+chans]) - round(32767 * ibuf[k])) - (round(32767 * ibuf[k]) - round(32767 * ibuf[k-chans]));
  441. x1 = (6.0 * u[k])/2.0;
  442. x2 = sig * u[k-chans];
  443. u[k] = (x1 - x2)/p;
  444. }
  445. }
  446. if(all_read) { /* add "natural spline" end vals of 2nd derivative */
  447. for(m = 0;m <chans; m++)
  448. y2[n+m] = 0.0;
  449. }
  450. /* CALCULATE 2nd DERIVATIVE : STAGE 2 */
  451. for(n = samps_to_process-chans;n >= 0;n -= chans) {
  452. for(m = 0;m <chans; m++) {
  453. k = n + m;
  454. y3[k] = (y2[k] * y2[k+chans]) + u[k];
  455. }
  456. }
  457. /* DO SPLINE */
  458. k = samps_to_process/chans;
  459. kk = (double)k;
  460. if(start) {
  461. for(m=0;m<chans;m++)
  462. obuf[m] = ibuf[m];
  463. obufcnt = chans;
  464. start = 0;
  465. }
  466. for(;;) {
  467. d += incr; /* Advance re-read pointer in buffer */
  468. if(d >= kk) {
  469. d -= incr;
  470. d -= kk; /* if at end of input buffer, reset pointer, and break */
  471. break;
  472. }
  473. lo = floor(d); /* find buffer indices of samples above and below pointer */
  474. hi = lo + 1.0;
  475. hidif = hi - d;
  476. lodif = d - lo;
  477. lochan = (int)lo * chans;
  478. hichan = (int)hi * chans;
  479. for(m=0;m<chans;m++) {
  480. n = obufcnt + m;
  481. inlo = lochan + m;
  482. inhi = hichan + m;
  483. /* DO SPLINE */
  484. // x1 = (hidif * ibuf[inlo]) + (lodif * ibuf[inhi]);
  485. x1 = (hidif * round(32767 * ibuf[inlo])) + (lodif * round(32767 * ibuf[inhi]));
  486. x2 = ((hidif * hidif * hidif) - hidif) * y3[inlo];
  487. x3 = ((lodif * lodif * lodif) - lodif) * y3[inhi];
  488. x4 = (x2 + x3)/6.0;
  489. // samp = x1 + x4;
  490. samp = ((int)round(x1 + x4)/32767.0);
  491. if(samp > 1.0)
  492. samp = 1.0;
  493. if(samp < -1.0)
  494. samp = -1.0;
  495. obuf[n] = (float)samp;
  496. }
  497. obufcnt += chans;
  498. if(obufcnt >= dz->buflen) {
  499. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  500. return(exit_status);
  501. obufcnt = 0;
  502. }
  503. }
  504. if(!all_read) { /* do wrap-around points for input & derivatives */
  505. memcpy((char *)dz->sbufptr[0],(char *)dz->sbufptr[1],chans * sizeof(float));
  506. memcpy((char *)dz->ptr[0],(char *)dz->ptr[1],chans * sizeof(double));
  507. memcpy((char *)dz->ptr[2],(char *)dz->ptr[3],chans * sizeof(double));
  508. memcpy((char *)dz->ptr[4],(char *)dz->ptr[5],chans * sizeof(double));
  509. }
  510. }
  511. if(obufcnt > 0) {
  512. if((exit_status = write_samps(obuf,obufcnt,dz))<0)
  513. return(exit_status);
  514. }
  515. return FINISHED;
  516. }