abfdcode.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Copyright (c) 1983-2013 Richard Dobson and Composers Desktop Project Ltd
  3. * http://people.bath.ac.uk/masrwd
  4. * http://www.composersdesktop.com
  5. * This file is part of the CDP System.
  6. * The CDP System is free software; you can redistribute it
  7. * and/or modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  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.
  14. * See the 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 02111-1307 USA
  18. *
  19. */
  20. //abfdcode.cpp : write mono wave file into ambisonic B-format
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <math.h>
  25. #include "portsf.h"
  26. #ifdef unix
  27. /* in portsf.lib */
  28. extern "C" {
  29. int stricmp(const char *a, const char *b);
  30. }
  31. #endif
  32. typedef struct abf_samp {
  33. float W;
  34. float X;
  35. float Y;
  36. float Z;
  37. } ABFSAMPLE;
  38. int main(int argc,char *argv[])
  39. {
  40. int i,ifd, ofd;
  41. long outchans = 4;
  42. long outsize;
  43. char *sfname;
  44. bool write_wavex = false;
  45. ABFSAMPLE abfsample;
  46. float frame[4];
  47. PSF_PROPS props;
  48. PSF_CHPEAK peaks[4];
  49. long inchans;
  50. MYLONG peaktime;
  51. /* CDP version number */
  52. if(argc==2 && (stricmp(argv[1],"--version")==0)){
  53. printf("1.2.1\n");
  54. return 0;
  55. }
  56. if(argc < 3){
  57. printf("\nCDP MCTOOLS: ABFDCODE v 1.2.1: CDP 1999,2004,2005\n"
  58. "Horizontal B Format Decoder\n"
  59. "usage: abfdcode [-x] infile outfile\n"
  60. " -x : write WAVE_EX (Quad) outfile format\n"
  61. " (requires .wav extension)\n"
  62. "NB: infile must have 3 or 4 channels\n"
  63. "UPDATE 2009: This program is now replaced by FMDCODE, \n"
  64. "and may be omitted in future updates to the Toolkit.\n"
  65. "For this task use fmdcode with e.g. layout 4.\n"
  66. );
  67. return 1;
  68. }
  69. while(argv[1][0] =='-'){
  70. switch(argv[1][1]){
  71. case('x'):
  72. write_wavex = true;
  73. break;
  74. default:
  75. fprintf(stderr,"abfdecode: error: illegal flag option %s\n",argv[1]);
  76. return 1;
  77. }
  78. argc--; argv++;
  79. }
  80. if(argc < 3){
  81. fprintf(stderr,"CDP MCTOOLS: ABFDCODE.EXE: CDP 1999,2005\nHorizontal B Format Decoder\nusage: abfdcode [-x] infile outfile\n");
  82. return 1;
  83. }
  84. if(psf_init()){
  85. fprintf(stderr,"abfdcode: startup failure.\n");
  86. return 1;
  87. }
  88. sfname = argv[2];
  89. ifd = psf_sndOpen(argv[1],&props,0);
  90. if(ifd < 0){
  91. fprintf(stderr,"unable toopen infile %s\n",argv[1]);
  92. return 1;
  93. }
  94. inchans = props.chans;
  95. if(!(inchans == 3 || inchans == 4)){
  96. fprintf(stderr,"Sorry: infile is not first-order\n");
  97. psf_sndClose(ifd);
  98. return 1;
  99. }
  100. outsize = psf_sndSize(ifd);
  101. if(outsize <= 0){
  102. fprintf(stderr,"infile is empty!\n");
  103. psf_sndClose(ifd);
  104. return 1;
  105. }
  106. props.chformat = STDWAVE;
  107. props.chans = 4;
  108. if(!is_legalsize(outsize,&props)){
  109. fprintf(stderr,"error: outfile size exceeds capacity of format.\n");
  110. return 1;
  111. }
  112. if(write_wavex){
  113. props.chformat = MC_QUAD;
  114. props.format = PSF_WAVE_EX;
  115. }
  116. //ofd = sndcreat_formatted(sfname,outsize * outchans,stype,outchans,srate,CDP_CREATE_NORMAL);
  117. ofd = psf_sndCreate(sfname,&props,0,0,PSF_CREATE_RDWR);
  118. if(ofd < 0){
  119. fprintf(stderr,"can't create outfile %s.\n",sfname);
  120. psf_sndClose(ifd);
  121. return 1;
  122. }
  123. int got, halfsec = props.srate / 2;
  124. unsigned int framepos = 0;
  125. printf("\ndoing b-format decoding:\n");
  126. while((got = psf_sndReadFloatFrames(ifd,(float *) &abfsample,1))==1){
  127. //this_samp = 0.5 * p_iosc->tick(1000);
  128. float aw = abfsample.W;
  129. float ax = abfsample.X * 0.707f;
  130. float ay = abfsample.Y * 0.707f;
  131. frame[0] = 0.3333f * (aw + ax + ay);
  132. frame[1] = 0.3333f * (aw + ax - ay);
  133. frame[2] = 0.3333f * (aw - ax + ay);
  134. frame[3] = 0.3333f * (aw - ax - ay);
  135. if(0 > psf_sndWriteFloatFrames(ofd,frame,1)){
  136. fprintf(stderr,"error writing sample block %ld\n",got * outchans);
  137. psf_sndClose(ifd);
  138. psf_sndClose(ofd);
  139. return 1;
  140. }
  141. if(framepos % halfsec==0) {
  142. printf("%.2lf secs\r",(double)framepos / (double) props.srate);
  143. fflush(stdout);
  144. }
  145. framepos++;
  146. }
  147. if(got != 0){
  148. fprintf(stderr,"warning: not all data was read\n");
  149. }
  150. printf("\n%.4lf secs\nWritten %d quad frames to %s\n",(double)framepos / (double) props.srate,framepos,sfname);
  151. if(psf_sndReadPeaks( ofd,peaks,&peaktime)){
  152. printf("PEAK values:\n");
  153. for(i=0; i < outchans; i++){
  154. double val, dbval;
  155. val = (double) peaks[i].val;
  156. if(val > 0.0){
  157. dbval = 20.0 * log10(val);
  158. printf("CH %d: %.6f (%.2lfdB) at frame %u:\t%.4f secs\n",i,
  159. val,dbval,(unsigned int) peaks[i].pos,(double)peaks[i].pos / (double) props.srate);
  160. }
  161. else{
  162. printf("CH %d: %.6f (-infdB) at frame %u:\t%.4f secs\n",i,
  163. val,(unsigned int) peaks[i].pos,(double)peaks[i].pos / (double) props.srate);
  164. }
  165. }
  166. }
  167. psf_sndClose(ifd);
  168. psf_sndClose(ofd);
  169. psf_finish();
  170. return 0;
  171. }