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