/CS/migrated/branches/R0_17/plugins/sound/loader/aifffile.cpp

# · C++ · 185 lines · 134 code · 28 blank · 23 comment · 27 complexity · 94a7605b4901f7c82db5cb72ae9f7a51 MD5 · raw file

  1. /*
  2. Copyright (C) 1998 by Jorrit Tyberghein
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Library General Public
  5. License as published by the Free Software Foundation; either
  6. version 2 of the License, or (at your option) any later version.
  7. This library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Library General Public License for more details.
  11. You should have received a copy of the GNU Library General Public
  12. License along with this library; if not, write to the Free
  13. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #include <math.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include "cssysdef.h"
  20. #include "csutil/csvector.h"
  21. #include "sndload.h"
  22. // MacIntosh AIFF file format loader
  23. // big warning, I hack this format with a hex editor,
  24. // if you have some informations about this format
  25. // email me at noote@bigfoot.com
  26. #define BIT8 0x0008
  27. #define BIT16 0x0010
  28. #define HZ11025 0x400C
  29. #define HZ22050 0x400D
  30. #define HZ44100 0x400E
  31. #define setStream(x) {if(x>size) {goto exit_read;} else {index=x;}}
  32. #define canAddStream(x) {if((index+x)>size) goto exit_read;}
  33. #define addStream(x) {if((index+x)>size) {goto exit_read;} else {index+=x;}}
  34. #define Stream buf[index]
  35. const char *csSoundLoader_AIFF::GetDesc() const {
  36. return "MacIntosh AIFF sound format";
  37. }
  38. iSoundData *csSoundLoader_AIFF::Load(UByte* buf, ULong size,
  39. const csSoundFormat *fmt) const {
  40. unsigned long index=0;
  41. csSoundDataWave *sb= NULL;
  42. char *data=NULL;
  43. unsigned char dummy0, dummy1, dummy2, dummy3;
  44. unsigned long flag = 0, flag2 = 0, nchannels = 0, length_form, samples_size = 0, max_freq;
  45. if(memcmp(&Stream, "FORM", 4))
  46. goto exit_read;
  47. addStream(4);
  48. dummy0 = Stream; addStream(1);
  49. dummy1 = Stream; addStream(1);
  50. dummy2 = Stream; addStream(1);
  51. dummy3 = Stream; addStream(1);
  52. length_form = csSndFunc::makeDWord(dummy0, dummy1, dummy2, dummy3)-4;
  53. if(length_form>size)
  54. goto exit_read;
  55. if(memcmp(&Stream, "AIFF", 4))
  56. goto exit_read;
  57. addStream(4);
  58. while(index<length_form)
  59. {
  60. char chunk[4];
  61. int chunk_size;
  62. memcpy(chunk, &Stream, 4);
  63. addStream(4);
  64. dummy0 = Stream; addStream(1);
  65. dummy1 = Stream; addStream(1);
  66. dummy2 = Stream; addStream(1);
  67. dummy3 = Stream; addStream(1);
  68. chunk_size = csSndFunc::makeDWord(dummy0, dummy1, dummy2, dummy3);
  69. if(memcmp(chunk, "COMM", 4)==0)
  70. {
  71. dummy0 = Stream; addStream(1);
  72. dummy1 = Stream; addStream(1);
  73. nchannels = csSndFunc::makeWord(dummy0, dummy1);
  74. if(nchannels !=1 && nchannels !=2)
  75. goto exit_read;
  76. dummy0 = Stream; addStream(1);
  77. dummy1 = Stream; addStream(1);
  78. dummy2 = Stream; addStream(1);
  79. dummy3 = Stream; addStream(1);
  80. samples_size = csSndFunc::makeDWord(dummy0, dummy1, dummy2, dummy3);
  81. if(samples_size>size)
  82. goto exit_read;
  83. dummy0 = Stream; addStream(1);
  84. dummy1 = Stream; addStream(1);
  85. flag = csSndFunc::makeWord(dummy0, dummy1);
  86. if(flag!=BIT8 && flag!=BIT16)
  87. goto exit_read;
  88. dummy0 = Stream; addStream(1);
  89. dummy1 = Stream; addStream(1);
  90. flag2 = csSndFunc::makeWord(dummy0, dummy1);
  91. if(flag2!=HZ11025 && flag2!=HZ22050 && flag2!=HZ44100)
  92. goto exit_read;
  93. dummy0 = Stream; addStream(1);
  94. dummy1 = Stream; addStream(1);
  95. // ?
  96. max_freq = csSndFunc::makeWord(dummy0, dummy1);
  97. addStream(chunk_size-12);
  98. }
  99. else if(memcmp(chunk, "SSND", 4)==0)
  100. {
  101. if(flag==BIT8)
  102. {
  103. int i=0;
  104. if((ULong)chunk_size>size)
  105. goto exit_read;
  106. data = new char[chunk_size];
  107. if(data==NULL) goto exit_read;
  108. char *ptr=(char *)data;
  109. while(i<chunk_size)
  110. {
  111. dummy0 = Stream; addStream(1);
  112. // datas are stored in unsigned 8 bit but mixer engine only support signed 8 bit
  113. *ptr++=dummy0-128;
  114. i++;
  115. }
  116. }
  117. else if(flag==BIT16)
  118. {
  119. int i=0;
  120. if((ULong)chunk_size>size)
  121. goto exit_read;
  122. data= new char[chunk_size];
  123. if(data==NULL) goto exit_read;
  124. unsigned short *ptr=(unsigned short *)data;
  125. int nbs = chunk_size/2;
  126. while(i<nbs)
  127. {
  128. dummy0 = Stream; addStream(1);
  129. dummy1 = Stream; addStream(1);
  130. *ptr++=csSndFunc::makeWord(dummy0, dummy1);
  131. i++;
  132. }
  133. }
  134. }
  135. else
  136. {
  137. canAddStream(chunk_size);
  138. addStream(chunk_size);
  139. }
  140. }
  141. if(data==NULL) goto exit_read;
  142. sb=new csSoundDataWave(NULL);
  143. sb->Initialize((flag2==HZ11025)?11025:(flag2==HZ22050)?22050:/*(flag2==HZ44100)*/44100,
  144. (flag==BIT16)?16:8,
  145. nchannels,
  146. (flag==BIT16)?samples_size/2:samples_size,
  147. (unsigned char*)data);
  148. sb->Prepare(fmt);
  149. goto exit_ok;
  150. exit_read:
  151. delete [] data;
  152. exit_ok:
  153. return sb;
  154. }