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