aRts audio server
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

391 lines
8.9KB

  1. /*
  2. Copyright (C) 2001 Carsten Griwodz
  3. griff@ifi.uio.no
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public License
  13. along with this library; see the file COPYING.LIB. If not, write to
  14. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15. Boston, MA 02110-1301, USA.
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. #include <config.h>
  19. #endif
  20. #ifdef _AIX
  21. /*
  22. * The audio header files exist even if there is not soundcard the
  23. * the AIX machine. You won't be able to compile this code on AIX3
  24. * which had ACPA support, so /dev/acpa is not checked here.
  25. * I have no idea whether the Ultimedia Audio Adapter is actually
  26. * working or what it is right now.
  27. * For PCI machines including PowerSeries 850, baud or paud should
  28. * work. The DSP (MWave?) of the 850 laptops may need microcode
  29. * download. This is not implemented.
  30. */
  31. #include <assert.h>
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <errno.h>
  36. #include <unistd.h>
  37. #include <fcntl.h>
  38. #include <sys/time.h>
  39. #include <sys/ioctl.h>
  40. #include <sys/stat.h>
  41. #include <sys/machine.h>
  42. #undef BIG_ENDIAN
  43. #include <sys/audio.h>
  44. #ifndef AUDIO_BIG_ENDIAN
  45. #define AUDIO_BIG_ENDIAN BIG_ENDIAN
  46. #endif
  47. #include "debug.h"
  48. #include "audioio.h"
  49. namespace Arts {
  50. class AudioIOAIX : public AudioIO {
  51. int openDevice();
  52. protected:
  53. int audio_fd;
  54. public:
  55. AudioIOAIX();
  56. void setParam(AudioParam param, int& value);
  57. int getParam(AudioParam param);
  58. bool open();
  59. void close();
  60. int read(void *buffer, int size);
  61. int write(void *buffer, int size);
  62. };
  63. REGISTER_AUDIO_IO(AudioIOAIX,"paud","Personal Audio Device");
  64. };
  65. using namespace std;
  66. using namespace Arts;
  67. int AudioIOAIX::openDevice()
  68. {
  69. char devname[14];
  70. int fd;
  71. for ( int dev=0; dev<4; dev++ )
  72. {
  73. for ( int chan=1; chan<8; chan++ )
  74. {
  75. sprintf(devname,"/dev/paud%d/%d",dev,chan);
  76. fd = ::open (devname, O_WRONLY, 0);
  77. if ( fd >= 0 )
  78. {
  79. paramStr(deviceName) = devname;
  80. return fd;
  81. }
  82. sprintf(devname,"/dev/baud%d/%d",dev,chan);
  83. fd = ::open (devname, O_WRONLY, 0);
  84. if ( fd >= 0 )
  85. {
  86. paramStr(deviceName) = devname;
  87. return fd;
  88. }
  89. }
  90. }
  91. return -1;
  92. }
  93. AudioIOAIX::AudioIOAIX()
  94. {
  95. int fd = openDevice();
  96. if( fd >= 0 )
  97. {
  98. audio_status audiotqStatus;
  99. memset( &audiotqStatus, 0, sizeof(audio_status) );
  100. ioctl(fd, AUDIO_STATUS, &audiotqStatus);
  101. audio_buffer audioBuffer;
  102. memset( &audioBuffer, 0, sizeof(audio_buffer) );
  103. ioctl(fd, AUDIO_BUFFER, &audioBuffer);
  104. ::close( fd );
  105. /*
  106. * default parameters
  107. */
  108. param(samplingRate) = audiotqStatus.srate;
  109. param(fragmentSize) = audiotqStatus.bsize;
  110. param(fragmentCount) = audioBuffer.write_buf_cap / audiotqStatus.bsize;
  111. param(channels) = audiotqStatus.channels;
  112. param(direction) = 2;
  113. param(format) = ( audiotqStatus.bits_per_sample==8 ) ? 8
  114. : ( ( audiotqStatus.flags & AUDIO_BIG_ENDIAN ) ? 17 : 16 );
  115. }
  116. }
  117. bool AudioIOAIX::open()
  118. {
  119. string& _error = paramStr(lastError);
  120. string& _deviceName = paramStr(deviceName);
  121. int& _channels = param(channels);
  122. int& _fragmentSize = param(fragmentSize);
  123. int& _fragmentCount = param(fragmentCount);
  124. int& _samplingRate = param(samplingRate);
  125. int& _format = param(format);
  126. int mode;
  127. switch( param(direction) )
  128. {
  129. case 1 : mode = O_RDONLY | O_NDELAY; break;
  130. case 2 : mode = O_WRONLY | O_NDELAY; break;
  131. case 3 :
  132. _error = "open device twice to RDWR";
  133. return false;
  134. default :
  135. _error = "invalid direction";
  136. return false;
  137. }
  138. audio_fd = ::open(_deviceName.c_str(), mode, 0);
  139. if(audio_fd == -1)
  140. {
  141. _error = "device ";
  142. _error += _deviceName.c_str();
  143. _error += " can't be opened (";
  144. _error += strerror(errno);
  145. _error += ")";
  146. return false;
  147. }
  148. if( (_channels!=1) && (_channels!=2) )
  149. {
  150. _error = "internal error; set channels to 1 (mono) or 2 (stereo)";
  151. close();
  152. return false;
  153. }
  154. // int requeststereo = stereo;
  155. // int speed = _samplingRate;
  156. audio_init audioInit;
  157. memset( &audioInit, 0, sizeof(audio_init) );
  158. audioInit.srate = _samplingRate;
  159. audioInit.bits_per_sample = ((_format==8)?8:16);
  160. audioInit.bsize = _fragmentSize;
  161. audioInit.mode = PCM;
  162. audioInit.channels = _channels;
  163. audioInit.flags = 0;
  164. audioInit.flags |= (_format==17) ? AUDIO_BIG_ENDIAN : 0;
  165. audioInit.flags |= (_format==8) ? 0 : SIGNED;
  166. audioInit.operation = (param(direction)==1) ? RECORD : PLAY;
  167. if ( ioctl(audio_fd, AUDIO_INIT, &audioInit) < 0 )
  168. {
  169. _error = "AUDIO_INIT failed - ";
  170. _error += strerror(errno);
  171. switch ( audioInit.rc )
  172. {
  173. case 1 :
  174. _error += "Couldn't set audio format: DSP can't do play requests";
  175. break;
  176. case 2 :
  177. _error += "Couldn't set audio format: DSP can't do record requests";
  178. break;
  179. case 4 :
  180. _error += "Couldn't set audio format: request was invalid";
  181. break;
  182. case 5 :
  183. _error += "Couldn't set audio format: conflict with open's flags";
  184. break;
  185. case 6 :
  186. _error += "Couldn't set audio format: out of DSP MIPS or memory";
  187. break;
  188. default :
  189. _error += "Couldn't set audio format: not documented in sys/audio.h";
  190. break;
  191. }
  192. close();
  193. return false;
  194. }
  195. if (audioInit.channels != _channels)
  196. {
  197. _error = "audio device doesn't support number of requested channels";
  198. close();
  199. return false;
  200. }
  201. switch( _format )
  202. {
  203. case 8 :
  204. if (audioInit.flags&AUDIO_BIG_ENDIAN==1)
  205. {
  206. _error = "setting little endian format failed";
  207. close();
  208. return false;
  209. }
  210. if (audioInit.flags&SIGNED==1)
  211. {
  212. _error = "setting unsigned format failed";
  213. close();
  214. return false;
  215. }
  216. break;
  217. case 16 :
  218. if (audioInit.flags&AUDIO_BIG_ENDIAN==1)
  219. {
  220. _error = "setting little endian format failed";
  221. close();
  222. return false;
  223. }
  224. if (audioInit.flags&SIGNED==0)
  225. {
  226. _error = "setting signed format failed";
  227. close();
  228. return false;
  229. }
  230. break;
  231. case 17 :
  232. if (audioInit.flags&AUDIO_BIG_ENDIAN==0)
  233. {
  234. _error = "setting big endian format failed";
  235. close();
  236. return false;
  237. }
  238. if (audioInit.flags&SIGNED==0)
  239. {
  240. _error = "setting signed format failed";
  241. close();
  242. return false;
  243. }
  244. break;
  245. default :
  246. break;
  247. }
  248. /*
  249. * Some soundcards seem to be able to only supply "nearly" the requested
  250. * sampling rate, especially PAS 16 cards seem to quite radical supplying
  251. * something different than the requested sampling rate ;)
  252. *
  253. * So we have a quite large tolerance here (when requesting 44100 Hz, it
  254. * will accept anything between 38690 Hz and 49510 Hz). Most parts of the
  255. * aRts code will do resampling where appropriate, so it shouldn't affect
  256. * sound quality.
  257. */
  258. int tolerance = _samplingRate/10+1000;
  259. if (abs(audioInit.srate - _samplingRate) > tolerance)
  260. {
  261. _error = "can't set requested samplingrate";
  262. char details[80];
  263. sprintf(details," (requested rate %d, got rate %ld)",
  264. _samplingRate, audioInit.srate);
  265. _error += details;
  266. close();
  267. return false;
  268. }
  269. _samplingRate = audioInit.srate;
  270. _fragmentSize = audioInit.bsize;
  271. _fragmentCount = audioInit.bsize / audioInit.bits_per_sample;
  272. audio_buffer buffer_info;
  273. ioctl(audio_fd, AUDIO_BUFFER, &buffer_info);
  274. _fragmentCount = buffer_info.write_buf_cap / audioInit.bsize;
  275. artsdebug("buffering: %d fragments with %d bytes "
  276. "(audio latency is %1.1f ms)", _fragmentCount, _fragmentSize,
  277. (float)(_fragmentSize*_fragmentCount) /
  278. (float)(2.0 * _samplingRate * _channels)*1000.0);
  279. return true;
  280. }
  281. void AudioIOAIX::close()
  282. {
  283. ::close(audio_fd);
  284. }
  285. void AudioIOAIX::setParam(AudioParam p, int& value)
  286. {
  287. param(p) = value;
  288. }
  289. int AudioIOAIX::getParam(AudioParam p)
  290. {
  291. audio_buffer info;
  292. switch(p)
  293. {
  294. case canRead:
  295. ioctl(audio_fd, AUDIO_BUFFER, &info);
  296. return (info.read_buf_cap - info.read_buf_size);
  297. break;
  298. case canWrite:
  299. ioctl(audio_fd, AUDIO_BUFFER, &info);
  300. return (info.write_buf_cap - info.write_buf_size);
  301. break;
  302. case selectReadFD:
  303. return (param(direction) & directionRead)?audio_fd:-1;
  304. break;
  305. case selectWriteFD:
  306. return (param(direction) & directionWrite)?audio_fd:-1;
  307. break;
  308. case autoDetect:
  309. /* You may prefer OSS if it works, e.g. on 43P 240
  310. * or you may prefer UMS, if anyone bothers to write
  311. * a module for it.
  312. */
  313. return 2;
  314. break;
  315. default:
  316. return param(p);
  317. break;
  318. }
  319. }
  320. int AudioIOAIX::read(void *buffer, int size)
  321. {
  322. arts_assert(audio_fd != 0);
  323. return ::read(audio_fd,buffer,size);
  324. }
  325. int AudioIOAIX::write(void *buffer, int size)
  326. {
  327. arts_assert(audio_fd != 0);
  328. return ::write(audio_fd,buffer,size);
  329. }
  330. #endif