diff options
Diffstat (limited to 'apps/plugins/sdl/src/cdrom/macosx/SDL_syscdrom_c.h')
-rw-r--r-- | apps/plugins/sdl/src/cdrom/macosx/SDL_syscdrom_c.h | 136 |
1 files changed, 0 insertions, 136 deletions
diff --git a/apps/plugins/sdl/src/cdrom/macosx/SDL_syscdrom_c.h b/apps/plugins/sdl/src/cdrom/macosx/SDL_syscdrom_c.h deleted file mode 100644 index 589c5897e6..0000000000 --- a/apps/plugins/sdl/src/cdrom/macosx/SDL_syscdrom_c.h +++ /dev/null | |||
@@ -1,136 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* This is the Mac OS X / CoreAudio specific header for the SDL CD-ROM API | ||
25 | Contributed by Darrell Walisser and Max Horn | ||
26 | */ | ||
27 | |||
28 | /*********************************************************************************** | ||
29 | Implementation Notes | ||
30 | ********************* | ||
31 | |||
32 | This code has several limitations currently (all of which are proabaly fixable): | ||
33 | |||
34 | 1. A CD-ROM device is inferred from a mounted cdfs volume, so device 0 is | ||
35 | not necessarily the first CD-ROM device on the system. (Somewhat easy to fix | ||
36 | by useing the device name from the volume id's to reorder the volumes) | ||
37 | |||
38 | 2. You can only open and control 1 CD-ROM device at a time. (Challenging to fix, | ||
39 | due to extensive code restructuring) | ||
40 | |||
41 | 3. The status reported by SDL_CDStatus only changes to from CD_PLAYING to CD_STOPPED in | ||
42 | 1-second intervals (because the audio is buffered in 1-second chunks) If | ||
43 | the audio data is less than 1 second, the remainder is filled with silence. | ||
44 | |||
45 | If you need to play sequences back-to-back that are less that 1 second long, | ||
46 | use the frame position to determine when to play the next sequence, instead | ||
47 | of SDL_CDStatus. | ||
48 | |||
49 | This may be possible to fix with a clever usage of the AudioUnit API. | ||
50 | |||
51 | 4. When new volumes are inserted, our volume information is not updated. The only way | ||
52 | to refresh this information is to reinit the CD-ROM subsystem of SDL. To fix this, | ||
53 | one would probably have to fix point 1 above first, then figure out how to register | ||
54 | for a notification when new media is mounted in order to perform an automatic | ||
55 | rescan for cdfs volumes. | ||
56 | |||
57 | |||
58 | |||
59 | So, here comes a description of how this all works. | ||
60 | |||
61 | < Initializing > | ||
62 | |||
63 | To get things rolling, we have to locate mounted volumes that contain | ||
64 | audio (since nearly all Macs don't have analog audio-in on the sound card). | ||
65 | That's easy, since these volumes have a flag that indicates this special | ||
66 | filesystem. See DetectAudioCDVolumes() in CDPlayer.cpp for this code. | ||
67 | |||
68 | Next, we parse the invisible .TOC.plist in the root of the volume, which gets us | ||
69 | the track information (number, offset, length, leadout, etc). See ReadTOCData() in | ||
70 | CDPlayer.cpp for the skinny on this. | ||
71 | |||
72 | |||
73 | < The Playback Loop > | ||
74 | |||
75 | Now come the tricky parts. Let's start with basic audio playback. When a frame | ||
76 | range to play is requested, we must first find the .aiff files on the volume, | ||
77 | hopefully in the right order. Since these files all begin with a number "1 Audio Track", | ||
78 | etc, this is used to determine the correct track order. | ||
79 | |||
80 | Once all files are determined, we have to find what file corresponds to the start | ||
81 | and length parameter to SDL_SYS_CDPlay(). Again, this is quite simple by walking the | ||
82 | cdrom's track list. At this point, we also save the offset to the next track and frames | ||
83 | remaining, if we're going to have to play another file after the first one. See | ||
84 | GetFileForOffset() for this code. | ||
85 | |||
86 | At this point we have all info needed to start playback, so we hand off to the LoadFile() | ||
87 | function, which proceeds to do its magic and plays back the file. | ||
88 | |||
89 | When the file is finished playing, CompletionProc() is invoked, at which time we can | ||
90 | play the next file if the previously saved next track and frames remaining | ||
91 | indicates that we should. | ||
92 | |||
93 | |||
94 | < Magic > | ||
95 | |||
96 | OK, so it's not really magic, but since I don't fully understand all the hidden details it | ||
97 | seems like it to me ;-) The API's involved are the AudioUnit and AudioFile API's. These | ||
98 | appear to be an extension of CoreAudio for creating modular playback and f/x entities. | ||
99 | The important thing is that CPU usage is very low and reliability is very high. You'd | ||
100 | be hard-pressed to find a way to stutter the playback with other CPU-intensive tasks. | ||
101 | |||
102 | One part of this magic is that it uses multiple threads, which carries the usual potential | ||
103 | for disaster if not handled carefully. Playback currently requires 4 additional threads: | ||
104 | 1. The coreaudio runloop thread | ||
105 | 2. The coreaudio device i/o thread | ||
106 | 3. The file streaming thread | ||
107 | 4. The notification/callback thread | ||
108 | |||
109 | The first 2 threads are necessary evil - CoreAudio creates this no matter what the situation | ||
110 | is (even the SDL sound implementation creates theses suckers). The last two are are created | ||
111 | by us. | ||
112 | |||
113 | The file is streamed from disk using a threaded double-buffer approach. | ||
114 | This way, the high latency operation of reading from disk can be performed without interrupting | ||
115 | the real-time device thread (which amounts to avoiding dropouts). The device thread grabs the | ||
116 | buffer that isn't being read and sends it to the CoreAudio mixer where it eventually gets | ||
117 | to the sound card. | ||
118 | |||
119 | The device thread posts a notification when the file streaming thread is out of data. This | ||
120 | notification must be handled in a separate thread to avoid potential deadlock in the | ||
121 | device thread. That's where the notification thread comes in. This thread is signaled | ||
122 | whenever a notification needs to be processed, so another file can be played back if need be. | ||
123 | |||
124 | The API in CDPlayer.cpp contains synchronization because otherwise both the notification thread | ||
125 | and main thread (or another other thread using the SDL CD api) can potentially call it at the same time. | ||
126 | |||
127 | ************************************************************************************/ | ||
128 | |||
129 | |||
130 | #include "SDL_cdrom.h" | ||
131 | #include "../SDL_syscdrom.h" | ||
132 | |||
133 | #include "CDPlayer.h" | ||
134 | |||
135 | #define kErrorFakeDevice "Error: Cannot proceed since we're faking a CD-ROM device. Reinit the CD-ROM subsystem to scan for new volumes." | ||
136 | |||