blob: d0ce4a1a2b781616c7b1d018c0eba07bb85b3a2f [file] [log] [blame]
Benny Prijono8eeab0b2009-03-04 19:00:28 +00001/* $Id$ */
2/*
3 * Copyright (C) 2008-2009 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{
Benny Prijono64f91382009-03-05 18:02:28 +000049 PJ_BUILD_ERR( PJMEDIA_EAUD_ERR, "Unspecified audio device error" ),
Benny Prijono8eeab0b2009-03-04 19:00:28 +000050 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" ),
Benny Prijono64f91382009-03-05 18:02:28 +000059 PJ_BUILD_ERR( PJMEDIA_EAUD_SAMPFORMAT, "Invalid audio device sample format"),
60 PJ_BUILD_ERR( PJMEDIA_EAUD_BADLATENCY, "Bad audio latency setting")
Benny Prijono8eeab0b2009-03-04 19:00:28 +000061
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
Sauw Ming55a73cd2010-05-17 12:51:06 +000078
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
Benny Prijono8eeab0b2009-03-04 19:00:28 +000094 /* 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, 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 /* Audiodev error */
159 if (statcode >= PJMEDIA_AUDIODEV_ERRNO_START &&
160 statcode < PJMEDIA_AUDIODEV_ERRNO_END)
161 {
162 /* Find the error in the table.
163 * Use binary search!
164 */
165 int first = 0;
166 int n = PJ_ARRAY_SIZE(err_str);
167
168 while (n > 0) {
169 int half = n/2;
170 int mid = first + half;
171
172 if (err_str[mid].code < statcode) {
173 first = mid+1;
174 n -= (half+1);
175 } else if (err_str[mid].code > statcode) {
176 n = half;
177 } else {
178 first = mid;
179 break;
180 }
181 }
182
183
184 if (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {
185 pj_str_t msg;
186
187 msg.ptr = (char*)err_str[first].msg;
188 msg.slen = pj_ansi_strlen(err_str[first].msg);
189
190 errstr.ptr = buf;
191 pj_strncpy_with_null(&errstr, &msg, bufsize);
192 return errstr;
193
194 }
195 }
196#endif /* PJ_HAS_ERROR_STRING */
197
198 /* Error not found. */
199 errstr.ptr = buf;
200 errstr.slen = pj_ansi_snprintf(buf, bufsize,
201 "Unknown pjmedia-audiodev error %d",
202 statcode);
203
204 return errstr;
205}
206