blob: 28522490f8e9fc0ae476e6c96c1044e2ade2bf99 [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
78 /* See if the error comes from PortAudio. */
79#if PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
80 if (statcode >= PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START &&
81 statcode <= PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_END)
82 {
83
84 //int pa_err = statcode - PJMEDIA_ERRNO_FROM_PORTAUDIO(0);
85 int pa_err = PJMEDIA_AUDIODEV_PORTAUDIO_ERRNO_START - statcode;
86 pj_str_t msg;
87
88 msg.ptr = (char*)Pa_GetErrorText(pa_err);
89 msg.slen = pj_ansi_strlen(msg.ptr);
90
91 errstr.ptr = buf;
92 pj_strncpy_with_null(&errstr, &msg, bufsize);
93 return errstr;
94
95 } else
96#endif /* PJMEDIA_SOUND_IMPLEMENTATION */
97
98 /* See if the error comes from WMME */
99#if PJMEDIA_AUDIO_DEV_HAS_WMME
100 if ((statcode >= PJMEDIA_AUDIODEV_WMME_IN_ERROR_START &&
101 statcode < PJMEDIA_AUDIODEV_WMME_IN_ERROR_END) ||
102 (statcode >= PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START &&
103 statcode < PJMEDIA_AUDIODEV_WMME_OUT_ERROR_END))
104 {
105 MMRESULT native_err, mr;
106 MMRESULT (WINAPI *waveGetErrText)(UINT mmrError, LPTSTR pszText, UINT cchText);
107 PJ_DECL_UNICODE_TEMP_BUF(wbuf, 80)
108
109 if (statcode >= PJMEDIA_AUDIODEV_WMME_IN_ERROR_START &&
110 statcode <= PJMEDIA_AUDIODEV_WMME_IN_ERROR_END)
111 {
112 native_err = statcode - PJMEDIA_AUDIODEV_WMME_IN_ERROR_START;
113 waveGetErrText = &waveInGetErrorText;
114 } else {
115 native_err = statcode - PJMEDIA_AUDIODEV_WMME_OUT_ERROR_START;
116 waveGetErrText = &waveOutGetErrorText;
117 }
118
119#if PJ_NATIVE_STRING_IS_UNICODE
120 mr = (*waveGetErrText)(native_err, wbuf, PJ_ARRAY_SIZE(wbuf));
121 if (mr == MMSYSERR_NOERROR) {
122 int len = wcslen(wbuf);
123 pj_unicode_to_ansi(wbuf, len, buf, bufsize);
124 }
125#else
126 mr = (*waveGetErrText)(native_err, buf, bufsize);
127#endif
128
129 if (mr==MMSYSERR_NOERROR) {
130 errstr.ptr = buf;
131 errstr.slen = pj_ansi_strlen(buf);
132 return errstr;
133 } else {
134 pj_ansi_snprintf(buf, bufsize, "MMSYSTEM native error %d",
135 native_err);
136 return pj_str(buf);
137 }
138
139 } else
140#endif
141
142 /* Audiodev error */
143 if (statcode >= PJMEDIA_AUDIODEV_ERRNO_START &&
144 statcode < PJMEDIA_AUDIODEV_ERRNO_END)
145 {
146 /* Find the error in the table.
147 * Use binary search!
148 */
149 int first = 0;
150 int n = PJ_ARRAY_SIZE(err_str);
151
152 while (n > 0) {
153 int half = n/2;
154 int mid = first + half;
155
156 if (err_str[mid].code < statcode) {
157 first = mid+1;
158 n -= (half+1);
159 } else if (err_str[mid].code > statcode) {
160 n = half;
161 } else {
162 first = mid;
163 break;
164 }
165 }
166
167
168 if (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {
169 pj_str_t msg;
170
171 msg.ptr = (char*)err_str[first].msg;
172 msg.slen = pj_ansi_strlen(err_str[first].msg);
173
174 errstr.ptr = buf;
175 pj_strncpy_with_null(&errstr, &msg, bufsize);
176 return errstr;
177
178 }
179 }
180#endif /* PJ_HAS_ERROR_STRING */
181
182 /* Error not found. */
183 errstr.ptr = buf;
184 errstr.slen = pj_ansi_snprintf(buf, bufsize,
185 "Unknown pjmedia-audiodev error %d",
186 statcode);
187
188 return errstr;
189}
190