Mercurial > sdl-ios-xcode
annotate src/audio/qsa/SDL_qsa_audio.c @ 3235:d35b649858e0
David Carre to Sam
Hello sam, me again.
I'v fixed another bug in the pandora code, it's on the no-X videodriver, i forgot to add some code to destroy the window so it was impossible to reload SDL inside the same application (eglTerminate).
You'll find the svn diff attached.
See you,
David.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 11 Aug 2009 13:45:01 +0000 |
parents | 7f684f249ec9 |
children | f7b03b6838cb |
rev | line source |
---|---|
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
1 /* |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
2 SDL - Simple DirectMedia Layer |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
3 Copyright (C) 1997-2009 Sam Lantinga |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
4 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
5 This library is free software; you can redistribute it and/or |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
6 modify it under the terms of the GNU Library General Public |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
7 License as published by the Free Software Foundation; either |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
8 version 2 of the License, or (at your option) any later version. |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
9 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
10 This library is distributed in the hope that it will be useful, |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
13 Library General Public License for more details. |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
14 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
15 You should have received a copy of the GNU Library General Public |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
16 License along with this library; if not, write to the Free |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
18 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
19 Sam Lantinga |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
20 slouken@libsdl.org |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
21 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
22 QNX Sound Architecture (QSA) SDL driver |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
23 Copyright (C) 2009 Mike Gorchak |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
24 (mike@malva.ua, lestat@i.com.ua) |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
25 */ |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
26 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
27 #include "SDL_config.h" |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
28 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
29 #include <errno.h> |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
30 #include <unistd.h> |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
31 #include <fcntl.h> |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
32 #include <signal.h> |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
33 #include <sys/types.h> |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
34 #include <sys/time.h> |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
35 #include <sched.h> |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
36 #include <sys/select.h> |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
37 #include <sys/neutrino.h> |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
38 #include <sys/asoundlib.h> |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
39 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
40 #include "SDL_timer.h" |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
41 #include "SDL_audio.h" |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
42 #include "../SDL_audiomem.h" |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
43 #include "../SDL_audio_c.h" |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
44 #include "SDL_qsa_audio.h" |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
45 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
46 /* The tag name used by QSA audio framework */ |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
47 #define DRIVER_NAME "qsa" |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
48 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
49 /* default channel communication parameters */ |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
50 #define DEFAULT_CPARAMS_RATE 44100 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
51 #define DEFAULT_CPARAMS_VOICES 1 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
52 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
53 #define DEFAULT_CPARAMS_FRAG_SIZE 4096 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
54 #define DEFAULT_CPARAMS_FRAGS_MIN 1 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
55 #define DEFAULT_CPARAMS_FRAGS_MAX 1 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
56 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
57 #define QSA_NO_WORKAROUNDS 0x00000000 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
58 #define QSA_MMAP_WORKAROUND 0x00000001 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
59 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
60 struct BuggyCards |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
61 { |
3139 | 62 char *cardname; |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
63 unsigned long bugtype; |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
64 }; |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
65 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
66 #define QSA_WA_CARDS 3 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
67 #define QSA_MAX_CARD_NAME_LENGTH 33 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
68 |
3139 | 69 struct BuggyCards buggycards[QSA_WA_CARDS] = { |
70 {"Sound Blaster Live!", QSA_MMAP_WORKAROUND}, | |
71 {"Vortex 8820", QSA_MMAP_WORKAROUND}, | |
72 {"Vortex 8830", QSA_MMAP_WORKAROUND}, | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
73 }; |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
74 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
75 /* List of found devices */ |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
76 #define QSA_MAX_DEVICES 32 |
3139 | 77 #define QSA_MAX_NAME_LENGTH 81+16 /* Hardcoded in QSA, can't be changed */ |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
78 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
79 typedef struct _QSA_Device |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
80 { |
3139 | 81 char name[QSA_MAX_NAME_LENGTH]; /* Long audio device name for SDL */ |
82 int cardno; | |
83 int deviceno; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
84 } QSA_Device; |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
85 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
86 QSA_Device qsa_playback_device[QSA_MAX_DEVICES]; |
3139 | 87 uint32_t qsa_playback_devices; |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
88 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
89 QSA_Device qsa_capture_device[QSA_MAX_DEVICES]; |
3139 | 90 uint32_t qsa_capture_devices; |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
91 |
3139 | 92 static inline void |
93 QSA_SetError(const char *fn, int status) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
94 { |
3139 | 95 SDL_SetError("QSA: %s() failed: %s", fn, snd_strerror(status)); |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
96 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
97 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
98 /* card names check to apply the workarounds */ |
3139 | 99 static int |
100 QSA_CheckBuggyCards(_THIS, unsigned long checkfor) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
101 { |
3139 | 102 char scardname[QSA_MAX_CARD_NAME_LENGTH]; |
103 int it; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
104 |
3139 | 105 if (snd_card_get_name |
106 (this->hidden->cardno, scardname, QSA_MAX_CARD_NAME_LENGTH - 1) < 0) { | |
107 return 0; | |
108 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
109 |
3139 | 110 for (it = 0; it < QSA_WA_CARDS; it++) { |
111 if (SDL_strcmp(buggycards[it].cardname, scardname) == 0) { | |
112 if (buggycards[it].bugtype == checkfor) { | |
113 return 1; | |
114 } | |
115 } | |
116 } | |
117 | |
118 return 0; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
119 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
120 |
3139 | 121 static void |
122 QSA_ThreadInit(_THIS) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
123 { |
3139 | 124 struct sched_param param; |
125 int status; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
126 |
3139 | 127 /* Increase default 10 priority to 25 to avoid jerky sound */ |
128 status = SchedGet(0, 0, ¶m); | |
129 param.sched_priority = param.sched_curpriority + 15; | |
130 status = SchedSet(0, 0, SCHED_NOCHANGE, ¶m); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
131 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
132 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
133 /* PCM channel parameters initialize function */ |
3139 | 134 static void |
135 QSA_InitAudioParams(snd_pcm_channel_params_t * cpars) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
136 { |
3139 | 137 SDL_memset(cpars, 0, sizeof(snd_pcm_channel_params_t)); |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
138 |
3139 | 139 cpars->channel = SND_PCM_CHANNEL_PLAYBACK; |
140 cpars->mode = SND_PCM_MODE_BLOCK; | |
141 cpars->start_mode = SND_PCM_START_DATA; | |
142 cpars->stop_mode = SND_PCM_STOP_STOP; | |
143 cpars->format.format = SND_PCM_SFMT_S16_LE; | |
144 cpars->format.interleave = 1; | |
145 cpars->format.rate = DEFAULT_CPARAMS_RATE; | |
146 cpars->format.voices = DEFAULT_CPARAMS_VOICES; | |
147 cpars->buf.block.frag_size = DEFAULT_CPARAMS_FRAG_SIZE; | |
148 cpars->buf.block.frags_min = DEFAULT_CPARAMS_FRAGS_MIN; | |
149 cpars->buf.block.frags_max = DEFAULT_CPARAMS_FRAGS_MAX; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
150 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
151 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
152 /* This function waits until it is possible to write a full sound buffer */ |
3139 | 153 static void |
154 QSA_WaitDevice(_THIS) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
155 { |
3139 | 156 fd_set wfds; |
157 fd_set rfds; | |
158 int selectret; | |
159 struct timeval timeout; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
160 |
3139 | 161 if (!this->hidden->iscapture) { |
162 FD_ZERO(&wfds); | |
163 FD_SET(this->hidden->audio_fd, &wfds); | |
164 } else { | |
165 FD_ZERO(&rfds); | |
166 FD_SET(this->hidden->audio_fd, &rfds); | |
167 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
168 |
3139 | 169 do { |
170 /* Setup timeout for playing one fragment equal to 2 seconds */ | |
171 /* If timeout occured than something wrong with hardware or driver */ | |
172 /* For example, Vortex 8820 audio driver stucks on second DAC because */ | |
173 /* it doesn't exist ! */ | |
174 timeout.tv_sec = 2; | |
175 timeout.tv_usec = 0; | |
176 this->hidden->timeout_on_wait = 0; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
177 |
3139 | 178 if (!this->hidden->iscapture) { |
179 selectret = | |
180 select(this->hidden->audio_fd + 1, NULL, &wfds, NULL, | |
181 &timeout); | |
182 } else { | |
183 selectret = | |
184 select(this->hidden->audio_fd + 1, &rfds, NULL, NULL, | |
185 &timeout); | |
186 } | |
187 | |
188 switch (selectret) { | |
189 case -1: | |
190 { | |
191 SDL_SetError("QSA: select() failed: %s\n", strerror(errno)); | |
192 return; | |
193 } | |
194 break; | |
195 case 0: | |
196 { | |
197 SDL_SetError("QSA: timeout on buffer waiting occured\n"); | |
198 this->hidden->timeout_on_wait = 1; | |
199 return; | |
200 } | |
201 break; | |
202 default: | |
203 { | |
204 if (!this->hidden->iscapture) { | |
205 if (FD_ISSET(this->hidden->audio_fd, &wfds)) { | |
206 return; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
207 } |
3139 | 208 } else { |
209 if (FD_ISSET(this->hidden->audio_fd, &rfds)) { | |
210 return; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
211 } |
3139 | 212 } |
213 } | |
214 break; | |
215 } | |
216 } while (1); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
217 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
218 |
3139 | 219 static void |
220 QSA_PlayDevice(_THIS) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
221 { |
3139 | 222 snd_pcm_channel_status_t cstatus; |
223 int written; | |
224 int status; | |
225 int towrite; | |
226 void *pcmbuffer; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
227 |
3139 | 228 if ((!this->enabled) || (!this->hidden)) { |
229 return; | |
230 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
231 |
3139 | 232 towrite = this->spec.size; |
233 pcmbuffer = this->hidden->pcm_buf; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
234 |
3139 | 235 /* Write the audio data, checking for EAGAIN (buffer full) and underrun */ |
236 do { | |
237 written = | |
238 snd_pcm_plugin_write(this->hidden->audio_handle, pcmbuffer, | |
239 towrite); | |
240 if (written != towrite) { | |
241 /* Check if samples playback got stuck somewhere in hardware or in */ | |
242 /* the audio device driver */ | |
243 if ((errno == EAGAIN) && (written == 0)) { | |
244 if (this->hidden->timeout_on_wait != 0) { | |
245 SDL_SetError("QSA: buffer playback timeout\n"); | |
246 return; | |
247 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
248 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
249 |
3139 | 250 /* Check for errors or conditions */ |
251 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { | |
252 /* Let a little CPU time go by and try to write again */ | |
253 SDL_Delay(1); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
254 |
3139 | 255 /* if we wrote some data */ |
256 towrite -= written; | |
257 pcmbuffer += written * this->spec.channels; | |
258 continue; | |
259 } else { | |
260 if ((errno == EINVAL) || (errno == EIO)) { | |
261 SDL_memset(&cstatus, 0, sizeof(cstatus)); | |
262 if (!this->hidden->iscapture) { | |
263 cstatus.channel = SND_PCM_CHANNEL_PLAYBACK; | |
264 } else { | |
265 cstatus.channel = SND_PCM_CHANNEL_CAPTURE; | |
266 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
267 |
3139 | 268 status = |
269 snd_pcm_plugin_status(this->hidden->audio_handle, | |
270 &cstatus); | |
271 if (status < 0) { | |
272 QSA_SetError("snd_pcm_plugin_status", status); | |
273 return; | |
274 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
275 |
3139 | 276 if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) || |
277 (cstatus.status == SND_PCM_STATUS_READY)) { | |
278 if (!this->hidden->iscapture) { | |
279 status = | |
280 snd_pcm_plugin_prepare(this->hidden-> | |
281 audio_handle, | |
282 SND_PCM_CHANNEL_PLAYBACK); | |
283 } else { | |
284 status = | |
285 snd_pcm_plugin_prepare(this->hidden-> | |
286 audio_handle, | |
287 SND_PCM_CHANNEL_CAPTURE); | |
288 } | |
289 if (status < 0) { | |
290 QSA_SetError("snd_pcm_plugin_prepare", status); | |
291 return; | |
292 } | |
293 } | |
294 continue; | |
295 } else { | |
296 return; | |
297 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
298 } |
3139 | 299 } else { |
300 /* we wrote all remaining data */ | |
301 towrite -= written; | |
302 pcmbuffer += written * this->spec.channels; | |
303 } | |
304 } while ((towrite > 0) && (this->enabled)); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
305 |
3139 | 306 /* If we couldn't write, assume fatal error for now */ |
307 if (towrite != 0) { | |
308 this->enabled = 0; | |
309 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
310 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
311 |
3139 | 312 static Uint8 * |
313 QSA_GetDeviceBuf(_THIS) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
314 { |
3139 | 315 return this->hidden->pcm_buf; |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
316 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
317 |
3139 | 318 static void |
319 QSA_CloseDevice(_THIS) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
320 { |
3139 | 321 if (this->hidden != NULL) { |
322 if (this->hidden->audio_handle != NULL) { | |
323 if (!this->hidden->iscapture) { | |
324 /* Finish playing available samples */ | |
325 snd_pcm_plugin_flush(this->hidden->audio_handle, | |
326 SND_PCM_CHANNEL_PLAYBACK); | |
327 } else { | |
328 /* Cancel unread samples during capture */ | |
329 snd_pcm_plugin_flush(this->hidden->audio_handle, | |
330 SND_PCM_CHANNEL_CAPTURE); | |
331 } | |
332 snd_pcm_close(this->hidden->audio_handle); | |
333 this->hidden->audio_handle = NULL; | |
334 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
335 |
3139 | 336 if (this->hidden->pcm_buf != NULL) { |
337 SDL_FreeAudioMem(this->hidden->pcm_buf); | |
338 this->hidden->pcm_buf = NULL; | |
339 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
340 |
3139 | 341 SDL_free(this->hidden); |
342 this->hidden = NULL; | |
343 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
344 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
345 |
3139 | 346 static int |
347 QSA_OpenDevice(_THIS, const char *devname, int iscapture) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
348 { |
3139 | 349 int status = 0; |
350 int format = 0; | |
351 SDL_AudioFormat test_format = 0; | |
352 int found = 0; | |
353 snd_pcm_channel_setup_t csetup; | |
354 snd_pcm_channel_params_t cparams; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
355 |
3139 | 356 /* Initialize all variables that we clean on shutdown */ |
357 this->hidden = | |
358 (struct SDL_PrivateAudioData *) SDL_calloc(1, | |
359 (sizeof | |
360 (struct | |
361 SDL_PrivateAudioData))); | |
362 if (this->hidden == NULL) { | |
363 SDL_OutOfMemory(); | |
364 return 0; | |
365 } | |
366 SDL_memset(this->hidden, 0, sizeof(struct SDL_PrivateAudioData)); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
367 |
3139 | 368 /* Initialize channel transfer parameters to default */ |
369 QSA_InitAudioParams(&cparams); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
370 |
3139 | 371 /* Initialize channel direction: capture or playback */ |
372 this->hidden->iscapture = iscapture; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
373 |
3139 | 374 /* Find deviceid and cardid by device name for playback */ |
375 if ((!this->hidden->iscapture) && (devname != NULL)) { | |
376 uint32_t device; | |
377 int32_t status; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
378 |
3139 | 379 /* Search in the playback devices */ |
380 device = 0; | |
381 do { | |
382 status = SDL_strcmp(qsa_playback_device[device].name, devname); | |
383 if (status == 0) { | |
384 /* Found requested device */ | |
385 this->hidden->deviceno = qsa_playback_device[device].deviceno; | |
386 this->hidden->cardno = qsa_playback_device[device].cardno; | |
387 break; | |
388 } | |
389 device++; | |
390 if (device >= qsa_playback_devices) { | |
391 QSA_CloseDevice(this); | |
392 SDL_SetError("No such playback device"); | |
393 return 0; | |
394 } | |
395 } while (1); | |
396 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
397 |
3139 | 398 /* Find deviceid and cardid by device name for capture */ |
399 if ((this->hidden->iscapture) && (devname != NULL)) { | |
400 /* Search in the capture devices */ | |
401 uint32_t device; | |
402 int32_t status; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
403 |
3139 | 404 /* Searching in the playback devices */ |
405 device = 0; | |
406 do { | |
407 status = SDL_strcmp(qsa_capture_device[device].name, devname); | |
408 if (status == 0) { | |
409 /* Found requested device */ | |
410 this->hidden->deviceno = qsa_capture_device[device].deviceno; | |
411 this->hidden->cardno = qsa_capture_device[device].cardno; | |
412 break; | |
413 } | |
414 device++; | |
415 if (device >= qsa_capture_devices) { | |
416 QSA_CloseDevice(this); | |
417 SDL_SetError("No such capture device"); | |
418 return 0; | |
419 } | |
420 } while (1); | |
421 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
422 |
3139 | 423 /* Check if SDL requested default audio device */ |
424 if (devname == NULL) { | |
425 /* Open system default audio device */ | |
426 if (!this->hidden->iscapture) { | |
427 status = snd_pcm_open_preferred(&this->hidden->audio_handle, | |
428 &this->hidden->cardno, | |
429 &this->hidden->deviceno, | |
430 SND_PCM_OPEN_PLAYBACK); | |
431 } else { | |
432 status = snd_pcm_open_preferred(&this->hidden->audio_handle, | |
433 &this->hidden->cardno, | |
434 &this->hidden->deviceno, | |
435 SND_PCM_OPEN_CAPTURE); | |
436 } | |
437 } else { | |
438 /* Open requested audio device */ | |
439 if (!this->hidden->iscapture) { | |
440 status = | |
441 snd_pcm_open(&this->hidden->audio_handle, | |
442 this->hidden->cardno, this->hidden->deviceno, | |
443 SND_PCM_OPEN_PLAYBACK); | |
444 } else { | |
445 status = | |
446 snd_pcm_open(&this->hidden->audio_handle, | |
447 this->hidden->cardno, this->hidden->deviceno, | |
448 SND_PCM_OPEN_CAPTURE); | |
449 } | |
450 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
451 |
3139 | 452 /* Check if requested device is opened */ |
453 if (status < 0) { | |
454 this->hidden->audio_handle = NULL; | |
455 QSA_CloseDevice(this); | |
456 QSA_SetError("snd_pcm_open", status); | |
457 return 0; | |
458 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
459 |
3139 | 460 if (!QSA_CheckBuggyCards(this, QSA_MMAP_WORKAROUND)) { |
461 /* Disable QSA MMAP plugin for buggy audio drivers */ | |
462 status = | |
463 snd_pcm_plugin_set_disable(this->hidden->audio_handle, | |
464 PLUGIN_DISABLE_MMAP); | |
465 if (status < 0) { | |
466 QSA_CloseDevice(this); | |
467 QSA_SetError("snd_pcm_plugin_set_disable", status); | |
468 return 0; | |
469 } | |
470 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
471 |
3139 | 472 /* Try for a closest match on audio format */ |
473 format = 0; | |
474 /* can't use format as SND_PCM_SFMT_U8 = 0 in qsa */ | |
475 found = 0; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
476 |
3139 | 477 for (test_format = SDL_FirstAudioFormat(this->spec.format); !found;) { |
478 /* if match found set format to equivalent QSA format */ | |
479 switch (test_format) { | |
480 case AUDIO_U8: | |
481 { | |
482 format = SND_PCM_SFMT_U8; | |
483 found = 1; | |
484 } | |
485 break; | |
486 case AUDIO_S8: | |
487 { | |
488 format = SND_PCM_SFMT_S8; | |
489 found = 1; | |
490 } | |
491 break; | |
492 case AUDIO_S16LSB: | |
493 { | |
494 format = SND_PCM_SFMT_S16_LE; | |
495 found = 1; | |
496 } | |
497 break; | |
498 case AUDIO_S16MSB: | |
499 { | |
500 format = SND_PCM_SFMT_S16_BE; | |
501 found = 1; | |
502 } | |
503 break; | |
504 case AUDIO_U16LSB: | |
505 { | |
506 format = SND_PCM_SFMT_U16_LE; | |
507 found = 1; | |
508 } | |
509 break; | |
510 case AUDIO_U16MSB: | |
511 { | |
512 format = SND_PCM_SFMT_U16_BE; | |
513 found = 1; | |
514 } | |
515 break; | |
516 case AUDIO_S32LSB: | |
517 { | |
518 format = SND_PCM_SFMT_S32_LE; | |
519 found = 1; | |
520 } | |
521 break; | |
522 case AUDIO_S32MSB: | |
523 { | |
524 format = SND_PCM_SFMT_S32_BE; | |
525 found = 1; | |
526 } | |
527 break; | |
528 case AUDIO_F32LSB: | |
529 { | |
530 format = SND_PCM_SFMT_FLOAT_LE; | |
531 found = 1; | |
532 } | |
533 break; | |
534 case AUDIO_F32MSB: | |
535 { | |
536 format = SND_PCM_SFMT_FLOAT_BE; | |
537 found = 1; | |
538 } | |
539 break; | |
540 default: | |
541 { | |
542 break; | |
543 } | |
544 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
545 |
3139 | 546 if (!found) { |
547 test_format = SDL_NextAudioFormat(); | |
548 } | |
549 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
550 |
3139 | 551 /* assumes test_format not 0 on success */ |
552 if (test_format == 0) { | |
553 QSA_CloseDevice(this); | |
554 SDL_SetError("QSA: Couldn't find any hardware audio formats"); | |
555 return 0; | |
556 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
557 |
3139 | 558 this->spec.format = test_format; |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
559 |
3139 | 560 /* Set the audio format */ |
561 cparams.format.format = format; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
562 |
3139 | 563 /* Set mono/stereo/4ch/6ch/8ch audio */ |
564 cparams.format.voices = this->spec.channels; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
565 |
3139 | 566 /* Set rate */ |
567 cparams.format.rate = this->spec.freq; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
568 |
3139 | 569 /* Setup the transfer parameters according to cparams */ |
570 status = snd_pcm_plugin_params(this->hidden->audio_handle, &cparams); | |
571 if (status < 0) { | |
572 QSA_CloseDevice(this); | |
573 QSA_SetError("snd_pcm_channel_params", status); | |
574 return 0; | |
575 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
576 |
3139 | 577 /* Make sure channel is setup right one last time */ |
578 SDL_memset(&csetup, '\0', sizeof(csetup)); | |
579 if (!this->hidden->iscapture) { | |
580 csetup.channel = SND_PCM_CHANNEL_PLAYBACK; | |
581 } else { | |
582 csetup.channel = SND_PCM_CHANNEL_CAPTURE; | |
583 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
584 |
3139 | 585 /* Setup an audio channel */ |
586 if (snd_pcm_plugin_setup(this->hidden->audio_handle, &csetup) < 0) { | |
587 QSA_CloseDevice(this); | |
588 SDL_SetError("QSA: Unable to setup channel\n"); | |
589 return 0; | |
590 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
591 |
3139 | 592 /* Calculate the final parameters for this audio specification */ |
593 SDL_CalculateAudioSpec(&this->spec); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
594 |
3139 | 595 this->hidden->pcm_len = this->spec.size; |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
596 |
3139 | 597 if (this->hidden->pcm_len == 0) { |
598 this->hidden->pcm_len = | |
599 csetup.buf.block.frag_size * this->spec.channels * | |
600 (snd_pcm_format_width(format) / 8); | |
601 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
602 |
3139 | 603 /* |
604 * Allocate memory to the audio buffer and initialize with silence | |
605 * (Note that buffer size must be a multiple of fragment size, so find | |
606 * closest multiple) | |
607 */ | |
608 this->hidden->pcm_buf = | |
609 (Uint8 *) SDL_AllocAudioMem(this->hidden->pcm_len); | |
610 if (this->hidden->pcm_buf == NULL) { | |
611 QSA_CloseDevice(this); | |
612 SDL_OutOfMemory(); | |
613 return 0; | |
614 } | |
615 SDL_memset(this->hidden->pcm_buf, this->spec.silence, | |
616 this->hidden->pcm_len); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
617 |
3139 | 618 /* get the file descriptor */ |
619 if (!this->hidden->iscapture) { | |
620 this->hidden->audio_fd = | |
621 snd_pcm_file_descriptor(this->hidden->audio_handle, | |
622 SND_PCM_CHANNEL_PLAYBACK); | |
623 } else { | |
624 this->hidden->audio_fd = | |
625 snd_pcm_file_descriptor(this->hidden->audio_handle, | |
626 SND_PCM_CHANNEL_CAPTURE); | |
627 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
628 |
3139 | 629 if (this->hidden->audio_fd < 0) { |
630 QSA_CloseDevice(this); | |
631 QSA_SetError("snd_pcm_file_descriptor", status); | |
632 return 0; | |
633 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
634 |
3139 | 635 /* Prepare an audio channel */ |
636 if (!this->hidden->iscapture) { | |
637 /* Prepare audio playback */ | |
638 status = | |
639 snd_pcm_plugin_prepare(this->hidden->audio_handle, | |
640 SND_PCM_CHANNEL_PLAYBACK); | |
641 } else { | |
642 /* Prepare audio capture */ | |
643 status = | |
644 snd_pcm_plugin_prepare(this->hidden->audio_handle, | |
645 SND_PCM_CHANNEL_CAPTURE); | |
646 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
647 |
3139 | 648 if (status < 0) { |
649 QSA_CloseDevice(this); | |
650 QSA_SetError("snd_pcm_plugin_prepare", status); | |
651 return 0; | |
652 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
653 |
3139 | 654 /* We're really ready to rock and roll. :-) */ |
655 return 1; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
656 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
657 |
3139 | 658 int |
659 QSA_DetectDevices(int iscapture) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
660 { |
3139 | 661 uint32_t it; |
662 uint32_t cards; | |
663 uint32_t devices; | |
664 int32_t status; | |
665 | |
666 /* Detect amount of available devices */ | |
667 /* this value can be changed in the runtime */ | |
668 cards = snd_cards(); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
669 |
3139 | 670 /* If io-audio manager is not running we will get 0 as number */ |
671 /* of available audio devices */ | |
672 if (cards == 0) { | |
673 /* We have no any available audio devices */ | |
674 return 0; | |
675 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
676 |
3139 | 677 /* Find requested devices by type */ |
678 if (!iscapture) { | |
679 /* Playback devices enumeration requested */ | |
680 for (it = 0; it < cards; it++) { | |
681 devices = 0; | |
682 do { | |
683 status = | |
684 snd_card_get_longname(it, | |
685 qsa_playback_device | |
686 [qsa_playback_devices].name, | |
687 QSA_MAX_NAME_LENGTH); | |
688 if (status == EOK) { | |
689 snd_pcm_t *handle; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
690 |
3139 | 691 /* Add device number to device name */ |
692 sprintf(qsa_playback_device[qsa_playback_devices].name + | |
693 SDL_strlen(qsa_playback_device | |
694 [qsa_playback_devices].name), " d%d", | |
695 devices); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
696 |
3139 | 697 /* Store associated card number id */ |
698 qsa_playback_device[qsa_playback_devices].cardno = it; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
699 |
3139 | 700 /* Check if this device id could play anything */ |
701 status = | |
702 snd_pcm_open(&handle, it, devices, | |
703 SND_PCM_OPEN_PLAYBACK); | |
704 if (status == EOK) { | |
705 qsa_playback_device[qsa_playback_devices].deviceno = | |
706 devices; | |
707 status = snd_pcm_close(handle); | |
708 if (status == EOK) { | |
709 qsa_playback_devices++; | |
710 } | |
711 } else { | |
712 /* Check if we got end of devices list */ | |
713 if (status == -ENOENT) { | |
714 break; | |
715 } | |
716 } | |
717 } else { | |
718 break; | |
719 } | |
720 | |
721 /* Check if we reached maximum devices count */ | |
722 if (qsa_playback_devices >= QSA_MAX_DEVICES) { | |
723 break; | |
724 } | |
725 devices++; | |
726 } while (1); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
727 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
728 /* Check if we reached maximum devices count */ |
3139 | 729 if (qsa_playback_devices >= QSA_MAX_DEVICES) { |
730 break; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
731 } |
3139 | 732 } |
733 } else { | |
734 /* Capture devices enumeration requested */ | |
735 for (it = 0; it < cards; it++) { | |
736 devices = 0; | |
737 do { | |
738 status = | |
739 snd_card_get_longname(it, | |
740 qsa_capture_device | |
741 [qsa_capture_devices].name, | |
742 QSA_MAX_NAME_LENGTH); | |
743 if (status == EOK) { | |
744 snd_pcm_t *handle; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
745 |
3139 | 746 /* Add device number to device name */ |
747 sprintf(qsa_capture_device[qsa_capture_devices].name + | |
748 SDL_strlen(qsa_capture_device | |
749 [qsa_capture_devices].name), " d%d", | |
750 devices); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
751 |
3139 | 752 /* Store associated card number id */ |
753 qsa_capture_device[qsa_capture_devices].cardno = it; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
754 |
3139 | 755 /* Check if this device id could play anything */ |
756 status = | |
757 snd_pcm_open(&handle, it, devices, | |
758 SND_PCM_OPEN_CAPTURE); | |
759 if (status == EOK) { | |
760 qsa_capture_device[qsa_capture_devices].deviceno = | |
761 devices; | |
762 status = snd_pcm_close(handle); | |
763 if (status == EOK) { | |
764 qsa_capture_devices++; | |
765 } | |
766 } else { | |
767 /* Check if we got end of devices list */ | |
768 if (status == -ENOENT) { | |
769 break; | |
770 } | |
771 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
772 |
3139 | 773 /* Check if we reached maximum devices count */ |
774 if (qsa_capture_devices >= QSA_MAX_DEVICES) { | |
775 break; | |
776 } | |
777 } else { | |
778 break; | |
779 } | |
780 devices++; | |
781 } while (1); | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
782 |
3139 | 783 /* Check if we reached maximum devices count */ |
784 if (qsa_capture_devices >= QSA_MAX_DEVICES) { | |
785 break; | |
786 } | |
787 } | |
788 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
789 |
3139 | 790 /* Return amount of available playback or capture devices */ |
791 if (!iscapture) { | |
792 return qsa_playback_devices; | |
793 } else { | |
794 return qsa_capture_devices; | |
795 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
796 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
797 |
3139 | 798 const char * |
799 QSA_GetDeviceName(int index, int iscapture) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
800 { |
3139 | 801 if (!iscapture) { |
802 if (index >= qsa_playback_devices) { | |
803 return "No such playback device"; | |
804 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
805 |
3139 | 806 return qsa_playback_device[index].name; |
807 } else { | |
808 if (index >= qsa_capture_devices) { | |
809 return "No such capture device"; | |
810 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
811 |
3139 | 812 return qsa_capture_device[index].name; |
813 } | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
814 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
815 |
3139 | 816 void |
817 QSA_WaitDone(_THIS) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
818 { |
3139 | 819 if (!this->hidden->iscapture) { |
820 if (this->hidden->audio_handle != NULL) { | |
821 /* Wait till last fragment is played and stop channel */ | |
822 snd_pcm_plugin_flush(this->hidden->audio_handle, | |
823 SND_PCM_CHANNEL_PLAYBACK); | |
824 } | |
825 } else { | |
826 if (this->hidden->audio_handle != NULL) { | |
827 /* Discard all unread data and stop channel */ | |
828 snd_pcm_plugin_flush(this->hidden->audio_handle, | |
829 SND_PCM_CHANNEL_CAPTURE); | |
830 } | |
831 } | |
832 } | |
833 | |
834 void | |
835 QSA_Deinitialize(void) | |
836 { | |
837 /* Clear devices array on shutdown */ | |
838 SDL_memset(qsa_playback_device, 0x00, | |
839 sizeof(QSA_Device) * QSA_MAX_DEVICES); | |
840 SDL_memset(qsa_capture_device, 0x00, | |
841 sizeof(QSA_Device) * QSA_MAX_DEVICES); | |
842 qsa_playback_devices = 0; | |
843 qsa_capture_devices = 0; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
844 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
845 |
3139 | 846 static int |
847 QSA_Init(SDL_AudioDriverImpl * impl) | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
848 { |
3139 | 849 snd_pcm_t *handle = NULL; |
850 int32_t status = 0; | |
851 | |
852 /* Clear devices array */ | |
853 SDL_memset(qsa_playback_device, 0x00, | |
854 sizeof(QSA_Device) * QSA_MAX_DEVICES); | |
855 SDL_memset(qsa_capture_device, 0x00, | |
856 sizeof(QSA_Device) * QSA_MAX_DEVICES); | |
857 qsa_playback_devices = 0; | |
858 qsa_capture_devices = 0; | |
859 | |
860 /* Set function pointers */ | |
861 /* DeviceLock and DeviceUnlock functions are used default, */ | |
862 /* provided by SDL, which uses pthread_mutex for lock/unlock */ | |
863 impl->DetectDevices = QSA_DetectDevices; | |
864 impl->GetDeviceName = QSA_GetDeviceName; | |
865 impl->OpenDevice = QSA_OpenDevice; | |
866 impl->ThreadInit = QSA_ThreadInit; | |
867 impl->WaitDevice = QSA_WaitDevice; | |
868 impl->PlayDevice = QSA_PlayDevice; | |
869 impl->GetDeviceBuf = QSA_GetDeviceBuf; | |
870 impl->CloseDevice = QSA_CloseDevice; | |
871 impl->WaitDone = QSA_WaitDone; | |
872 impl->Deinitialize = QSA_Deinitialize; | |
873 impl->LockDevice = NULL; | |
874 impl->UnlockDevice = NULL; | |
875 | |
876 impl->OnlyHasDefaultOutputDevice = 0; | |
877 impl->ProvidesOwnCallbackThread = 0; | |
878 impl->SkipMixerLock = 0; | |
879 impl->HasCaptureSupport = 1; | |
880 impl->OnlyHasDefaultOutputDevice = 0; | |
881 impl->OnlyHasDefaultInputDevice = 0; | |
882 | |
883 /* Check if io-audio manager is running or not */ | |
884 status = snd_cards(); | |
885 if (status == 0) { | |
886 /* if no, return immediately */ | |
887 return 1; | |
888 } | |
889 | |
890 /* At this point we are definitely has an audio device */ | |
891 return 2; | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
892 } |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
893 |
3139 | 894 AudioBootStrap QSAAUDIO_bootstrap = { |
895 DRIVER_NAME, "QNX QSA Audio", QSA_Init, 0 | |
3099
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
896 }; |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
897 |
82e60908fab1
Date: Mon, 23 Mar 2009 09:17:24 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
diff
changeset
|
898 /* vi: set ts=4 sw=4 expandtab: */ |