1 /* 2 * EchoGals/Echo24 BeOS Driver for Echo audio cards 3 * 4 * Copyright (c) 2003, Jerome Duval (jerome.duval@free.fr) 5 * 6 * Original code : BeOS Driver for Intel ICH AC'97 Link interface 7 * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de> 8 * 9 * All rights reserved. 10 * Redistribution and use in source and binary forms, with or without modification, 11 * are permitted provided that the following conditions are met: 12 * 13 * - Redistributions of source code must retain the above copyright notice, 14 * this list of conditions and the following disclaimer. 15 * - Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 25 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 */ 31 32 #include <OS.h> 33 #include <MediaDefs.h> 34 #include "debug.h" 35 #include "hmulti_audio.h" 36 #include "multi.h" 37 38 //#define DEBUG 1 39 40 #include "echo.h" 41 #include "util.h" 42 43 typedef enum { 44 B_MIX_GAIN = 1 << 0, 45 B_MIX_MUTE = 1 << 1, 46 B_MIX_NOMINAL = 1 << 2 47 } mixer_type; 48 49 static void 50 echo_channel_get_mix(void *card, MIXER_AUDIO_CHANNEL channel, int32 type, float *values) { 51 52 echo_dev *dev = (echo_dev*) card; 53 MIXER_MULTI_FUNCTION multi_function[2]; 54 PMIXER_FUNCTION function = multi_function[0].MixerFunction; 55 INT32 size = ComputeMixerMultiFunctionSize(2); 56 function[0].Channel = channel; 57 function[1].Channel = channel; 58 function[1].Channel.wChannel++; 59 switch (type) { 60 case B_MIX_GAIN: 61 function[0].iFunction = function[1].iFunction = MXF_GET_LEVEL; 62 break; 63 case B_MIX_MUTE: 64 function[0].iFunction = function[1].iFunction = MXF_GET_MUTE; 65 break; 66 case B_MIX_NOMINAL: 67 function[0].iFunction = function[1].iFunction = MXF_GET_NOMINAL; 68 break; 69 } 70 71 multi_function[0].iCount = 2; 72 dev->pEG->ProcessMixerMultiFunction(multi_function, size); 73 74 if (function[0].RtnStatus == ECHOSTATUS_OK) { 75 if (type == B_MIX_GAIN) { 76 values[0] = (float)function[0].Data.iLevel / 256; 77 values[1] = (float)function[1].Data.iLevel / 256; 78 } else if (type == B_MIX_MUTE) { 79 values[0] = function[0].Data.bMuteOn ? 1.0 : 0.0; 80 } else { 81 values[0] = function[0].Data.iNominal == 4 ? 1.0 : 0.0; 82 } 83 PRINT(("echo_channel_get_mix iLevel: %ld, %d, %ld\n", function[0].Data.iLevel, channel.wChannel, channel.dwType)); 84 } 85 86 } 87 88 static void 89 echo_channel_set_mix(void *card, MIXER_AUDIO_CHANNEL channel, int32 type, float *values) { 90 echo_dev *dev = (echo_dev*) card; 91 MIXER_MULTI_FUNCTION multi_function[2]; 92 PMIXER_FUNCTION function = multi_function[0].MixerFunction; 93 INT32 size = ComputeMixerMultiFunctionSize(2); 94 function[0].Channel = channel; 95 function[1].Channel = channel; 96 function[1].Channel.wChannel++; 97 if (type == B_MIX_GAIN) { 98 function[0].Data.iLevel = (int)(values[0] * 256); 99 function[0].iFunction = MXF_SET_LEVEL; 100 function[1].Data.iLevel = (int)(values[1] * 256); 101 function[1].iFunction = MXF_SET_LEVEL; 102 } else if (type == B_MIX_MUTE) { 103 function[0].Data.bMuteOn = values[0] == 1.0; 104 function[0].iFunction = MXF_SET_MUTE; 105 function[1].Data.bMuteOn = values[0] == 1.0; 106 function[1].iFunction = MXF_SET_MUTE; 107 } else { 108 function[0].Data.iNominal = values[0] == 1.0 ? 4 : -10; 109 function[0].iFunction = MXF_SET_NOMINAL; 110 function[1].Data.iNominal = values[0] == 1.0 ? 4 : -10; 111 function[1].iFunction = MXF_SET_NOMINAL; 112 } 113 114 multi_function[0].iCount = 2; 115 dev->pEG->ProcessMixerMultiFunction(multi_function, size); 116 117 if (function[0].RtnStatus == ECHOSTATUS_OK) { 118 PRINT(("echo_channel_set_mix OK: %ld, %d, %ld\n", function[0].Data.iLevel, channel.wChannel, channel.dwType)); 119 } 120 121 } 122 123 124 static int32 125 echo_create_group_control(multi_dev *multi, uint32 *index, int32 parent, 126 enum strind_id string, const char* name) { 127 uint32 i = *index; 128 (*index)++; 129 multi->controls[i].mix_control.id = MULTI_CONTROL_FIRSTID + i; 130 multi->controls[i].mix_control.parent = parent; 131 multi->controls[i].mix_control.flags = B_MULTI_MIX_GROUP; 132 multi->controls[i].mix_control.master = MULTI_CONTROL_MASTERID; 133 multi->controls[i].mix_control.string = string; 134 if(name) 135 strcpy(multi->controls[i].mix_control.name, name); 136 137 return multi->controls[i].mix_control.id; 138 } 139 140 static void 141 echo_create_channel_control(multi_dev *multi, uint32 *index, int32 parent, int32 string, 142 MIXER_AUDIO_CHANNEL channel, bool nominal) { 143 uint32 i = *index, id; 144 multi_mixer_control control; 145 146 control.mix_control.master = MULTI_CONTROL_MASTERID; 147 control.mix_control.parent = parent; 148 control.channel = channel; 149 control.get = &echo_channel_get_mix; 150 control.set = &echo_channel_set_mix; 151 control.mix_control.gain.min_gain = -128; 152 control.mix_control.gain.max_gain = 6; 153 control.mix_control.gain.granularity = 0.5; 154 155 control.mix_control.id = MULTI_CONTROL_FIRSTID + i; 156 control.mix_control.flags = B_MULTI_MIX_ENABLE; 157 control.mix_control.string = S_MUTE; 158 control.type = B_MIX_MUTE; 159 multi->controls[i] = control; 160 i++; 161 162 control.mix_control.id = MULTI_CONTROL_FIRSTID + i; 163 control.mix_control.flags = B_MULTI_MIX_GAIN; 164 control.mix_control.string = S_null; 165 control.type = B_MIX_GAIN; 166 strcpy(control.mix_control.name, "Gain"); 167 multi->controls[i] = control; 168 id = control.mix_control.id; 169 i++; 170 171 // second channel 172 control.mix_control.id = MULTI_CONTROL_FIRSTID + i; 173 control.mix_control.master = id; 174 multi->controls[i] = control; 175 i++; 176 177 // nominal level (+4/-10) 178 if (nominal) { 179 control.mix_control.id = MULTI_CONTROL_FIRSTID + i; 180 control.mix_control.master = MULTI_CONTROL_MASTERID; 181 control.mix_control.flags = B_MULTI_MIX_ENABLE; 182 control.mix_control.string = S_null; 183 control.type = B_MIX_NOMINAL; 184 strcpy(control.mix_control.name, "+4dB"); 185 multi->controls[i] = control; 186 i++; 187 } 188 189 *index = i; 190 } 191 192 193 static status_t 194 echo_create_controls_list(multi_dev *multi) 195 { 196 uint32 i = 0, index = 0, parent, parent2; 197 echo_dev *card = (echo_dev*)multi->card; 198 199 parent = echo_create_group_control(multi, &index, 0, S_OUTPUT, NULL); 200 201 MIXER_AUDIO_CHANNEL channel; 202 channel.wCardId = 0; 203 channel.dwType = ECHO_BUS_OUT; 204 for (i=0; i < card->caps.wNumBussesOut / 2; i++) { 205 channel.wChannel = i * 2; 206 parent2 = echo_create_group_control(multi, &index, parent, S_null, "Output"); 207 208 echo_create_channel_control(multi, &index, parent2, 0, channel, 209 card->caps.dwBusOutCaps[i*2] & ECHOCAPS_NOMINAL_LEVEL); 210 } 211 212 parent = echo_create_group_control(multi, &index, 0, S_INPUT, NULL); 213 214 channel.dwType = ECHO_BUS_IN; 215 for (i=0; i < card->caps.wNumBussesIn / 2; i++) { 216 channel.wChannel = i * 2; 217 218 parent2 = echo_create_group_control(multi, &index, parent, S_null, "Input"); 219 220 echo_create_channel_control(multi, &index, parent2, 0, channel, 221 card->caps.dwBusInCaps[i*2] & ECHOCAPS_NOMINAL_LEVEL); 222 } 223 224 multi->control_count = index; 225 PRINT(("multi->control_count %lu\n", multi->control_count)); 226 return B_OK; 227 } 228 229 static status_t 230 echo_get_mix(echo_dev *card, multi_mix_value_info * MMVI) 231 { 232 int32 i; 233 uint32 id; 234 multi_mixer_control *control = NULL; 235 for(i=0; i<MMVI->item_count; i++) { 236 id = MMVI->values[i].id - MULTI_CONTROL_FIRSTID; 237 if(id < 0 || id >= card->multi.control_count) { 238 PRINT(("echo_get_mix : invalid control id requested : %li\n", id)); 239 continue; 240 } 241 control = &card->multi.controls[id]; 242 243 if(control->mix_control.flags & B_MULTI_MIX_GAIN) { 244 if(control->get) { 245 float values[2]; 246 control->get(card, control->channel, control->type, values); 247 if(control->mix_control.master == MULTI_CONTROL_MASTERID) 248 MMVI->values[i].gain = values[0]; 249 else 250 MMVI->values[i].gain = values[1]; 251 } 252 } 253 254 if(control->mix_control.flags & B_MULTI_MIX_ENABLE && control->get) { 255 float values[1]; 256 control->get(card, control->channel, control->type, values); 257 MMVI->values[i].enable = (values[0] == 1.0); 258 } 259 260 if(control->mix_control.flags & B_MULTI_MIX_MUX && control->get) { 261 float values[1]; 262 control->get(card, control->channel, control->type, values); 263 MMVI->values[i].mux = (int32)values[0]; 264 } 265 } 266 return B_OK; 267 } 268 269 static status_t 270 echo_set_mix(echo_dev *card, multi_mix_value_info * MMVI) 271 { 272 int32 i; 273 uint32 id; 274 multi_mixer_control *control = NULL; 275 for(i=0; i<MMVI->item_count; i++) { 276 id = MMVI->values[i].id - MULTI_CONTROL_FIRSTID; 277 if(id < 0 || id >= card->multi.control_count) { 278 PRINT(("echo_set_mix : invalid control id requested : %li\n", id)); 279 continue; 280 } 281 control = &card->multi.controls[id]; 282 283 if(control->mix_control.flags & B_MULTI_MIX_GAIN) { 284 multi_mixer_control *control2 = NULL; 285 if(i+1<MMVI->item_count) { 286 id = MMVI->values[i + 1].id - MULTI_CONTROL_FIRSTID; 287 if(id < 0 || id >= card->multi.control_count) { 288 PRINT(("echo_set_mix : invalid control id requested : %li\n", id)); 289 } else { 290 control2 = &card->multi.controls[id]; 291 if(control2->mix_control.master != control->mix_control.id) 292 control2 = NULL; 293 } 294 } 295 296 if(control->set) { 297 float values[2]; 298 values[0] = 0.0; 299 values[1] = 0.0; 300 301 if(control->mix_control.master == MULTI_CONTROL_MASTERID) 302 values[0] = MMVI->values[i].gain; 303 else 304 values[1] = MMVI->values[i].gain; 305 306 if(control2 && control2->mix_control.master != MULTI_CONTROL_MASTERID) 307 values[1] = MMVI->values[i+1].gain; 308 309 control->set(card, control->channel, control->type, values); 310 } 311 312 if(control2) 313 i++; 314 } 315 316 if(control->mix_control.flags & B_MULTI_MIX_ENABLE && control->set) { 317 float values[1]; 318 319 values[0] = MMVI->values[i].enable ? 1.0 : 0.0; 320 control->set(card, control->channel, control->type, values); 321 } 322 323 if(control->mix_control.flags & B_MULTI_MIX_MUX && control->set) { 324 float values[1]; 325 326 values[0] = (float)MMVI->values[i].mux; 327 control->set(card, control->channel, control->type, values); 328 } 329 } 330 return B_OK; 331 } 332 333 static status_t 334 echo_list_mix_controls(echo_dev *card, multi_mix_control_info * MMCI) 335 { 336 multi_mix_control *MMC; 337 uint32 i; 338 339 MMC = MMCI->controls; 340 if(MMCI->control_count < 24) 341 return B_ERROR; 342 343 if(echo_create_controls_list(&card->multi) < B_OK) 344 return B_ERROR; 345 for(i=0; i<card->multi.control_count; i++) { 346 MMC[i] = card->multi.controls[i].mix_control; 347 } 348 349 MMCI->control_count = card->multi.control_count; 350 return B_OK; 351 } 352 353 static status_t 354 echo_list_mix_connections(echo_dev *card, multi_mix_connection_info * data) 355 { 356 return B_ERROR; 357 } 358 359 static status_t 360 echo_list_mix_channels(echo_dev *card, multi_mix_channel_info *data) 361 { 362 return B_ERROR; 363 } 364 365 /*multi_channel_info chans[] = { 366 { 0, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 367 { 1, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 368 { 2, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 369 { 3, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 370 { 4, B_MULTI_INPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 371 { 5, B_MULTI_INPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 372 { 6, B_MULTI_INPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 373 { 7, B_MULTI_INPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 374 { 8, B_MULTI_OUTPUT_BUS, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 375 { 9, B_MULTI_OUTPUT_BUS, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 376 { 10, B_MULTI_INPUT_BUS, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 377 { 11, B_MULTI_INPUT_BUS, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 378 };*/ 379 380 /*multi_channel_info chans[] = { 381 { 0, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 382 { 1, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 383 { 2, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_SURROUND_BUS, 0 }, 384 { 3, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_SURROUND_BUS, 0 }, 385 { 4, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_REARLEFT | B_CHANNEL_SURROUND_BUS, 0 }, 386 { 5, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_REARRIGHT | B_CHANNEL_SURROUND_BUS, 0 }, 387 { 6, B_MULTI_INPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 388 { 7, B_MULTI_INPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 389 { 8, B_MULTI_INPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 390 { 9, B_MULTI_INPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 391 { 10, B_MULTI_OUTPUT_BUS, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 392 { 11, B_MULTI_OUTPUT_BUS, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 393 { 12, B_MULTI_INPUT_BUS, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 394 { 13, B_MULTI_INPUT_BUS, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 395 };*/ 396 397 398 static void 399 echo_create_channels_list(multi_dev *multi) 400 { 401 echo_stream *stream; 402 int32 mode; 403 uint32 index, i, designations; 404 multi_channel_info *chans; 405 uint32 chan_designations[] = { 406 B_CHANNEL_LEFT, 407 B_CHANNEL_RIGHT, 408 B_CHANNEL_REARLEFT, 409 B_CHANNEL_REARRIGHT, 410 B_CHANNEL_CENTER, 411 B_CHANNEL_SUB 412 }; 413 414 chans = multi->chans; 415 index = 0; 416 417 for(mode=ECHO_USE_PLAY; mode!=-1; 418 mode = (mode == ECHO_USE_PLAY) ? ECHO_USE_RECORD : -1) { 419 LIST_FOREACH(stream, &((echo_dev*)multi->card)->streams, next) { 420 if ((stream->use & mode) == 0) 421 continue; 422 423 if(stream->channels == 2) 424 designations = B_CHANNEL_STEREO_BUS; 425 else 426 designations = B_CHANNEL_SURROUND_BUS; 427 428 for(i=0; i<stream->channels; i++) { 429 chans[index].channel_id = index; 430 chans[index].kind = (mode == ECHO_USE_PLAY) ? B_MULTI_OUTPUT_CHANNEL : B_MULTI_INPUT_CHANNEL; 431 chans[index].designations = designations | chan_designations[i]; 432 chans[index].connectors = 0; 433 index++; 434 } 435 } 436 437 if(mode==ECHO_USE_PLAY) { 438 multi->output_channel_count = index; 439 } else { 440 multi->input_channel_count = index - multi->output_channel_count; 441 } 442 } 443 444 chans[index].channel_id = index; 445 chans[index].kind = B_MULTI_OUTPUT_BUS; 446 chans[index].designations = B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS; 447 chans[index].connectors = B_CHANNEL_MINI_JACK_STEREO; 448 index++; 449 450 chans[index].channel_id = index; 451 chans[index].kind = B_MULTI_OUTPUT_BUS; 452 chans[index].designations = B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS; 453 chans[index].connectors = B_CHANNEL_MINI_JACK_STEREO; 454 index++; 455 456 multi->output_bus_channel_count = index - multi->output_channel_count 457 - multi->input_channel_count; 458 459 chans[index].channel_id = index; 460 chans[index].kind = B_MULTI_INPUT_BUS; 461 chans[index].designations = B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS; 462 chans[index].connectors = B_CHANNEL_MINI_JACK_STEREO; 463 index++; 464 465 chans[index].channel_id = index; 466 chans[index].kind = B_MULTI_INPUT_BUS; 467 chans[index].designations = B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS; 468 chans[index].connectors = B_CHANNEL_MINI_JACK_STEREO; 469 index++; 470 471 multi->input_bus_channel_count = index - multi->output_channel_count 472 - multi->input_channel_count - multi->output_bus_channel_count; 473 474 multi->aux_bus_channel_count = 0; 475 } 476 477 478 static status_t 479 echo_get_description(echo_dev *card, multi_description *data) 480 { 481 int32 size; 482 483 data->interface_version = B_CURRENT_INTERFACE_VERSION; 484 data->interface_minimum = B_CURRENT_INTERFACE_VERSION; 485 486 strncpy(data->friendly_name, card->caps.szName, 32); 487 strcpy(data->vendor_info, AUTHOR); 488 489 data->output_channel_count = card->multi.output_channel_count; 490 data->input_channel_count = card->multi.input_channel_count; 491 data->output_bus_channel_count = card->multi.output_bus_channel_count; 492 data->input_bus_channel_count = card->multi.input_bus_channel_count; 493 data->aux_bus_channel_count = card->multi.aux_bus_channel_count; 494 495 size = card->multi.output_channel_count + card->multi.input_channel_count 496 + card->multi.output_bus_channel_count + card->multi.input_bus_channel_count 497 + card->multi.aux_bus_channel_count; 498 499 // for each channel, starting with the first output channel, 500 // then the second, third..., followed by the first input 501 // channel, second, third, ..., followed by output bus 502 // channels and input bus channels and finally auxillary channels, 503 504 LOG(("request_channel_count = %d\n",data->request_channel_count)); 505 if (data->request_channel_count >= size) { 506 LOG(("copying data\n")); 507 memcpy(data->channels, card->multi.chans, size * sizeof(card->multi.chans[0])); 508 } 509 510 switch (current_settings.sample_rate) { 511 case 192000: data->output_rates = data->input_rates = B_SR_192000; break; 512 case 96000: data->output_rates = data->input_rates = B_SR_96000; break; 513 case 48000: data->output_rates = data->input_rates = B_SR_48000; break; 514 case 44100: data->output_rates = data->input_rates = B_SR_44100; break; 515 } 516 data->min_cvsr_rate = 0; 517 data->max_cvsr_rate = 48000; 518 519 switch (current_settings.bitsPerSample) { 520 case 8: data->output_formats = data->input_formats = B_FMT_8BIT_U; break; 521 case 16: data->output_formats = data->input_formats = B_FMT_16BIT; break; 522 case 24: data->output_formats = data->input_formats = B_FMT_24BIT; break; 523 case 32: data->output_formats = data->input_formats = B_FMT_32BIT; break; 524 } 525 data->lock_sources = B_MULTI_LOCK_INTERNAL; 526 data->timecode_sources = 0; 527 data->interface_flags = B_MULTI_INTERFACE_PLAYBACK | B_MULTI_INTERFACE_RECORD; 528 data->start_latency = 3000; 529 530 strcpy(data->control_panel,""); 531 532 return B_OK; 533 } 534 535 static status_t 536 echo_get_enabled_channels(echo_dev *card, multi_channel_enable *data) 537 { 538 B_SET_CHANNEL(data->enable_bits, 0, true); 539 B_SET_CHANNEL(data->enable_bits, 1, true); 540 B_SET_CHANNEL(data->enable_bits, 2, true); 541 B_SET_CHANNEL(data->enable_bits, 3, true); 542 data->lock_source = B_MULTI_LOCK_INTERNAL; 543 /* 544 uint32 lock_source; 545 int32 lock_data; 546 uint32 timecode_source; 547 uint32 * connectors; 548 */ 549 return B_OK; 550 } 551 552 static status_t 553 echo_set_enabled_channels(echo_dev *card, multi_channel_enable *data) 554 { 555 PRINT(("set_enabled_channels 0 : %s\n", B_TEST_CHANNEL(data->enable_bits, 0) ? "enabled": "disabled")); 556 PRINT(("set_enabled_channels 1 : %s\n", B_TEST_CHANNEL(data->enable_bits, 1) ? "enabled": "disabled")); 557 PRINT(("set_enabled_channels 2 : %s\n", B_TEST_CHANNEL(data->enable_bits, 2) ? "enabled": "disabled")); 558 PRINT(("set_enabled_channels 3 : %s\n", B_TEST_CHANNEL(data->enable_bits, 3) ? "enabled": "disabled")); 559 return B_OK; 560 } 561 562 static status_t 563 echo_get_global_format(echo_dev *card, multi_format_info *data) 564 { 565 data->output_latency = 0; 566 data->input_latency = 0; 567 data->timecode_kind = 0; 568 switch (current_settings.sample_rate) { 569 case 192000: data->output.rate = data->input.rate = B_SR_192000; break; 570 case 96000: data->output.rate = data->input.rate = B_SR_96000; break; 571 case 48000: data->output.rate = data->input.rate = B_SR_48000; break; 572 case 44100: data->output.rate = data->input.rate = B_SR_44100; break; 573 } 574 switch (current_settings.bitsPerSample) { 575 case 8: data->input.format = data->output.format = B_FMT_8BIT_U; break; 576 case 16: data->input.format = data->output.format = B_FMT_16BIT; break; 577 case 24: data->input.format = data->output.format = B_FMT_24BIT; break; 578 case 32: data->input.format = data->output.format = B_FMT_32BIT; break; 579 } 580 data->input.cvsr = data->output.cvsr = current_settings.sample_rate; 581 return B_OK; 582 } 583 584 static status_t 585 echo_get_buffers(echo_dev *card, multi_buffer_list *data) 586 { 587 int32 i, j, channels; 588 echo_stream *stream; 589 590 LOG(("flags = %#x\n",data->flags)); 591 LOG(("request_playback_buffers = %#x\n",data->request_playback_buffers)); 592 LOG(("request_playback_channels = %#x\n",data->request_playback_channels)); 593 LOG(("request_playback_buffer_size = %#x\n",data->request_playback_buffer_size)); 594 LOG(("request_record_buffers = %#x\n",data->request_record_buffers)); 595 LOG(("request_record_channels = %#x\n",data->request_record_channels)); 596 LOG(("request_record_buffer_size = %#x\n",data->request_record_buffer_size)); 597 598 if (data->request_playback_buffers < current_settings.buffer_count || 599 data->request_record_buffers < current_settings.buffer_count) { 600 LOG(("not enough channels/buffers\n")); 601 } 602 603 ASSERT(current_settings.buffer_count == 2); 604 605 data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; // XXX ??? 606 // data->flags = 0; 607 608 data->return_playback_buffers = current_settings.buffer_count; /* playback_buffers[b][] */ 609 data->return_playback_channels = 0; /* playback_buffers[][c] */ 610 data->return_playback_buffer_size = current_settings.buffer_frames; /* frames */ 611 612 LIST_FOREACH(stream, &card->streams, next) { 613 if ((stream->use & ECHO_USE_PLAY) == 0) 614 continue; 615 LOG(("get_buffers pipe %d\n", stream->pipe)); 616 channels = data->return_playback_channels; 617 data->return_playback_channels += stream->channels; 618 if (data->request_playback_channels < data->return_playback_channels) { 619 LOG(("not enough channels\n")); 620 } 621 for(i=0; i<current_settings.buffer_count; i++) 622 for(j=0; j<stream->channels; j++) 623 echo_stream_get_nth_buffer(stream, j, i, 624 &data->playback_buffers[i][channels+j].base, 625 &data->playback_buffers[i][channels+j].stride); 626 } 627 628 data->return_record_buffers = current_settings.buffer_count; 629 data->return_record_channels = 0; 630 data->return_record_buffer_size = current_settings.buffer_frames; /* frames */ 631 632 LIST_FOREACH(stream, &card->streams, next) { 633 if ((stream->use & ECHO_USE_PLAY) != 0) 634 continue; 635 LOG(("get_buffers pipe %d\n", stream->pipe)); 636 channels = data->return_record_channels; 637 data->return_record_channels += stream->channels; 638 if (data->request_record_channels < data->return_record_channels) { 639 LOG(("not enough channels\n")); 640 } 641 for(i=0; i<current_settings.buffer_count; i++) 642 for(j=0; j<stream->channels; j++) 643 echo_stream_get_nth_buffer(stream, j, i, 644 &data->record_buffers[i][channels+j].base, 645 &data->record_buffers[i][channels+j].stride); 646 } 647 648 return B_OK; 649 } 650 651 652 void 653 echo_play_inth(void* inthparams) 654 { 655 echo_stream *stream = (echo_stream *)inthparams; 656 //int32 count; 657 658 //TRACE(("echo_play_inth\n")); 659 660 acquire_spinlock(&slock); 661 stream->real_time = system_time(); 662 stream->frames_count += current_settings.buffer_frames; 663 stream->buffer_cycle = (stream->trigblk 664 + stream->blkmod) % stream->blkmod; 665 stream->update_needed = true; 666 release_spinlock(&slock); 667 668 //get_sem_count(stream->card->buffer_ready_sem, &count); 669 //if (count <= 0) 670 release_sem_etc(stream->card->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE); 671 } 672 673 void 674 echo_record_inth(void* inthparams) 675 { 676 echo_stream *stream = (echo_stream *)inthparams; 677 //int32 count; 678 679 //TRACE(("echo_record_inth\n")); 680 681 acquire_spinlock(&slock); 682 stream->real_time = system_time(); 683 stream->frames_count += current_settings.buffer_frames; 684 stream->buffer_cycle = (stream->trigblk 685 + stream->blkmod - 1) % stream->blkmod; 686 stream->update_needed = true; 687 release_spinlock(&slock); 688 689 //get_sem_count(stream->card->buffer_ready_sem, &count); 690 //if (count <= 0) 691 release_sem_etc(stream->card->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE); 692 } 693 694 static status_t 695 echo_buffer_exchange(echo_dev *card, multi_buffer_info *data) 696 { 697 cpu_status status; 698 echo_stream *pstream, *rstream, *stream; 699 700 data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; 701 702 LIST_FOREACH(stream, &card->streams, next) { 703 if ((stream->state & ECHO_STATE_STARTED) != 0) 704 continue; 705 echo_stream_start(stream, 706 (stream->use & ECHO_USE_PLAY == 0) ? echo_record_inth : echo_play_inth, stream); 707 } 708 709 if(acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 50000) 710 == B_TIMED_OUT) { 711 LOG(("buffer_exchange timeout ff\n")); 712 } 713 714 status = lock(); 715 716 LIST_FOREACH(pstream, &card->streams, next) { 717 if ((pstream->use & ECHO_USE_PLAY) == 0 || 718 (pstream->state & ECHO_STATE_STARTED) == 0) 719 continue; 720 if(pstream->update_needed) 721 break; 722 } 723 724 LIST_FOREACH(rstream, &card->streams, next) { 725 if ((rstream->use & ECHO_USE_RECORD) == 0 || 726 (rstream->state & ECHO_STATE_STARTED) == 0) 727 continue; 728 if(rstream->update_needed) 729 break; 730 } 731 732 if(!pstream) 733 pstream = card->pstream; 734 if(!rstream) 735 rstream = card->rstream; 736 737 /* do playback */ 738 data->playback_buffer_cycle = pstream->buffer_cycle; 739 data->played_real_time = pstream->real_time; 740 data->played_frames_count = pstream->frames_count; 741 data->_reserved_0 = pstream->first_channel; 742 pstream->update_needed = false; 743 744 /* do record */ 745 data->record_buffer_cycle = rstream->buffer_cycle; 746 data->recorded_frames_count = rstream->frames_count; 747 data->recorded_real_time = rstream->real_time; 748 data->_reserved_1 = rstream->first_channel; 749 rstream->update_needed = false; 750 unlock(status); 751 752 //TRACE(("buffer_exchange ended\n")); 753 return B_OK; 754 } 755 756 static status_t 757 echo_buffer_force_stop(echo_dev *card) 758 { 759 //echo_voice_halt(card->pvoice); 760 return B_OK; 761 } 762 763 static status_t 764 echo_multi_control(void *cookie, uint32 op, void *data, size_t length) 765 { 766 echo_dev *card = (echo_dev *)cookie; 767 768 #ifdef CARDBUS 769 // Check 770 if (card->plugged == false) { 771 LOG(("device %s unplugged\n", card->name)); 772 return B_ERROR; 773 } 774 #endif 775 776 switch (op) { 777 case B_MULTI_GET_DESCRIPTION: 778 LOG(("B_MULTI_GET_DESCRIPTION\n")); 779 return echo_get_description(card, (multi_description *)data); 780 case B_MULTI_GET_EVENT_INFO: 781 LOG(("B_MULTI_GET_EVENT_INFO\n")); 782 return B_ERROR; 783 case B_MULTI_SET_EVENT_INFO: 784 LOG(("B_MULTI_SET_EVENT_INFO\n")); 785 return B_ERROR; 786 case B_MULTI_GET_EVENT: 787 LOG(("B_MULTI_GET_EVENT\n")); 788 return B_ERROR; 789 case B_MULTI_GET_ENABLED_CHANNELS: 790 LOG(("B_MULTI_GET_ENABLED_CHANNELS\n")); 791 return echo_get_enabled_channels(card, (multi_channel_enable *)data); 792 case B_MULTI_SET_ENABLED_CHANNELS: 793 LOG(("B_MULTI_SET_ENABLED_CHANNELS\n")); 794 return echo_set_enabled_channels(card, (multi_channel_enable *)data); 795 case B_MULTI_GET_GLOBAL_FORMAT: 796 LOG(("B_MULTI_GET_GLOBAL_FORMAT\n")); 797 return echo_get_global_format(card, (multi_format_info *)data); 798 case B_MULTI_SET_GLOBAL_FORMAT: 799 LOG(("B_MULTI_SET_GLOBAL_FORMAT\n")); 800 return B_OK; /* XXX BUG! we *MUST* return B_OK, returning B_ERROR will prevent 801 * BeOS to accept the format returned in B_MULTI_GET_GLOBAL_FORMAT 802 */ 803 case B_MULTI_GET_CHANNEL_FORMATS: 804 LOG(("B_MULTI_GET_CHANNEL_FORMATS\n")); 805 return B_ERROR; 806 case B_MULTI_SET_CHANNEL_FORMATS: /* only implemented if possible */ 807 LOG(("B_MULTI_SET_CHANNEL_FORMATS\n")); 808 return B_ERROR; 809 case B_MULTI_GET_MIX: 810 LOG(("B_MULTI_GET_MIX\n")); 811 return echo_get_mix(card, (multi_mix_value_info *)data); 812 case B_MULTI_SET_MIX: 813 LOG(("B_MULTI_SET_MIX\n")); 814 return echo_set_mix(card, (multi_mix_value_info *)data); 815 case B_MULTI_LIST_MIX_CHANNELS: 816 LOG(("B_MULTI_LIST_MIX_CHANNELS\n")); 817 return echo_list_mix_channels(card, (multi_mix_channel_info *)data); 818 case B_MULTI_LIST_MIX_CONTROLS: 819 LOG(("B_MULTI_LIST_MIX_CONTROLS\n")); 820 return echo_list_mix_controls(card, (multi_mix_control_info *)data); 821 case B_MULTI_LIST_MIX_CONNECTIONS: 822 LOG(("B_MULTI_LIST_MIX_CONNECTIONS\n")); 823 return echo_list_mix_connections(card, (multi_mix_connection_info *)data); 824 case B_MULTI_GET_BUFFERS: /* Fill out the struct for the first time; doesn't start anything. */ 825 LOG(("B_MULTI_GET_BUFFERS\n")); 826 return echo_get_buffers(card, (multi_buffer_list*)data); 827 case B_MULTI_SET_BUFFERS: /* Set what buffers to use, if the driver supports soft buffers. */ 828 LOG(("B_MULTI_SET_BUFFERS\n")); 829 return B_ERROR; /* we do not support soft buffers */ 830 case B_MULTI_SET_START_TIME: /* When to actually start */ 831 LOG(("B_MULTI_SET_START_TIME\n")); 832 return B_ERROR; 833 case B_MULTI_BUFFER_EXCHANGE: /* stop and go are derived from this being called */ 834 //TRACE(("B_MULTI_BUFFER_EXCHANGE\n")); 835 return echo_buffer_exchange(card, (multi_buffer_info *)data); 836 case B_MULTI_BUFFER_FORCE_STOP: /* force stop of playback, nothing in data */ 837 LOG(("B_MULTI_BUFFER_FORCE_STOP\n")); 838 return echo_buffer_force_stop(card); 839 } 840 LOG(("ERROR: unknown multi_control %#x\n",op)); 841 return B_ERROR; 842 } 843 844 static status_t echo_open(const char *name, uint32 flags, void** cookie); 845 static status_t echo_close(void* cookie); 846 static status_t echo_free(void* cookie); 847 static status_t echo_control(void* cookie, uint32 op, void* arg, size_t len); 848 static status_t echo_read(void* cookie, off_t position, void *buf, size_t* num_bytes); 849 static status_t echo_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes); 850 851 device_hooks multi_hooks = { 852 echo_open, /* -> open entry point */ 853 echo_close, /* -> close entry point */ 854 echo_free, /* -> free cookie */ 855 echo_control, /* -> control entry point */ 856 echo_read, /* -> read entry point */ 857 echo_write, /* -> write entry point */ 858 NULL, /* start select */ 859 NULL, /* stop select */ 860 NULL, /* scatter-gather read from the device */ 861 NULL /* scatter-gather write to the device */ 862 }; 863 864 static status_t 865 echo_open(const char *name, uint32 flags, void** cookie) 866 { 867 echo_dev *card = NULL; 868 int i, first_record_channel; 869 echo_stream *stream = NULL; 870 871 LOG(("echo_open()\n")); 872 873 #ifdef CARDBUS 874 LIST_FOREACH(card, &devices, next) { 875 if (!strcmp(card->name, name)) { 876 break; 877 } 878 } 879 #else 880 for (i=0; i<num_cards; i++) { 881 if (!strcmp(cards[i].name, name)) { 882 card = &cards[i]; 883 } 884 } 885 #endif 886 887 if(card == NULL) { 888 LOG(("open() card not found %s\n", name)); 889 #ifdef CARDBUS 890 LIST_FOREACH(card, &devices, next) { 891 LOG(("open() card available %s\n", card->name)); 892 } 893 #else 894 for (int ix=0; ix<num_cards; ix++) { 895 LOG(("open() card available %s\n", cards[ix].name)); 896 } 897 #endif 898 return B_ERROR; 899 } 900 901 #ifdef CARDBUS 902 if (card->plugged == false) { 903 LOG(("device %s unplugged\n", name)); 904 return B_ERROR; 905 } 906 #endif 907 908 LOG(("open() got card\n")); 909 910 if (card->pstream != NULL) 911 return B_ERROR; 912 if (card->rstream != NULL) 913 return B_ERROR; 914 915 *cookie = card; 916 card->multi.card = card; 917 #ifdef CARDBUS 918 card->opened = true; 919 #endif 920 921 LOG(("creating play streams\n")); 922 923 i = card->caps.wNumPipesOut - 2; 924 first_record_channel = card->caps.wNumPipesOut; 925 #ifdef ECHO3G_FAMILY 926 if (current_settings.sample_rate > 50000) { 927 i = card->caps.wFirstDigitalBusOut; 928 first_record_channel = card->caps.wFirstDigitalBusOut + 2; 929 } 930 #endif 931 932 for (; i >=0 ; i-=2) { 933 stream = echo_stream_new(card, ECHO_USE_PLAY, current_settings.buffer_frames, current_settings.buffer_count); 934 if (!card->pstream) 935 card->pstream = stream; 936 echo_stream_set_audioparms(stream, current_settings.channels, 937 current_settings.bitsPerSample, current_settings.sample_rate, i); 938 stream->first_channel = i; 939 } 940 941 LOG(("creating record streams\n")); 942 i = card->caps.wNumPipesIn - 2; 943 #ifdef ECHO3G_FAMILY 944 if (current_settings.sample_rate > 50000) { 945 i = card->caps.wFirstDigitalBusIn; 946 } 947 #endif 948 949 for (; i >= 0; i-=2) { 950 stream = echo_stream_new(card, ECHO_USE_RECORD, current_settings.buffer_frames, current_settings.buffer_count); 951 if (!card->rstream) 952 card->rstream = stream; 953 echo_stream_set_audioparms(stream, current_settings.channels, 954 current_settings.bitsPerSample, current_settings.sample_rate, i); 955 stream->first_channel = i + first_record_channel; 956 } 957 958 card->buffer_ready_sem = create_sem(0, "pbuffer ready"); 959 960 LOG(("creating channels list\n")); 961 echo_create_channels_list(&card->multi); 962 963 return B_OK; 964 } 965 966 static status_t 967 echo_close(void* cookie) 968 { 969 LOG(("close()\n")); 970 #ifdef CARDBUS 971 echo_dev *card = (echo_dev *) cookie; 972 card->opened = false; 973 #endif 974 975 return B_OK; 976 } 977 978 static status_t 979 echo_free(void* cookie) 980 { 981 echo_dev *card = (echo_dev *) cookie; 982 echo_stream *stream; 983 LOG(("echo_free()\n")); 984 985 if (card->buffer_ready_sem > B_OK) 986 delete_sem(card->buffer_ready_sem); 987 988 LIST_FOREACH(stream, &card->streams, next) { 989 echo_stream_halt(stream); 990 } 991 992 while(!LIST_EMPTY(&card->streams)) { 993 echo_stream_delete(LIST_FIRST(&card->streams)); 994 } 995 996 card->pstream = NULL; 997 card->rstream = NULL; 998 999 return B_OK; 1000 } 1001 1002 static status_t 1003 echo_control(void* cookie, uint32 op, void* arg, size_t len) 1004 { 1005 return echo_multi_control(cookie, op, arg, len); 1006 } 1007 1008 static status_t 1009 echo_read(void* cookie, off_t position, void *buf, size_t* num_bytes) 1010 { 1011 *num_bytes = 0; /* tell caller nothing was read */ 1012 return B_IO_ERROR; 1013 } 1014 1015 static status_t 1016 echo_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes) 1017 { 1018 *num_bytes = 0; /* tell caller nothing was written */ 1019 return B_IO_ERROR; 1020 } 1021 1022