/CS/migrated/branches/R0_94/plugins/sound/loader/au/aufile.cpp

# · C++ · 194 lines · 144 code · 28 blank · 22 comment · 20 complexity · e79b4d705aedad9cf83c3d6277d3768f 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 "isound/loader.h"
  21. #include "iutil/eventh.h"
  22. #include "iutil/comp.h"
  23. #include "../common/soundraw.h"
  24. #include "../common/sndload.h"
  25. CS_IMPLEMENT_PLUGIN
  26. // Sun AU file loader
  27. // support 8 and 16 bits PCM
  28. // and 8 bit ULAW (no compressed)
  29. class csSoundLoader_AU : public iSoundLoader
  30. {
  31. public:
  32. SCF_DECLARE_IBASE;
  33. struct eiComponent : public iComponent
  34. {
  35. SCF_DECLARE_EMBEDDED_IBASE(csSoundLoader_AU);
  36. virtual bool Initialize (iObjectRegistry*) { return true; }
  37. } scfiComponent;
  38. csSoundLoader_AU(iBase *p)
  39. {
  40. SCF_CONSTRUCT_IBASE(p);
  41. SCF_CONSTRUCT_EMBEDDED_IBASE(scfiComponent);
  42. }
  43. virtual iSoundData *LoadSound(void *Buffer, unsigned long Size) const;
  44. };
  45. SCF_IMPLEMENT_IBASE(csSoundLoader_AU)
  46. SCF_IMPLEMENTS_INTERFACE(iSoundLoader)
  47. SCF_IMPLEMENTS_EMBEDDED_INTERFACE(iComponent)
  48. SCF_IMPLEMENT_IBASE_END;
  49. SCF_IMPLEMENT_EMBEDDED_IBASE (csSoundLoader_AU::eiComponent)
  50. SCF_IMPLEMENTS_INTERFACE (iComponent)
  51. SCF_IMPLEMENT_EMBEDDED_IBASE_END
  52. SCF_IMPLEMENT_FACTORY(csSoundLoader_AU);
  53. SCF_EXPORT_CLASS_TABLE (sndau)
  54. SCF_EXPORT_CLASS (csSoundLoader_AU,
  55. "crystalspace.sound.loader.au", "AU Sound Loader")
  56. SCF_EXPORT_CLASS_TABLE_END;
  57. #define BIT16 0x03
  58. #define BIT8 0x02
  59. #define BIT8ULAW 0x01
  60. #define setStream(x) {if(x>size) {goto exit_read;} else {index=x;}}
  61. #define canAddStream(x) {if((index+x)>size) goto exit_read;}
  62. #define addStream(x) {if((index+x)>size) {goto exit_read;} else {index+=x;}}
  63. #define Stream buf[index]
  64. iSoundData *csSoundLoader_AU::LoadSound(void *databuf, uint32 size) const
  65. {
  66. uint8 *buf = (uint8*) databuf;
  67. unsigned long index=0;
  68. csSoundDataRaw *sb= NULL;
  69. char *data=NULL;
  70. unsigned char dummy0, dummy1, dummy2, dummy3;
  71. unsigned long offset, nbytes, flag, freq, nchannels;
  72. if(memcmp(&Stream, ".snd", 4))
  73. goto exit_read;
  74. addStream(4);
  75. dummy0 = Stream; addStream(1);
  76. dummy1 = Stream; addStream(1);
  77. dummy2 = Stream; addStream(1);
  78. dummy3 = Stream; addStream(1);
  79. offset = csSndFunc::makeDWord(dummy0, dummy1, dummy2, dummy3);
  80. dummy0 = Stream; addStream(1);
  81. dummy1 = Stream; addStream(1);
  82. dummy2 = Stream; addStream(1);
  83. dummy3 = Stream; addStream(1);
  84. nbytes = csSndFunc::makeDWord(dummy0, dummy1, dummy2, dummy3);
  85. dummy0 = Stream; addStream(1);
  86. dummy1 = Stream; addStream(1);
  87. dummy2 = Stream; addStream(1);
  88. dummy3 = Stream; addStream(1);
  89. flag = csSndFunc::makeDWord(dummy0, dummy1, dummy2, dummy3);
  90. if(flag!=BIT16 && flag!=BIT8 && flag!=BIT8ULAW)
  91. goto exit_read;
  92. dummy0 = Stream; addStream(1);
  93. dummy1 = Stream; addStream(1);
  94. dummy2 = Stream; addStream(1);
  95. dummy3 = Stream; addStream(1);
  96. freq = csSndFunc::makeDWord(dummy0, dummy1, dummy2, dummy3);
  97. dummy0 = Stream; addStream(1);
  98. dummy1 = Stream; addStream(1);
  99. dummy2 = Stream; addStream(1);
  100. dummy3 = Stream; addStream(1);
  101. nchannels = csSndFunc::makeDWord(dummy0, dummy1, dummy2, dummy3);
  102. if(nchannels>2 || nchannels<1)
  103. goto exit_read;
  104. canAddStream(nbytes);
  105. if(flag==BIT8)
  106. {
  107. data=new char[nbytes];
  108. if (data==NULL)
  109. goto exit_read;
  110. unsigned long i=0;
  111. char *ptr=(char *)data;
  112. while(i<nbytes)
  113. {
  114. dummy0 = Stream; addStream(1);
  115. // datas are stored in unsigned 8 bit but mixer engine only support
  116. // signed 8 bit
  117. *ptr++=dummy0-128;
  118. i++;
  119. }
  120. }
  121. else if(flag==BIT16)
  122. {
  123. data=new char[nbytes];
  124. if(data==NULL)
  125. goto exit_read;
  126. int i=0;
  127. int nbs = nbytes/2;
  128. unsigned short *ptr=(unsigned short *)data;
  129. while(i<nbs)
  130. {
  131. dummy0 = Stream; addStream(1);
  132. dummy1 = Stream; addStream(1);
  133. *ptr++=csSndFunc::makeWord(dummy0, dummy1);
  134. i++;
  135. }
  136. }
  137. else if(flag==BIT8ULAW)
  138. {
  139. data=new char[nbytes*2];
  140. if(data==NULL)
  141. goto exit_read;
  142. int i=0;
  143. int nbs = nbytes;
  144. unsigned short *ptr=(unsigned short *)data;
  145. while(i<nbs)
  146. {
  147. dummy0 = Stream; addStream(1);
  148. *ptr++=csSndFunc::ulaw2linear(dummy0);
  149. i++;
  150. }
  151. }
  152. csSoundFormat Format;
  153. Format.Freq=freq;
  154. Format.Bits=(flag==BIT16 || flag==BIT8ULAW)?16:8;
  155. Format.Channels=nchannels;
  156. sb=new csSoundDataRaw(NULL, data,
  157. (flag==BIT16)?(nbytes/2)-1:nbytes-1, Format);
  158. goto exit_ok;
  159. exit_read:
  160. delete [] data;
  161. exit_ok:
  162. return sb;
  163. }