int canSplitCard(const struct Player* player) { int canSplit = FALSE; if(!player->isDealer && countCardInSlot(&player->slot) == 2) { int firstCard = getCardInSlot(&player->slot, 0); int secondCard = getCardInSlot(&player->slot, 1); if(getCardNumber(firstCard) == getCardNumber(secondCard)) { canSplit = TRUE; } } return canSplit; }
bool TinyAlsaCtlPortConfig::doOpenStream(StreamDirection streamDirection, std::string &error) { struct pcm *&streamHandle = _streamHandle[streamDirection]; struct pcm_config pcmConfig; const AlsaCtlPortConfig::PortConfig &portConfig = getPortConfig(); // Fill PCM configuration structure pcmConfig.channels = portConfig.channelNumber; pcmConfig.rate = portConfig.sampleRate; // Check Format is supported by the plugin if (portConfig.format >= pcmFormatTranslationTableSize) { error = "The format n°" + asString(portConfig.format) + " is not supported by the TinyAlsa plugin"; return false; } uint8_t format = pcmFormatTranslationTable[portConfig.format].formatAsNumerical; // Check format is supported by Tinyalsa if (format == std::numeric_limits<uint8_t>::max()) { error = "The format " + pcmFormatTranslationTable[portConfig.format].formatAsString + " is not supported by Tinyalsa"; return false; } pcmConfig.format = static_cast<pcm_format>(format); pcmConfig.period_size = _periodTimeMs * pcmConfig.rate / _msPerSec; pcmConfig.period_count = _nbRingBuffer; pcmConfig.start_threshold = 0; pcmConfig.stop_threshold = 0; pcmConfig.silence_threshold = 0; pcmConfig.silence_size = 0; pcmConfig.avail_min = 0; // Open and configure streamHandle = pcm_open(getCardNumber(), getDeviceNumber(), streamDirection == Capture ? PCM_IN : PCM_OUT, &pcmConfig); // Prepare the stream if (!pcm_is_ready(streamHandle) || (pcm_prepare(streamHandle) != 0)) { // Format error error = formatAlsaError(streamDirection, "open", pcm_get_error(streamHandle)); doCloseStream(streamDirection); return false; } return true; }
void AudioOutputDeviceManager::deviceEventProc( struct udev_device & _device , std::multimap< int, const AudioOutputDevice * > & _devices ) { if( udev_device_get_devnode( &_device ) != nullptr ) { return; } if( isInitializedDevice( _device ) == false ) { return; } auto card = getCardNumber( _device ); const auto ACTION = udev_device_get_action( &_device ); if( ACTION != nullptr && std::strcmp( ACTION , "remove" ) == 0 ) { this->removeDeviceEventProc( card , _devices ); } else { this->addDeviceEventProc( card , _devices ); } }
bool LegacyAmixerControl::accessHW(bool receive, string &error) { CAutoLog autoLog(getConfigurableElement(), "ALSA", isDebugEnabled()); #ifdef SIMULATION if (receive) { memset(getBlackboardLocation(), 0, getSize()); } log_info("%s ALSA Element Instance: %s\t\t(Control Element: %s)", receive ? "Reading" : "Writing", getConfigurableElement()->getPath().c_str(), getControlName().c_str()); return true; #endif int ret; // Mixer handle snd_ctl_t *sndCtrl; uint32_t value; uint32_t index; uint32_t elementCount; snd_ctl_elem_id_t *id; snd_ctl_elem_info_t *info; snd_ctl_elem_value_t *control; logControlInfo(receive); // Check parameter type is ok (deferred error, no exceptions available :-() if (!isTypeSupported()) { error = "Parameter type not supported."; return false; } int cardNumber = getCardNumber(); if (cardNumber < 0) { error = "Card " + getCardName() + " not found. Error: " + strerror(cardNumber); return false; } #ifdef ANDROID if ((ret = snd_ctl_hw_open(&sndCtrl, NULL, cardNumber, 0)) < 0) { error = snd_strerror(ret); return false; } #else // Create device name ostringstream deviceName; deviceName << "hw:" << cardNumber; // Open sound control if ((ret = snd_ctl_open(&sndCtrl, deviceName.str().c_str(), 0)) < 0) { error = snd_strerror(ret); return false; } #endif // Allocate in stack snd_ctl_elem_id_alloca(&id); snd_ctl_elem_info_alloca(&info); snd_ctl_elem_value_alloca(&control); // Set interface snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); string controlName = getControlName(); // Set name or id if (isdigit(controlName[0])) { snd_ctl_elem_id_set_numid(id, asInteger(controlName)); } else { snd_ctl_elem_id_set_name(id, controlName.c_str()); } // Init info id snd_ctl_elem_info_set_id(info, id); // Get info if ((ret = snd_ctl_elem_info(sndCtrl, info)) < 0) { error = "ALSA: Unable to get element info " + controlName + ": " + snd_strerror(ret); // Close sound control snd_ctl_close(sndCtrl); return false; } // Get type snd_ctl_elem_type_t eType = snd_ctl_elem_info_get_type(info); // Get element count elementCount = snd_ctl_elem_info_get_count(info); uint32_t scalarSize = getScalarSize(); // If size defined in the PFW different from alsa mixer control size, return an error if (elementCount * scalarSize != getSize()) { error = "ALSA: Control element count (" + asString(elementCount) + ") and configurable scalar element count (" + asString(getSize() / scalarSize) + ") mismatch"; // Close sound control snd_ctl_close(sndCtrl); return false; } // Set value id snd_ctl_elem_value_set_id(control, id); if (receive) { // Read element if ((ret = snd_ctl_elem_read(sndCtrl, control)) < 0) { error = "ALSA: Unable to read element " + controlName + ": " + snd_strerror(ret); // Close sound control snd_ctl_close(sndCtrl); return false; } // Go through all indexes for (index = 0; index < elementCount; index++) { switch (eType) { case SND_CTL_ELEM_TYPE_BOOLEAN: value = snd_ctl_elem_value_get_boolean(control, index); break; case SND_CTL_ELEM_TYPE_INTEGER: value = snd_ctl_elem_value_get_integer(control, index); break; case SND_CTL_ELEM_TYPE_INTEGER64: value = snd_ctl_elem_value_get_integer64(control, index); break; case SND_CTL_ELEM_TYPE_ENUMERATED: value = snd_ctl_elem_value_get_enumerated(control, index); break; case SND_CTL_ELEM_TYPE_BYTES: value = snd_ctl_elem_value_get_byte(control, index); break; default: error = "ALSA: Unknown control element type while reading alsa element " + controlName; return false; } if (isDebugEnabled()) { log_info("Reading alsa element %s, index %u with value %u", controlName.c_str(), index, value); } // Write data to blackboard (beware this code is OK on Little Endian machines only) toBlackboard(value); } } else { // Go through all indexes for (index = 0; index < elementCount; index++) { // Read data from blackboard (beware this code is OK on Little Endian machines only) value = fromBlackboard(); if (isDebugEnabled()) { log_info("Writing alsa element %s, index %u with value %u", controlName.c_str(), index, value); } switch (eType) { case SND_CTL_ELEM_TYPE_BOOLEAN: snd_ctl_elem_value_set_boolean(control, index, value); break; case SND_CTL_ELEM_TYPE_INTEGER: snd_ctl_elem_value_set_integer(control, index, value); break; case SND_CTL_ELEM_TYPE_INTEGER64: snd_ctl_elem_value_set_integer64(control, index, value); break; case SND_CTL_ELEM_TYPE_ENUMERATED: snd_ctl_elem_value_set_enumerated(control, index, value); break; case SND_CTL_ELEM_TYPE_BYTES: snd_ctl_elem_value_set_byte(control, index, value); break; default: error = "ALSA: Unknown control element type while writing alsa element " + controlName; return false; } } // Write element if ((ret = snd_ctl_elem_write(sndCtrl, control)) < 0) { error = "ALSA: Unable to write element " + controlName + ": " + snd_strerror(ret); // Close sound control snd_ctl_close(sndCtrl); return false; } } // Close sound control snd_ctl_close(sndCtrl); return true; }
bool TinyAmixerControl::accessHW(bool receive, std::string &error) { CAutoLog autoLog(getConfigurableElement(), "ALSA", isDebugEnabled()); // Mixer handle struct mixer *mixer; // Mixer control handle struct mixer_ctl *mixerControl; uint32_t elementCount; std::string controlName = getControlName(); // Debug conditionnaly enabled in XML logControlInfo(receive); // Check parameter type is ok (deferred error, no exceptions available :-() if (!isTypeSupported()) { error = "Parameter type not supported."; return false; } // Check card number int32_t cardIndex = getCardNumber(); if (cardIndex < 0) { error = "Card " + getCardName() + " not found. Error: " + strerror(-cardIndex); return false; } // Open alsa mixer // getMixerHandle is non-const; we need to forcefully remove the constness // then, we need to cast the generic subsystem into a TinyAlsaSubsystem. mixer = static_cast<TinyAlsaSubsystem *>( const_cast<CSubsystem *>(getSubsystem()))->getMixerHandle(cardIndex); if (!mixer) { error = "Failed to open mixer for card: " + getCardName(); return false; } // Get control handle if (isdigit(controlName[0])) { mixerControl = mixer_get_ctl(mixer, asInteger(controlName)); } else { mixerControl = mixer_get_ctl_by_name(mixer, controlName.c_str()); } // Check control has been found if (!mixerControl) { error = "Failed to open mixer control: " + controlName; return false; } // Get element count elementCount = getNumValues(mixerControl); uint32_t scalarSize = getScalarSize(); // Check available size if (elementCount * scalarSize != getSize()) { error = "ALSA: Control element count (" + asString(elementCount) + ") and configurable scalar element count (" + asString(getSize() / scalarSize) + ") mismatch"; return false; } // Read/Write element bool success; if (receive) { success = readControl(mixerControl, elementCount, error); } else { success = writeControl(mixerControl, elementCount, error); } return success; }