Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

485 lines
8.8 KiB

  1. /******************************Module*Header*********************************\
  2. * Module Name: cda.c
  3. *
  4. * Media Control Architecture Redbook CD Audio Driver
  5. *
  6. * Author: RobinSp
  7. *
  8. * History:
  9. * RobinSp 10th March 1992 - Move to Windows NT
  10. *
  11. * Copyright (c) 1990-1996 Microsoft Corporation
  12. *
  13. \****************************************************************************/
  14. #include <windows.h>
  15. #include <mmsystem.h>
  16. #include "mcicda.h"
  17. #include "cda.h"
  18. #include "cdio.h"
  19. int Usage; // See CDA_init_audio and CDA_terminate_audio
  20. // Counts number of 'init's over number of 'terminate's
  21. #define validdisk(did) ((did) >= 0 && (did) < MCIRBOOK_MAX_DRIVES && \
  22. CdInfo[did].hDevice != NULL)
  23. int CDA_traystate (DID did)
  24. {
  25. if (!validdisk(did))
  26. return(INVALID_DRIVE);
  27. return CdTrayClosed(&CdInfo[did]) ? TRAY_CLOSED : TRAY_OPEN;
  28. }
  29. /*
  30. * Convert frames to MSF
  31. */
  32. redbook CDA_bin2red (unsigned long ul)
  33. {
  34. return MAKERED(ul / (75 * 60), (ul / 75) % 60, ul % 75);
  35. }
  36. /*
  37. * Convert MSF to frames
  38. */
  39. unsigned long CDA_red2bin (redbook red)
  40. {
  41. return (unsigned long)((REDMINUTE(red) * 60) +
  42. REDSECOND(red)) * 75 +
  43. REDFRAME(red);
  44. }
  45. BOOL CDA_open(DID did)
  46. {
  47. return CdOpen(did);
  48. }
  49. BOOL CDA_close(DID did)
  50. {
  51. return CdClose(&CdInfo[did]);
  52. }
  53. int CDA_eject(DID did)
  54. {
  55. if (!validdisk(did))
  56. return(INVALID_DRIVE);
  57. return CdEject(&CdInfo[did]);
  58. }
  59. /*
  60. * Close the door.
  61. *
  62. * Returns :
  63. * TRUE if successful
  64. * FALSE if failed
  65. */
  66. BOOL CDA_closetray(DID did)
  67. {
  68. if (!validdisk(did))
  69. return(FALSE);
  70. return CdCloseTray(&CdInfo[did]);
  71. }
  72. /*
  73. * Check if the disk is ready
  74. *
  75. * Returns :
  76. * TRUE if successful
  77. * FALSE if failed
  78. */
  79. BOOL CDA_disc_ready(DID did)
  80. {
  81. if (!validdisk(did))
  82. return(FALSE);
  83. /* if drive is ejected, the disc is not ready! */
  84. if (CDA_traystate(did) != TRAY_CLOSED)
  85. return(FALSE);
  86. /* volume size ioctl just to get error code */
  87. return CdReady(&CdInfo[did]);
  88. }
  89. /*
  90. * Seek to the requested redbook address
  91. *
  92. * did - disk id
  93. * address - redbook address
  94. *
  95. * Return value :
  96. * INVALID_DRIVE - Invalid disk drive
  97. * COMMAND_SUCCESSFUL - OK
  98. * COMMAND_FAILED - did not succeed - possible hardware problem.
  99. */
  100. int CDA_seek_audio(DID did, redbook address, BOOL fForceAudio)
  101. {
  102. if (!validdisk(did))
  103. return(INVALID_DRIVE);
  104. //
  105. // LMSI drive needs to be stopped/paused before seeking
  106. //
  107. CdPause(&CdInfo[did]);
  108. return CdSeek(&CdInfo[did], address, fForceAudio) ? COMMAND_SUCCESSFUL : COMMAND_FAILED;
  109. }
  110. /*
  111. * init the CDA library, return the number of CD-Drives present
  112. */
  113. int CDA_init_audio(void)
  114. {
  115. //
  116. // if we are inited already, get out fast.
  117. //
  118. if (Usage++ == 0)
  119. {
  120. //
  121. // try the CDROM Extentions
  122. //
  123. NumDrives = CdGetNumDrives();
  124. if (NumDrives == 0) {
  125. CDA_terminate_audio();
  126. }
  127. }
  128. return NumDrives;
  129. }
  130. int CDA_terminate_audio()
  131. {
  132. DID did;
  133. if (Usage > 0 && --Usage == 0)
  134. {
  135. for(did=0;did<MCIRBOOK_MAX_DRIVES;did++) {
  136. if (CdInfo[did].hDevice) {
  137. CdClose(&CdInfo[did]);
  138. }
  139. }
  140. }
  141. return Usage;
  142. }
  143. unsigned long CDA_get_support_info(DID did)
  144. {
  145. if (!validdisk(did))
  146. return(0);
  147. return SUPPORTS_REDBOOKAUDIO | SUPPORTS_CHANNELCONTROL;
  148. }
  149. int CDA_drive_status (DID did)
  150. {
  151. if (!validdisk(did))
  152. return(INVALID_DRIVE);
  153. return (int)CdStatus(&CdInfo[did]);
  154. }
  155. /*
  156. * Find the number of tracks on the CD Rom. If the CD Rom can't be
  157. * accessed or has no audio tracks then 0 is returned.
  158. *
  159. * This function has the (MAJOR) side effect of updating the table
  160. * of contents of it's thought to be out of date
  161. */
  162. int CDA_num_tracks(DID did)
  163. {
  164. if (!validdisk(did))
  165. return 0;
  166. return CdNumTracks(&CdInfo[did]);
  167. }
  168. redbook CDA_track_start(DID did, int trk)
  169. {
  170. if (!validdisk(did)) {
  171. return (redbook)INVALID_TRACK;
  172. }
  173. return REDTH(CdTrackStart(&CdInfo[did], (UCHAR)trk), trk);
  174. }
  175. redbook CDA_track_length(DID did, int trk)
  176. {
  177. if (!validdisk(did)) {
  178. return (redbook)INVALID_TRACK;
  179. }
  180. return CdTrackLength(&CdInfo[did], (UCHAR)trk);
  181. }
  182. int CDA_track_type(DID did, int trk)
  183. {
  184. if (!validdisk(did)) {
  185. return INVALID_TRACK;
  186. }
  187. return CdTrackType(&CdInfo[did], (UCHAR)trk);
  188. }
  189. redbook CDA_disc_length(DID did)
  190. {
  191. if (!validdisk(did)) {
  192. return (redbook)INVALID_TRACK;
  193. }
  194. return CdDiskLength(&CdInfo[did]); // NB - subtract 1 for bad systems
  195. }
  196. int CDA_play_audio(DID did, redbook start, redbook to)
  197. {
  198. redbook diskinfo;
  199. if (!validdisk(did))
  200. return(INVALID_DRIVE);
  201. //
  202. // Must use Stop because Pause may not allow reading of data from
  203. // the CD. However, Stop sometimes has the nasty side-effect of
  204. // seeking to the start (!).
  205. //
  206. CdPause(&CdInfo[did]);
  207. if (start != to) {
  208. return CdPlay(&CdInfo[did], start, to) ?
  209. COMMAND_SUCCESSFUL : COMMAND_FAILED;
  210. } else {
  211. return COMMAND_SUCCESSFUL;
  212. }
  213. }
  214. int CDA_stop_audio(DID did)
  215. {
  216. return CdStop(&CdInfo[did]) ? COMMAND_SUCCESSFUL : COMMAND_FAILED;
  217. }
  218. int CDA_pause_audio(DID did)
  219. {
  220. return CdPause(&CdInfo[did]) ? COMMAND_SUCCESSFUL : COMMAND_FAILED;
  221. }
  222. int CDA_resume_audio(DID did)
  223. {
  224. return CdResume(&CdInfo[did]) ? COMMAND_SUCCESSFUL : COMMAND_FAILED;
  225. }
  226. int CDA_set_audio_volume(DID did, int channel, UCHAR volume)
  227. {
  228. if (!validdisk(did))
  229. return(INVALID_DRIVE);
  230. if ((channel > 3) || (channel < 0))
  231. return(COMMAND_FAILED);
  232. return CdSetVolume(&CdInfo[did], channel, volume) ?
  233. COMMAND_SUCCESSFUL : COMMAND_FAILED;
  234. }
  235. int CDA_set_audio_volume_all (DID did, UCHAR volume)
  236. {
  237. int rc = COMMAND_SUCCESSFUL;
  238. int channel;
  239. if (!validdisk(did))
  240. return(INVALID_DRIVE);
  241. if (!CdSetVolumeAll(&CdInfo[did], volume))
  242. {
  243. rc = COMMAND_FAILED;
  244. }
  245. /*
  246. for (channel = 0; channel < 4; ++channel)
  247. {
  248. if (!CdSetVolume(&CdInfo[did], channel, volume))
  249. {
  250. rc = COMMAND_FAILED;
  251. }
  252. }
  253. */
  254. return rc;
  255. }
  256. int CDA_time_info(DID did, redbook *ptracktime, redbook *pdisctime)
  257. {
  258. int rc;
  259. redbook tracktime, disctime;
  260. tracktime = INVALID_TRACK;
  261. disctime = INVALID_TRACK;
  262. if (!validdisk(did))
  263. {
  264. rc = INVALID_DRIVE;
  265. } else {
  266. if (CdPosition(&CdInfo[did], &tracktime, &disctime)) {
  267. rc = COMMAND_SUCCESSFUL;
  268. } else {
  269. rc = COMMAND_FAILED;
  270. }
  271. }
  272. if (ptracktime) {
  273. *ptracktime = tracktime;
  274. }
  275. if (pdisctime) {
  276. *pdisctime = disctime;
  277. }
  278. return rc;
  279. }
  280. /*
  281. * CDA_disc_end
  282. *
  283. * Parameters
  284. * did - The disk ID
  285. *
  286. * Return the redbook address for the end of the disk defined by did
  287. */
  288. redbook CDA_disc_end(DID did)
  289. {
  290. return CdDiskEnd(&CdInfo[did]);
  291. }
  292. /*
  293. * CDA_disc_upc
  294. *
  295. * Parameters
  296. * did - The disk ID
  297. * upc - where to store the upc
  298. */
  299. int CDA_disc_upc(DID did, LPTSTR upc)
  300. {
  301. if (!validdisk(did)) {
  302. return FALSE;
  303. }
  304. return CdDiskUPC(&CdInfo[did], upc) ?
  305. COMMAND_SUCCESSFUL : COMMAND_FAILED;
  306. }
  307. /*
  308. * CDA_disc_id
  309. *
  310. * Parameters
  311. * lpstrname - device name
  312. * pdid - The disk ID
  313. */
  314. DWORD CDA_disc_id(DID did)
  315. {
  316. if (!validdisk(did)) {
  317. return (DWORD)-1;
  318. }
  319. return CdDiskID(&CdInfo[did]);
  320. }
  321. /*
  322. * CDA_reset_drive
  323. *
  324. * Parameters
  325. * did - The disk ID
  326. */
  327. void CDA_reset_drive(DID did)
  328. {
  329. if (!validdisk(did)) {
  330. return;
  331. }
  332. return;
  333. }
  334. /*
  335. * CDA_get_drive
  336. *
  337. * Parameters
  338. *
  339. * lpstrDeviceName - name of device
  340. * pdid - The disk ID
  341. */
  342. int CDA_get_drive(LPCTSTR lpstrDeviceName, DID * pdid)
  343. {
  344. return CdGetDrive(lpstrDeviceName, pdid) ? COMMAND_SUCCESSFUL : COMMAND_FAILED;
  345. }
  346. /*
  347. * CDA_status_track_pos
  348. *
  349. * Parameters
  350. * pdid - The disk ID
  351. * pStatus - return status code
  352. * pTrackTime - track time
  353. * pDiscTime - disc time
  354. */
  355. int CDA_status_track_pos(
  356. DID did,
  357. DWORD * pStatus,
  358. redbook * pTrackTime,
  359. redbook * pDiscTime)
  360. {
  361. int rc;
  362. DWORD status;
  363. redbook tracktime, disctime;
  364. status = DISC_NOT_READY;
  365. tracktime = INVALID_TRACK;
  366. disctime = INVALID_TRACK;
  367. if (!validdisk(did))
  368. {
  369. rc = INVALID_DRIVE;
  370. }
  371. else
  372. {
  373. if (CdStatusTrackPos(&CdInfo[did], &status, &tracktime, &disctime))
  374. {
  375. rc = COMMAND_SUCCESSFUL;
  376. }
  377. else
  378. {
  379. rc = COMMAND_FAILED;
  380. }
  381. }
  382. if (pStatus)
  383. {
  384. *pStatus = status;
  385. }
  386. if (pTrackTime)
  387. {
  388. *pTrackTime = tracktime;
  389. }
  390. if (pDiscTime)
  391. {
  392. *pDiscTime = disctime;
  393. }
  394. return rc;
  395. } // End CDA_status_track_pos