blob: a928485a14f9940c0eb7a45841768b920c720df1 [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $Id$ */
2/*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <pjmedia-audiodev/errno.h>
20#include <pj/string.h>
21#include <pj/unicode.h>
22#if PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
23# include <portaudio.h>
24#endif
25#if PJMEDIA_AUDIO_DEV_HAS_WMME
26# ifdef _MSC_VER
27# pragma warning(push, 3)
28# endif
29# include <windows.h>
30# include <mmsystem.h>
31# ifdef _MSC_VER
32# pragma warning(pop)
33# endif
34#endif
35
36/* PJMEDIA-Audiodev's own error codes/messages
37 * MUST KEEP THIS ARRAY SORTED!!
38 * Message must be limited to 64 chars!
39 */
40
41#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)
42
43static const struct
44{
45 int code;
46 const char *msg;
47} err_str[] =
48{
49 PJ_BUILD_ERR( PJMEDIA_EAUD_ERR, "Unspecified audio device error" ),
50 PJ_BUILD_ERR( PJMEDIA_EAUD_SYSERR, "Unknown error from audio driver" ),
51 PJ_BUILD_ERR( PJMEDIA_EAUD_INIT, "Audio subsystem not initialized" ),
52 PJ_BUILD_ERR( PJMEDIA_EAUD_INVDEV, "Invalid audio device" ),
53 PJ_BUILD_ERR( PJMEDIA_EAUD_NODEV, "Found no audio devices" ),
54 PJ_BUILD_ERR( PJMEDIA_EAUD_NODEFDEV, "Unable to find default audio device" ),
55 PJ_BUILD_ERR( PJMEDIA_EAUD_NOTREADY, "Audio device not ready" ),
56 PJ_BUILD_ERR( PJMEDIA_EAUD_INVCAP, "Invalid or unsupported audio capability" ),
57 PJ_BUILD_ERR( PJMEDIA_EAUD_INVOP, "Invalid or unsupported audio device operation" ),
58 PJ_BUILD_ERR( PJMEDIA_EAUD_BADFORMAT, "Bad or invalid audio device format" ),
59 PJ_BUILD_ERR( PJMEDIA_EAUD_SAMPFORMAT, "Invalid audio device sample format"),
60 PJ_BUILD_ERR( PJMEDIA_EAUD_BADLATENCY, "Bad audio latency setting")
61
62};
63
64#endif /* PJ_HAS_ERROR_STRING */
65
66
67
68/*
69 * pjmedia_audiodev_strerror()
70 */
71PJ_DEF(pj_str_t) pjmedia_audiodev_strerror(pj_status_t statcode,
72 char *buf, pj_size_t bufsize )
73{
74 pj_str_t errstr;
75
76#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)
77
78
79 /* See if the error comes from Core Audio. */
80#if PJMEDIA_AUDIO_DEV_HAS_COREAUDIO
81 if (statcode >= PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_START &&
82 statcode <= PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_END)
83 {
84 int ca_err = PJMEDIA_AUDIODEV_COREAUDIO_ERRNO_START - statcode;
85
86 PJ_UNUSED_ARG(ca_err);
87 // TODO: create more helpful error messages
88 errstr.ptr = buf;
89 pj_strcpy2(&errstr, "Core audio error");
90 return errstr;
91 } else
92#endif
93
94 /* See if the error comes from PortAudio. */
95#if PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
96 if (statcode >= PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START &&
97 statcode <= PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_END)
98 {
99
100 //int pa_err = statcode - PJMEDIA_ERRNO_FROM_PORTAUDIO(0);
101 int pa_err = PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START - statcode;
102 pj_str_t msg;
103
104 msg.ptr = (char*)Pa_GetErrorText(pa_err);
105 msg.slen = pj_ansi_strlen(msg.ptr);
106
107 errstr.ptr = buf;
108 pj_strncpy_with_null(&errstr, &msg, bufsize);
109 return errstr;
110
111 } else
112#endif /* PJMEDIA_SOUND_IMPLEMENTATION */
113
114 /* See if the error comes from WMME */
115#if PJMEDIA_AUDIO_DEV_HAS_WMME
116 if ((statcode >= PJMEDIA_AUDIODEV_WMME_IN_ERROR_START &&
117 statcode < PJMEDIA_AUDIODEV_WMME_IN_ERROR_END) ||
118 (statcode >= PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START &&
119 statcode < PJMEDIA_AUDIODEV_WMME_OUT_ERROR_END))
120 {
121 MMRESULT native_err, mr;
122 MMRESULT (WINAPI *waveGetErrText)(UINT mmrError, LPTSTR pszText, UINT cchText);
123 PJ_DECL_UNICODE_TEMP_BUF(wbuf, 80)
124
125 if (statcode >= PJMEDIA_AUDIODEV_WMME_IN_ERROR_START &&
126 statcode <= PJMEDIA_AUDIODEV_WMME_IN_ERROR_END)
127 {
128 native_err = statcode - PJMEDIA_AUDIODEV_WMME_IN_ERROR_START;
129 waveGetErrText = &waveInGetErrorText;
130 } else {
131 native_err = statcode - PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START;
132 waveGetErrText = &waveOutGetErrorText;
133 }
134
135#if PJ_NATIVE_STRING_IS_UNICODE
136 mr = (*waveGetErrText)(native_err, wbuf, PJ_ARRAY_SIZE(wbuf));
137 if (mr == MMSYSERR_NOERROR) {
138 int len = wcslen(wbuf);
139 pj_unicode_to_ansi(wbuf, len, buf, bufsize);
140 }
141#else
142 mr = (*waveGetErrText)(native_err, buf, (UINT)bufsize);
143#endif
144
145 if (mr==MMSYSERR_NOERROR) {
146 errstr.ptr = buf;
147 errstr.slen = pj_ansi_strlen(buf);
148 return errstr;
149 } else {
150 pj_ansi_snprintf(buf, bufsize, "MMSYSTEM native error %d",
151 native_err);
152 return pj_str(buf);
153 }
154
155 } else
156#endif
157
158/* See if the error comes from BDIMAD */
159#if PJMEDIA_AUDIO_DEV_HAS_BDIMAD
160
161 if (statcode >= PJMEDIA_AUDIODEV_BDIMAD_ERROR_START &&
162 statcode < PJMEDIA_AUDIODEV_BDIMAD_ERROR_END)
163 {
164 pj_status_t native_err;
165 native_err = statcode - PJMEDIA_AUDIODEV_BDIMAD_ERROR_START;
166
167 pj_ansi_snprintf(buf, bufsize, "BDIMAD native error %d", native_err);
168 return pj_str(buf);
169 } else
170#endif
171
172 /* Audiodev error */
173 if (statcode >= PJMEDIA_AUDIODEV_ERRNO_START &&
174 statcode < PJMEDIA_AUDIODEV_ERRNO_END)
175 {
176 /* Find the error in the table.
177 * Use binary search!
178 */
179 int first = 0;
180 int n = PJ_ARRAY_SIZE(err_str);
181
182 while (n > 0) {
183 int half = n/2;
184 int mid = first + half;
185
186 if (err_str[mid].code < statcode) {
187 first = mid+1;
188 n -= (half+1);
189 } else if (err_str[mid].code > statcode) {
190 n = half;
191 } else {
192 first = mid;
193 break;
194 }
195 }
196
197
198 if (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {
199 pj_str_t msg;
200
201 msg.ptr = (char*)err_str[first].msg;
202 msg.slen = pj_ansi_strlen(err_str[first].msg);
203
204 errstr.ptr = buf;
205 pj_strncpy_with_null(&errstr, &msg, bufsize);
206 return errstr;
207
208 }
209 }
210#endif /* PJ_HAS_ERROR_STRING */
211
212 /* Error not found. */
213 errstr.ptr = buf;
214 errstr.slen = pj_ansi_snprintf(buf, bufsize,
215 "Unknown pjmedia-audiodev error %d",
216 statcode);
217
218 return errstr;
219}
220