drv_AF.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:5k
源码类别:

Windows CE

开发平台:

C/C++

  1. /* MikMod sound library
  2. (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for
  3. complete list.
  4. This library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of
  7. the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  17. 02111-1307, USA.
  18. */
  19.   
  20. /*==============================================================================
  21.   $Id: drv_AF.c,v 1.2 2004/01/31 22:39:40 raph Exp $
  22.   Driver for output on AF audio server.
  23. ==============================================================================*/
  24. /*
  25. Written by Roine Gustafsson <e93_rog@e.kth.se>
  26.   
  27. Portability:
  28. Unixes running Digital AudioFile library, available from
  29. ftp://crl.dec.com/pub/DEC/AF
  30. Usage:
  31. Run the audio server (Aaxp&, Amsb&, whatever)
  32. Set environment variable AUDIOFILE to something like 'mymachine:0'.
  33. Remember, stereo is default! See commandline switches.
  34. I have a version which uses 2 computers for stereo.
  35. Contact me if you want it.
  36.   
  37. */
  38. #ifdef HAVE_CONFIG_H
  39. #include "config.h"
  40. #endif
  41. #include "mikmod_internals.h"
  42. #ifdef DRV_AF
  43. #ifdef HAVE_UNISTD_H
  44. #include <unistd.h>
  45. #endif
  46. #include <stdlib.h>
  47. #include <AF/AFlib.h>
  48. /* Global variables */
  49. static SBYTE *audiobuffer=NULL;
  50. static int AFFragmentSize;
  51. static AFAudioConn *AFaud=NULL;
  52. static ATime AFtime;
  53. static AC AFac;
  54. static AFDeviceDescriptor *AFdesc;
  55. static CHAR *soundbox=NULL;
  56. static void AF_CommandLine(CHAR *cmdline)
  57. {
  58. CHAR *machine=MD_GetAtom("machine",cmdline,0);
  59. if(machine) {
  60. if(soundbox) free(soundbox);
  61. soundbox=machine;
  62. }
  63. }
  64. static BOOL AF_IsThere(void)
  65. {
  66. if ((AFaud=AFOpenAudioConn(soundbox)))
  67. AFCloseAudioConn(AFaud);
  68. AFaud=NULL;
  69. return 1;
  70. } else
  71. return 0;
  72. }
  73. static BOOL AF_Init(void)
  74. {
  75. unsigned long mask;
  76. AFSetACAttributes attributes;
  77. int srate;
  78. ADevice device;
  79. int n;
  80.   
  81. if (!(AFaud=AFOpenAudioConn(soundbox))) {
  82. _mm_errno=MMERR_OPENING_AUDIO;
  83. return 1;
  84. }
  85. /* Search for a suitable device */
  86. device=-1;
  87. for (n=0;n<AFaud->ndevices;n++) {
  88. AFdesc=AAudioDeviceDescriptor(AFaud,n);
  89. if ((AFdesc->playNchannels==2)&&(md_mode&DMODE_STEREO)) {
  90. device=n;
  91. break;
  92. }
  93. if ((AFdesc->playNchannels==1)&&!(md_mode&DMODE_STEREO)) {
  94. device=n;
  95. break;
  96. }
  97. }
  98. if (device==-1) {
  99. _mm_errno=MMERR_AF_AUDIO_PORT;
  100. return 1;
  101. }
  102. attributes.preempt=Mix;
  103. attributes.start_timeout=0;
  104. attributes.end_silence=0;
  105. /* in case of an 8bit device, the AF converts the 16 bit data to 8 bit */
  106. attributes.type=LIN16;
  107. attributes.channels=(md_mode&DMODE_STEREO)?Stereo:Mono;
  108. mask=ACPreemption|ACEncodingType|ACStartTimeout|ACEndSilence|ACChannels;
  109. AFac=AFCreateAC(AFaud,device,mask,&attributes);
  110. srate=AFac->device->playSampleFreq;
  111. md_mode|=DMODE_16BITS; /* This driver only handles 16bits */
  112. AFFragmentSize=(srate/40)*8; /* Update 5 times/sec */
  113. md_mixfreq=srate; /* set mixing freq */
  114. if (md_mode&DMODE_STEREO) {
  115. if (!(audiobuffer=(SBYTE*)_mm_malloc(2*2*AFFragmentSize))) 
  116. return 1;
  117. } else {
  118. if (!(audiobuffer=(SBYTE*)_mm_malloc(2*AFFragmentSize))) 
  119. return 1;
  120. }
  121.   
  122. return VC_Init();
  123. }
  124. static BOOL AF_PlayStart(void)
  125. {
  126. AFtime=AFGetTime(AFac);
  127. return VC_PlayStart();
  128. }
  129. static void AF_Exit(void)
  130. {
  131. VC_Exit();
  132. _mm_free(audiobuffer);
  133. if (AFaud) {
  134. AFCloseAudioConn(AFaud);
  135. AFaud=NULL;
  136. }
  137. }
  138. static void AF_Update(void)
  139. {
  140. ULONG done;
  141.   
  142. done=VC_WriteBytes(audiobuffer,AFFragmentSize);
  143. if (md_mode&DMODE_STEREO) {
  144. AFPlaySamples(AFac,AFtime,done,(unsigned char*)audiobuffer);
  145. AFtime+=done/4;
  146. /* while (AFGetTime(AFac)<AFtime-1000); */
  147. } else {
  148. AFPlaySamples(AFac,AFtime,done,(unsigned char*)audiobuffer);
  149. AFtime+=done/2;
  150. /* while (AFGetTime(AFac)<AFtime-1000); */
  151. }
  152. }
  153. MIKMODAPI MDRIVER drv_AF={
  154. NULL,
  155. "AF driver",
  156. "AudioFile driver v1.3",
  157. 0,255,
  158. "audiofile",
  159. "machine:t::Audio server machine (hostname:port)n",
  160. AF_CommandLine,
  161. AF_IsThere,
  162. VC_SampleLoad,
  163. VC_SampleUnload,
  164. VC_SampleSpace,
  165. VC_SampleLength,
  166. AF_Init,
  167. AF_Exit,
  168. NULL,
  169. VC_SetNumVoices,
  170. AF_PlayStart,
  171. VC_PlayStop,
  172. AF_Update,
  173. NULL,
  174. VC_VoiceSetVolume,
  175. VC_VoiceGetVolume,
  176. VC_VoiceSetFrequency,
  177. VC_VoiceGetFrequency,
  178. VC_VoiceSetPanning,
  179. VC_VoiceGetPanning,
  180. VC_VoicePlay,
  181. VC_VoiceStop,
  182. VC_VoiceStopped,
  183. VC_VoiceGetPosition,
  184. VC_VoiceRealVolume
  185. };
  186. #else
  187. MISSING(drv_AF);
  188. #endif
  189. /* ex:set ts=4: */