freeaudio.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. // freeaudio.h
  2. // version 0.3
  3. // freeware cross platform audio engine sponsored by Blitz Research Ltd
  4. #ifndef freeaudio_h
  5. #define freeaudio_h
  6. extern "C" int bbMilliSecs();
  7. typedef int (*ReadFunc)(void*,int);
  8. #if _MSC_VER
  9. typedef __int64 i64;
  10. #else
  11. typedef long long i64;
  12. #endif
  13. typedef unsigned char u8;
  14. typedef unsigned short u16;
  15. typedef unsigned int u32;
  16. #define MAXCHANNELS 4096
  17. #define VOLUMEONE 4096
  18. #define BBCALL
  19. #define ABS(a) (((a)>0)?(a):-(a))
  20. #define MAX(a,b) (((a)>(b))?(a):(b))
  21. #define MIN(a,b) (((a)<(b))?(a):(b))
  22. #define BND(a,b,c) MIN(MAX((a),(b)),(c))
  23. struct control
  24. {
  25. int current,target;
  26. };
  27. struct output
  28. {
  29. enum outputstates{FREE=0,STOPPED=1,SINGLESHOT=2,LOOPING=4,STREAMING=8,PAUSED=16};
  30. output *parent;
  31. int status,channel,recycle;
  32. virtual void setrate(int r) {}
  33. virtual void setvolume(short v) {}
  34. virtual void setpan(short p) {}
  35. virtual void setdepth(short d) {}
  36. virtual int getrate(int t) {return 65536;} //(status&PAUSED)?0:4096;}
  37. virtual short getvolume(int t) {return 4096;}
  38. virtual short getpan(int t) {return 0;}
  39. virtual short getdepth(int t) {return 0;}
  40. virtual int getposition() {return 0;}
  41. output(output *p) {
  42. parent=p;
  43. status=FREE;
  44. channel=0;
  45. recycle=0;
  46. }
  47. void stop(int user) {
  48. if (user) recycle=1;
  49. if (status!=FREE) status=STOPPED;
  50. }
  51. void setpause(int pause)
  52. {
  53. if (pause)
  54. {
  55. status|=PAUSED;
  56. }
  57. else
  58. {
  59. status&=~PAUSED;
  60. }
  61. }
  62. void setloop(int loop)
  63. {
  64. if (loop)
  65. {
  66. if (status&SINGLESHOT) status=(status&~SINGLESHOT)|LOOPING;
  67. }
  68. else
  69. {
  70. if (status&LOOPING) status=(status&~LOOPING)|SINGLESHOT;
  71. }
  72. }
  73. };
  74. struct sample
  75. {
  76. int freq,channels,bits;
  77. int loop0,loop1;
  78. int samples,samplesize,sizebytes;
  79. int writepos;
  80. int refcount;
  81. int loop;
  82. void *data,*buffer;
  83. int capacity;
  84. sample() {freq=channels=bits=0;loop=0;capacity=0;}
  85. int init(int length,int freq,int channels,int bits,void *data); //data=0 mallocs length in samples
  86. void free();
  87. int buffersize(int readpos);
  88. void write(int n);
  89. int write(void *mem,int bytes,int readpos=0);
  90. int peek(int t);
  91. void setloop(int flag);
  92. };
  93. struct sound:output
  94. {
  95. sound *next;
  96. sample *samp;
  97. i64 pos64;
  98. i64 mix64;
  99. int currentrate,targetrate;
  100. short currentvolume,targetvolume;
  101. short currentpan,targetpan;
  102. short currentdepth,targetdepth;
  103. int starttime,delay;
  104. virtual int getrate(int t) {return t?targetrate:currentrate;}
  105. virtual short getvolume(int t) {return t?targetvolume:currentvolume;}
  106. virtual short getpan(int t) {return t?targetpan:currentpan;}
  107. virtual short getdepth(int t) {return t?targetdepth:currentdepth;}
  108. virtual int getposition() {return (mix64>>32)/samp->channels;}
  109. virtual void setrate(int r) {targetrate=r;if (status&PAUSED) currentrate=r;}
  110. virtual void setvolume(short v) {targetvolume=v;if (status&PAUSED) currentvolume=v;}
  111. virtual void setpan(short p) {targetpan=p;if (status&PAUSED) currentpan=p;}
  112. virtual void setdepth(short d) {targetdepth=d;if (status&PAUSED) targetdepth=d;}
  113. void resetrate(int r) {currentrate=targetrate=r;}
  114. void resetvolume(short v) {currentvolume=targetvolume=v;}
  115. void resetpan(short p) {currentpan=targetpan=p;}
  116. void resetdepth(short d) {currentdepth=targetdepth=d;}
  117. // private
  118. sound(output *p);
  119. void flush();
  120. int mix(int *b,int size); //return 0 to remove from playlist
  121. };
  122. struct queue
  123. {
  124. int head,tail;
  125. sound *que[MAXCHANNELS];
  126. queue() {head=tail=0;}
  127. void push(sound *s)
  128. {
  129. que[tail++]=s;
  130. if (tail>=MAXCHANNELS) tail=0;
  131. }
  132. sound *pull()
  133. {
  134. sound *snd=0;
  135. if (head!=tail)
  136. {
  137. snd=que[head++];
  138. if (head>=MAXCHANNELS) head=0;
  139. }
  140. return snd;
  141. }
  142. };
  143. struct mixer:output
  144. {
  145. int *mbuff,size;
  146. int freq,channels;
  147. sound *playlist;
  148. queue startlist;
  149. queue freelist; //multi threading friendly
  150. mixer(int size);
  151. sound *allocsound(output *out);
  152. sound *play(sample *s,output *out,int state);
  153. void releasesound(sound *s);
  154. void releaseall();
  155. void mix8(u8 *abuff,int count=0);
  156. void mix16(short *abuff,int count=0);
  157. void mix16s(short *abuff,int count=0);
  158. void mix(int count);
  159. };
  160. // freeaudio device
  161. struct audiodevice
  162. {
  163. mixer *mix;
  164. // virtual OS dependent interface
  165. virtual int reset()=0;
  166. virtual int close()=0;
  167. audiodevice()
  168. {
  169. mix=0;
  170. }
  171. sound *play(sample *sam,output *out,int paused)
  172. {
  173. sound *snd;
  174. int freq,vol,state;
  175. if (mix==0) return 0;
  176. state=sound::SINGLESHOT;
  177. if (sam->loop) state=sound::LOOPING;
  178. if (paused) state|=sound::PAUSED; //freq=0;
  179. snd=mix->play(sam,out,state);
  180. return snd;
  181. }
  182. };
  183. // freeaudio standard C interface
  184. static audiodevice *audio=0;
  185. struct systemio
  186. {
  187. output **channels;
  188. int *freelist;
  189. int *cyclelist;
  190. systemio()
  191. {
  192. channels=new output*[MAXCHANNELS];
  193. freelist=new int[MAXCHANNELS];
  194. cyclelist=new int[MAXCHANNELS];
  195. for (int i=0;i<MAXCHANNELS;i++)
  196. {
  197. channels[i]=0;
  198. freelist[i]=i+1;
  199. cyclelist[i]=MAXCHANNELS;
  200. }
  201. freelist[MAXCHANNELS-1]=0;
  202. }
  203. ~systemio()
  204. {
  205. delete channels;
  206. delete freelist;
  207. }
  208. int allocchannel()
  209. {
  210. int ch=freelist[0];
  211. if (ch)
  212. {
  213. freelist[0]=freelist[ch];
  214. freelist[ch]=0;
  215. cyclelist[ch]+=MAXCHANNELS;
  216. ch|=cyclelist[ch];
  217. }
  218. return ch;
  219. }
  220. void freechannel(int ch)
  221. {
  222. if (ch==0) return;
  223. ch&=(MAXCHANNELS-1);
  224. if (freelist[ch]) return;
  225. if (channels[ch])
  226. {
  227. // channels[ch]->stop(0);
  228. channels[ch]=0;
  229. }
  230. freelist[ch]=freelist[0];
  231. freelist[0]=ch;
  232. }
  233. void setchannel(int ch,output *o)
  234. {
  235. output *old;
  236. if (ch==0) return;
  237. old=getchannel(ch);
  238. if (old) old->stop(0);
  239. ch&=(MAXCHANNELS-1);
  240. channels[ch]=o;
  241. }
  242. output *getchannel(int ch)
  243. {
  244. if (ch==0) return 0;
  245. if (audio==0) return 0;
  246. int cycle=ch & (-MAXCHANNELS);
  247. ch&=(MAXCHANNELS-1);
  248. if (cyclelist[ch]==cycle)
  249. {
  250. if (!channels[ch]) channels[ch]=audio->mix->allocsound(0);
  251. return channels[ch];
  252. }
  253. return 0;
  254. }
  255. };
  256. static systemio *io=0;
  257. #endif