- Timestamp:
- Feb 22, 2009 12:00:12 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia-audiodev/audiodev.c
r2468 r2469 80 80 unsigned dev_cnt; /* Number of devices */ 81 81 unsigned start_idx; /* Start index in global list */ 82 int rec_dev_idx;/* Default capture device. */ 83 int play_dev_idx;/* Default playback device */ 84 int dev_idx; /* Default device. */ 82 85 }; 83 86 … … 97 100 98 101 102 /* Internal: init driver */ 103 static pj_status_t init_driver(unsigned drv_idx) 104 { 105 struct driver *drv = &aud_subsys.drv[drv_idx]; 106 pjmedia_aud_dev_factory *f; 107 unsigned i, dev_cnt; 108 pj_status_t status; 109 110 /* Create the factory */ 111 f = (*drv->create)(aud_subsys.pf); 112 if (!f) 113 return PJ_EUNKNOWN; 114 115 /* Call factory->init() */ 116 status = f->op->init(f); 117 if (status != PJ_SUCCESS) { 118 f->op->destroy(f); 119 return status; 120 } 121 122 /* Get number of devices */ 123 dev_cnt = f->op->get_dev_count(f); 124 if (dev_cnt + aud_subsys.dev_cnt > MAX_DEVS) { 125 PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because" 126 " there are too many devices", 127 aud_subsys.dev_cnt + dev_cnt - MAX_DEVS)); 128 dev_cnt = MAX_DEVS - aud_subsys.dev_cnt; 129 } 130 if (dev_cnt == 0) { 131 f->op->destroy(f); 132 return PJMEDIA_EAUD_NODEV; 133 } 134 135 /* Fill in default devices */ 136 drv->play_dev_idx = drv->rec_dev_idx = drv->dev_idx = -1; 137 for (i=0; i<dev_cnt; ++i) { 138 pjmedia_aud_dev_info info; 139 140 status = f->op->get_dev_info(f, i, &info); 141 if (status != PJ_SUCCESS) { 142 f->op->destroy(f); 143 return status; 144 } 145 146 if (drv->name[0]=='\0') { 147 /* Set driver name */ 148 pj_ansi_strncpy(drv->name, info.driver, sizeof(drv->name)); 149 drv->name[sizeof(drv->name)-1] = '\0'; 150 } 151 152 if (drv->play_dev_idx < 0 && info.output_count) { 153 /* Set default playback device */ 154 drv->play_dev_idx = i; 155 } 156 if (drv->rec_dev_idx < 0 && info.input_count) { 157 /* Set default capture device */ 158 drv->rec_dev_idx = i; 159 } 160 if (drv->dev_idx < 0 && info.input_count && 161 info.output_count) 162 { 163 /* Set default capture and playback device */ 164 drv->dev_idx = i; 165 } 166 167 if (drv->play_dev_idx >= 0 && drv->rec_dev_idx >= 0 && 168 drv->dev_idx >= 0) 169 { 170 /* Done. */ 171 break; 172 } 173 } 174 175 /* Register the factory */ 176 drv->f = f; 177 drv->f->sys.drv_idx = drv_idx; 178 drv->start_idx = aud_subsys.dev_cnt; 179 drv->dev_cnt = dev_cnt; 180 181 /* Register devices to global list */ 182 for (i=0; i<dev_cnt; ++i) { 183 aud_subsys.dev_list[aud_subsys.dev_cnt++] = MAKE_DEV_ID(drv_idx, i); 184 } 185 186 return PJ_SUCCESS; 187 } 188 189 /* Internal: deinit driver */ 190 static void deinit_driver(unsigned drv_idx) 191 { 192 struct driver *drv = &aud_subsys.drv[drv_idx]; 193 194 if (drv->f) { 195 drv->f->op->destroy(drv->f); 196 drv->f = NULL; 197 } 198 199 drv->dev_cnt = 0; 200 drv->play_dev_idx = drv->rec_dev_idx = drv->dev_idx = -1; 201 } 99 202 100 203 /* API: Initialize the audio subsystem. */ … … 121 224 /* Initialize each factory and build the device ID list */ 122 225 for (i=0; i<aud_subsys.drv_cnt; ++i) { 123 pjmedia_aud_dev_factory *f; 124 pjmedia_aud_dev_info info; 125 unsigned j, dev_cnt; 126 127 /* Create the factory */ 128 f = (*aud_subsys.drv[i].create)(pf); 129 if (!f) 226 status = init_driver(i); 227 if (status != PJ_SUCCESS) { 228 deinit_driver(i); 130 229 continue; 131 132 /* Call factory->init() */ 133 status = f->op->init(f); 134 if (status != PJ_SUCCESS) { 135 f->op->destroy(f); 136 continue; 137 } 138 139 /* Build device list */ 140 dev_cnt = f->op->get_dev_count(f); 141 if (dev_cnt == 0) { 142 f->op->destroy(f); 143 continue; 144 } 145 146 /* Get one device info */ 147 status = f->op->get_dev_info(f, 0, &info); 148 if (status != PJ_SUCCESS) { 149 f->op->destroy(f); 150 continue; 151 } 152 153 /* Register the factory */ 154 aud_subsys.drv[i].f = f; 155 aud_subsys.drv[i].f->internal.id = i; 156 aud_subsys.drv[i].start_idx = aud_subsys.dev_cnt; 157 pj_ansi_strncpy(aud_subsys.drv[i].name, info.driver, 158 sizeof(aud_subsys.drv[i].name)); 159 aud_subsys.drv[i].name[sizeof(aud_subsys.drv[i].name)-1] = '\0'; 160 161 /* Register devices */ 162 if (aud_subsys.dev_cnt + dev_cnt > MAX_DEVS) { 163 PJ_LOG(4,(THIS_FILE, "%d device(s) cannot be registered because" 164 " there are too many sound devices", 165 aud_subsys.dev_cnt + dev_cnt - MAX_DEVS)); 166 dev_cnt = MAX_DEVS - aud_subsys.dev_cnt; 167 } 168 for (j=0; j<dev_cnt; ++j) { 169 aud_subsys.dev_list[aud_subsys.dev_cnt++] = MAKE_DEV_ID(i, j); 170 } 171 172 } 173 174 return aud_subsys.drv_cnt ? PJ_SUCCESS : status; 230 } 231 } 232 233 return aud_subsys.dev_cnt ? PJ_SUCCESS : status; 175 234 } 176 235 … … 195 254 196 255 for (i=0; i<aud_subsys.drv_cnt; ++i) { 197 pjmedia_aud_dev_factory *f = aud_subsys.drv[i].f; 198 199 if (!f) 200 continue; 201 202 f->op->destroy(f); 203 aud_subsys.drv[i].f = NULL; 204 } 205 256 deinit_driver(i); 257 } 258 259 aud_subsys.pf = NULL; 206 260 return PJ_SUCCESS; 207 261 } … … 234 288 { 235 289 return aud_subsys.dev_cnt; 290 } 291 292 /* Internal: convert local index to global device index */ 293 static pj_status_t make_global_index(unsigned drv_idx, 294 pjmedia_aud_dev_index *id) 295 { 296 if (*id < 0) { 297 return PJ_SUCCESS; 298 } 299 300 /* Check that factory still exists */ 301 PJ_ASSERT_RETURN(aud_subsys.drv[drv_idx].f, PJ_EBUG); 302 303 /* Check that device index is valid */ 304 PJ_ASSERT_RETURN(*id>=0 && *id<(int)aud_subsys.drv[drv_idx].dev_cnt, 305 PJ_EBUG); 306 307 *id += aud_subsys.drv[drv_idx].start_idx; 308 return PJ_SUCCESS; 236 309 } 237 310 … … 243 316 int f_id, index; 244 317 245 if (id == PJMEDIA_AUD_DEV_DEFAULT) 246 id = DEFAULT_DEV_ID; 247 248 PJ_ASSERT_RETURN(id>=0 && id<(int)aud_subsys.dev_cnt, 249 PJMEDIA_EAUD_INVDEV); 318 if (id < 0) { 319 unsigned i; 320 321 if (id == PJMEDIA_AUD_INVALID_DEV) 322 return PJMEDIA_EAUD_INVDEV; 323 324 for (i=0; i<aud_subsys.drv_cnt; ++i) { 325 struct driver *drv = &aud_subsys.drv[i]; 326 if (drv->dev_idx >= 0) { 327 id = drv->dev_idx; 328 make_global_index(i, &id); 329 break; 330 } else if (id==PJMEDIA_AUD_DEFAULT_CAPTURE_DEV && 331 drv->rec_dev_idx >= 0) 332 { 333 id = drv->rec_dev_idx; 334 make_global_index(i, &id); 335 break; 336 } else if (id==PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV && 337 drv->play_dev_idx >= 0) 338 { 339 id = drv->play_dev_idx; 340 make_global_index(i, &id); 341 break; 342 } 343 } 344 345 if (id < 0) { 346 return PJMEDIA_EAUD_NODEFDEV; 347 } 348 } 250 349 251 350 f_id = GET_FID(aud_subsys.dev_list[id]); … … 263 362 return PJ_SUCCESS; 264 363 265 }266 267 /* Internal: convert local index to global device index */268 static pj_status_t make_global_index(pjmedia_aud_dev_factory *f,269 pjmedia_aud_dev_index *id)270 {271 unsigned f_id = f->internal.id;272 273 if (*id == PJMEDIA_AUD_DEV_DEFAULT)274 return PJ_SUCCESS;275 276 /* Check that factory still exists */277 PJ_ASSERT_RETURN(f, PJ_EBUG);278 279 /* Check that device index is valid */280 PJ_ASSERT_RETURN(*id>=0 && *id<(int)aud_subsys.drv[f_id].dev_cnt, PJ_EBUG);281 282 *id += aud_subsys.drv[f_id].start_idx;283 return PJ_SUCCESS;284 364 } 285 365 … … 292 372 pj_status_t status; 293 373 294 PJ_ASSERT_RETURN(info, PJ_EINVAL); 374 PJ_ASSERT_RETURN(info && id!=PJMEDIA_AUD_INVALID_DEV, PJ_EINVAL); 375 PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT); 295 376 296 377 status = lookup_dev(id, &f, &index); … … 307 388 { 308 389 pjmedia_aud_dev_factory *f = NULL; 309 unsigned i, j;390 unsigned drv_idx, dev_idx; 310 391 311 392 PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL); 312 313 for (i=0; i<aud_subsys.drv_cnt; ++i) { 314 if (!pj_ansi_stricmp(drv_name, aud_subsys.drv[i].name)) { 315 f = aud_subsys.drv[i].f; 393 PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT); 394 395 for (drv_idx=0; drv_idx<aud_subsys.drv_cnt; ++drv_idx) { 396 if (!pj_ansi_stricmp(drv_name, aud_subsys.drv[drv_idx].name)) { 397 f = aud_subsys.drv[drv_idx].f; 316 398 break; 317 399 } … … 321 403 return PJ_ENOTFOUND; 322 404 323 for ( j=0; j<aud_subsys.drv[i].dev_cnt; ++j) {405 for (dev_idx=0; dev_idx<aud_subsys.drv[drv_idx].dev_cnt; ++dev_idx) { 324 406 pjmedia_aud_dev_info info; 325 407 pj_status_t status; 326 408 327 status = f->op->get_dev_info(f, j, &info);409 status = f->op->get_dev_info(f, dev_idx, &info); 328 410 if (status != PJ_SUCCESS) 329 411 return status; … … 333 415 } 334 416 335 if ( j==aud_subsys.drv[i].dev_cnt)417 if (dev_idx==aud_subsys.drv[drv_idx].dev_cnt) 336 418 return PJ_ENOTFOUND; 337 419 338 *id = j;339 make_global_index( f, id);420 *id = dev_idx; 421 make_global_index(drv_idx, id); 340 422 341 423 return PJ_SUCCESS; … … 352 434 pj_status_t status; 353 435 354 PJ_ASSERT_RETURN(param, PJ_EINVAL); 436 PJ_ASSERT_RETURN(param && id!=PJMEDIA_AUD_INVALID_DEV, PJ_EINVAL); 437 PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT); 355 438 356 439 status = lookup_dev(id, &f, &index); … … 363 446 364 447 /* Normalize device IDs */ 365 make_global_index(f , ¶m->rec_id);366 make_global_index(f , ¶m->play_id);448 make_global_index(f->sys.drv_idx, ¶m->rec_id); 449 make_global_index(f->sys.drv_idx, ¶m->play_id); 367 450 368 451 return PJ_SUCCESS; … … 381 464 382 465 PJ_ASSERT_RETURN(prm && prm->dir && p_aud_strm, PJ_EINVAL); 466 PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT); 383 467 384 468 /* Must make copy of param because we're changing device ID */ … … 389 473 unsigned index; 390 474 475 if (param.rec_id < 0) 476 param.rec_id = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV; 477 391 478 status = lookup_dev(param.rec_id, &rec_f, &index); 392 479 if (status != PJ_SUCCESS) … … 401 488 unsigned index; 402 489 490 if (param.play_id < 0) 491 param.play_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV; 492 403 493 status = lookup_dev(param.play_id, &play_f, &index); 404 494 if (status != PJ_SUCCESS) … … 409 499 410 500 /* For now, rec_id and play_id must belong to the same factory */ 411 PJ_ASSERT_RETURN(rec_f == play_f, PJ _EINVAL);501 PJ_ASSERT_RETURN(rec_f == play_f, PJMEDIA_EAUD_INVDEV); 412 502 } 413 503 … … 420 510 421 511 /* Assign factory id to the stream */ 422 (*p_aud_strm)-> factory_id = f->internal.id;512 (*p_aud_strm)->sys.drv_idx = f->sys.drv_idx; 423 513 return PJ_SUCCESS; 424 514 } … … 430 520 pj_status_t status; 431 521 522 PJ_ASSERT_RETURN(strm && param, PJ_EINVAL); 523 PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT); 524 432 525 status = strm->op->get_param(strm, param); 433 526 if (status != PJ_SUCCESS) … … 435 528 436 529 /* Normalize device id's */ 437 make_global_index( aud_subsys.drv[strm->factory_id].f, ¶m->rec_id);438 make_global_index( aud_subsys.drv[strm->factory_id].f, ¶m->play_id);530 make_global_index(strm->sys.drv_idx, ¶m->rec_id); 531 make_global_index(strm->sys.drv_idx, ¶m->play_id); 439 532 440 533 return PJ_SUCCESS;
Note: See TracChangeset
for help on using the changeset viewer.