props.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * Copyright (c) 1983-2013 Martin Atkins, Richard Dobson and Composers Desktop Project Ltd
  3. * http://people.bath.ac.uk/masrwd
  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. /* props.cpp: adapted from speclib3.c
  22. * NB this is now real C++ code, not C!
  23. *
  24. */
  25. //LATEST VERSION OCT97: supercedes all previous!
  26. //can I make this fully portable to both graphic and console apps?
  27. //TODO: Feb 2014: replace sizeof(long) with sizeof(int) everywhere!
  28. #include "stdafx.h" //for MFC: def of BOOL, TRUE, FALSE, etc
  29. //#include <propobjs.h>
  30. //use multi-threaded version of sfsys.lib
  31. extern "C" {
  32. #include <sfsys.h>
  33. }
  34. #include "props.h"
  35. char *props_errstr = NULL;
  36. //RWD TODO: also need a copy constructor...
  37. /***************************** HEADREAD *******************************
  38. *
  39. * Read input analysis file header data.
  40. */
  41. BOOL sndheadread(int fd,SFPROPS &props)
  42. {
  43. int srate,chans,samptype,origsize = 0,origrate = 0, origchans = 0,dummy;
  44. float arate = (float)0.0;
  45. int wlen=0,dfac=0,specenvcnt = 0,checksum=0;
  46. props_errstr = NULL;
  47. if(fd <0){
  48. props_errstr = "Bad Soundfile Handle";
  49. return FALSE;
  50. }
  51. if(sndgetprop(fd,"sample rate", (char *)&srate, sizeof(int)) < 0) {
  52. props_errstr = "Failure to read sample rate";
  53. return FALSE;
  54. }
  55. if(sndgetprop(fd,"channels", (char *)&chans, sizeof(int)) < 0) {
  56. props_errstr ="Failure to read channel data";
  57. return FALSE;
  58. }
  59. if(sndgetprop(fd,"sample type", (char *)&samptype, sizeof(int)) < 0){
  60. props_errstr = "Failure to read sample size";
  61. return FALSE;
  62. }
  63. if(!(samptype==SAMP_SHORT || samptype== SAMP_FLOAT)){
  64. props_errstr = "unsupported sample type";
  65. return FALSE;
  66. }
  67. props.srate = srate;
  68. props.chans = chans;
  69. if(samptype == SAMP_SHORT || samptype== SAMP_FLOAT){
  70. props.type = wt_wave;
  71. props.samptype = (samptype == SAMP_SHORT ? SHORT16 : FLOAT32);
  72. }
  73. if(props.samptype==FLOAT32) {
  74. //we know we have floats: is it spectral file?
  75. if(sndgetprop(fd,"original sampsize",(char *)&origsize, sizeof(int))<0){
  76. props_errstr = "Failure to read original sample size";
  77. }
  78. if(sndgetprop(fd,"original sample rate",(char *)&origrate,sizeof(int))<0){
  79. props_errstr = "Failure to read original sample rate";
  80. }
  81. if(sndgetprop(fd,"arate",(char *)&arate,sizeof(float)) < 0){
  82. props_errstr = "Failure to read analysis sample rate";
  83. }
  84. if(sndgetprop(fd,"analwinlen",(char *)&wlen,sizeof(int)) < 0){
  85. props_errstr = "Failure to read analysis window length";
  86. }
  87. if(sndgetprop(fd,"decfactor",(char *)&dfac,sizeof(int)) < 0){
  88. props_errstr = "Failure to read decimation factor";
  89. }
  90. //TODO: find a way to guarantee unique checksums...
  91. checksum = origsize + origrate + wlen + dfac + (int)arate;
  92. if(checksum==0) //its a wave file
  93. return TRUE;
  94. else {
  95. if(props_errstr==NULL){ //its a good spectral file
  96. props.origsize = origsize;
  97. props.origrate = origrate;
  98. props.arate = arate;
  99. props.winlen = wlen;
  100. props.decfac = dfac;
  101. //props.chans = (wlen+2)/2; //??
  102. if(sndgetprop(fd,"is a pitch file", (char *)&dummy, sizeof(int))>=0)
  103. props.type = wt_pitch;
  104. else if(sndgetprop(fd,"is a transpos file", (char *)&dummy, sizeof(int))>=0)
  105. props.type = wt_transposition;
  106. else if(sndgetprop(fd,"is a formant file", (char *)&dummy, sizeof(int))>=0)
  107. props.type = wt_formant;
  108. else
  109. props.type = wt_analysis;
  110. } else
  111. return FALSE; //somehow, got a bad analysis file...
  112. }
  113. // get any auxiliary stuff for control file
  114. //adapted from TW's function in speclibg.cpp
  115. switch(props.type){
  116. case(wt_formant):
  117. if(sndgetprop(fd,"specenvcnt",(char *)&specenvcnt,sizeof(int)) < 0){
  118. props_errstr = "Failure to read formant size in formant file";
  119. return FALSE;
  120. }
  121. props.specenvcnt = specenvcnt;
  122. break;
  123. case(wt_pitch):
  124. case(wt_transposition):
  125. if(props.chans != 1){
  126. props_errstr = "Channel count not equal to 1 in transposition file";
  127. return FALSE;
  128. }
  129. if(sndgetprop(fd,"orig channels", (char *)&origchans, sizeof(int)) < 0) {
  130. props_errstr = "Failure to read original channel data from transposition file";
  131. return FALSE;
  132. }
  133. props.origchans = origchans;
  134. break;
  135. default:
  136. break;
  137. }
  138. }
  139. return TRUE;
  140. }
  141. #if 0
  142. // next is for SOUND files only...
  143. //TODO: full support for analysis and control files!
  144. BOOL sfwave_headwrite(int fd,const SFPROPS &props)
  145. {
  146. #ifdef _DEBUG
  147. ASSERT(fd >= 0);
  148. ASSERT(props.samptype==SHORT16 || props.samptype==FLOAT32);
  149. ASSERT(props.srate > 0);
  150. ASSERT(props.chans > 0);
  151. #endif
  152. int srate = props.srate;
  153. int chans = props.chans;
  154. int samptype;
  155. if(fd <0){
  156. props_errstr = "Cannot write soundfile: bad Handle";
  157. return FALSE;
  158. }
  159. if(props.type == wt_wave)
  160. samptype = (props.samptype == SHORT16 ? SAMP_SHORT : SAMP_FLOAT); //within sfsys,mostly safe assumption...
  161. else {
  162. props_errstr = "Not a wave file";
  163. return FALSE;
  164. }
  165. if(sfputprop(fd,"sample rate", (char *)&srate, sizeof(long)) < 0) {
  166. props_errstr = "Failure to write sample rate";
  167. return FALSE;
  168. }
  169. if(sfputprop(fd,"channels", (char *)&chans, sizeof(long)) < 0) {
  170. props_errstr ="Failure to write channel data";
  171. return FALSE;
  172. }
  173. if(sfputprop(fd,"sample type", (char *)&samptype, sizeof(long)) < 0){
  174. props_errstr = "Failure to write sample size";
  175. return FALSE;
  176. }
  177. return TRUE;
  178. }
  179. #endif
  180. fileprops::~fileprops()
  181. {
  182. }
  183. fileprops::fileprops()
  184. {
  185. srate = 0;
  186. stype = -1;
  187. filetype = UNKNOWN;
  188. channels = 0;
  189. origstype = -1;
  190. origrate = 0;
  191. origchans = 0;
  192. specenvcnt = 0;
  193. Mlen = 0;
  194. Dfac = 0;
  195. arate = 0.0f;
  196. }
  197. //TODO: when I have unique checksums, can just compare them
  198. const fileprops& fileprops::operator=(const fileprops &rhs)
  199. {
  200. if(!(rhs == *this)){ //use my operator==; TODO: define operator!= as well...
  201. srate = rhs.srate;
  202. channels = rhs.channels;
  203. stype = rhs.stype;
  204. origstype = rhs.origstype;
  205. origrate = rhs.origrate;
  206. Mlen = rhs.Mlen;
  207. Dfac = rhs.Dfac;
  208. arate = rhs.arate;
  209. origchans = rhs.origchans;
  210. specenvcnt = rhs.specenvcnt; //RWD: comes from?
  211. }
  212. return *this;
  213. }
  214. int fileprops::operator==(const fileprops &rhs) const
  215. {
  216. return (srate == rhs.srate
  217. && channels == rhs.channels
  218. && stype == rhs.stype
  219. && origstype == rhs.origstype
  220. && origrate == rhs.origrate
  221. && Mlen == rhs.Mlen
  222. && Dfac == rhs.Dfac
  223. && arate == rhs.arate
  224. && origchans == rhs.origchans
  225. && specenvcnt == rhs.specenvcnt);
  226. }