bool TinyAmixerControlValue::writeControl(struct mixer_ctl *mixerControl,
                                          size_t elementCount,
                                          std::string &error)
{
    uint32_t elementNumber;

    // Write element
    // Go through all elements
    for (elementNumber = 0; elementNumber < elementCount; elementNumber++) {

        int32_t value;

        // Read data from blackboard (beware this code is OK on Little Endian machines only)
        value = fromBlackboard();

        if (isDebugEnabled()) {

            info() << "Writing alsa element " << getControlName()
                   << ", index " << elementNumber << " with value " << value;
        }

        // Write element
        int err;
        if ((err = mixer_ctl_set_value(mixerControl, elementNumber, value)) < 0) {

            error = "Failed to write value in mixer control: " + getControlName() + ": " +
                    strerror(-err);
            return false;
        }
    }
    return true;
}
bool TinyAmixerControlValue::readControl(struct mixer_ctl *mixerControl,
                                         size_t elementCount,
                                         std::string &error)
{
    uint32_t elementNumber;

    // Read element
    // Go through all elements
    for (elementNumber = 0; elementNumber < elementCount; elementNumber++) {

        int32_t value;
        if ((value = mixer_ctl_get_value(mixerControl, elementNumber)) < 0) {

            error = "Failed to read value in mixer control: " + getControlName();
            return false;
        }

        if (isDebugEnabled()) {

            info() << "Reading alsa element " << getControlName()
                   << ", index " << elementNumber << " with value " << value;
        }

        toBlackboard(value);
    }
    return true;
}
void TinyAmixerControlArray::logControlValues(bool receive,
                                              const void *array,
                                              uint32_t elementCount) const
{
    const unsigned char *buffer = reinterpret_cast<const unsigned char *>(array);
    unsigned int idx;
    std::stringstream log;

    log << (receive ? "Reading" : "Writing");
    log << " alsa element: " << getControlName() << " with value: ";
    displayAndCleanString(log);
    for (idx = 0; idx < elementCount; idx++) {
        log.width(2);
        log.fill('0');
        // cast to uint16_t necessary in order to avoid 'buffer[idx]' to be
        // treated as a printable character, apparently
        log << hex << static_cast<unsigned short>(buffer[idx]) << " ";
        if ((idx != 0) && ((idx % maxLogLine) == 0)) {
            log << '\n';
            displayAndCleanString(log);
        }
    }

    if (log.str().length() > 0) {
        log << '\n';
        displayAndCleanString(log);
    }

    log << "[" << dec << elementCount << " bytes]" << endl;
    displayAndCleanString(log);
}
예제 #4
0
QStringList ControllableDeviceList::getControlList() {
    QStringList reply;
    for (int i=0;i<deviceList.size();i++) {
        reply.append(getControlName(i));
    }
    return reply;
}
예제 #5
0
ofxWToggle & ofxWFrame::addToggle(const string & title, string controlName, string _style){
	controlName=getControlName(controlName,title);
	ofxWToggle * toggle = new ofxWToggle(controlName);
	toggle->init(title,_style==""?style:_style);

	toggle->setPosition(getNextPosition());


	addWidget(toggle,controlName);
	return *toggle;
}
예제 #6
0
ofxWButton & ofxWFrame::addButton(const string & title, string controlName, string _style){
	controlName=getControlName(controlName,title);
	ofxWButton * button = new ofxWButton(controlName);
	button->init(title,_style==""?style:_style);

	button->setPosition(getNextPosition());


	addWidget(button,controlName);
	return *button;
}
예제 #7
0
ofxW2DSlider & ofxWFrame::add2DSlider(const string & title, float xvalue, float yvalue, float xmin, float xmax, float ymin, float ymax, string controlName, const string & _style){
	controlName=getControlName(controlName,title);
	ofxW2DSlider * slider = new ofxW2DSlider(controlName);
	slider->init(title,xvalue,yvalue,xmin,xmax,ymin,ymax,_style==""?style:_style);

	slider->setPosition(getNextPosition());


	addWidget(slider,controlName);
	return *slider;
}
예제 #8
0
ofxWSpinSlider & ofxWFrame::addSpinSlider(const string & title, float value, float min, float max, float step,  string controlName, const string & _style){
	controlName=getControlName(controlName,title);
	ofxWSpinSlider * slider = new ofxWSpinSlider(controlName);
	slider->init(title,value,min,max,step,_style==""?style:_style);

	slider->setPosition(getNextPosition());


	addWidget(slider,controlName);
	return *slider;
}
예제 #9
0
ofxWTextBox & ofxWFrame::addTextBox(const string & title, string text, string controlName, string _style){
	controlName=getControlName(controlName,title);
	ofxWTextBox * textBox = new ofxWTextBox(controlName);
	textBox->init(title,_style==""?style:_style);

	textBox->setPosition(getNextPosition());
	textBox->setText(text);


	addWidget(textBox,controlName);
	return *textBox;
}
bool TinyAmixerControlArray::readControl(struct mixer_ctl *mixerControl,
                                         uint32_t elementCount,
                                         string &error)
{
    int err;

    if ((err = getArrayMixer(mixerControl, elementCount)) < 0) {

        error = "Failed to read value in mixer control: " + getControlName() + ": " +
                strerror(-err);
        return false;
    }

    return true;
}
예제 #11
0
int32_t CamConfig::readControlValue(uint32_t const id) {
    std::string control_name;
    getControlName(id, &control_name);
    LOG_DEBUG("CamConfig: readControlValue %s (%d)", control_name.c_str(), id);

    struct v4l2_control control;
    memset(&control, 0, sizeof(struct v4l2_control));
    control.id = id;
   
    if (0 != ioctl (mFd, VIDIOC_G_CTRL, &control)) {
        std::string err_str(strerror(errno)); 
        throw std::runtime_error(err_str.insert(0, "Could not read control object value: ")); 
    }
    LOG_DEBUG("Control %s(0x%x(%d)) value: %d", control_name.c_str(), id, id, control.value);
    return control.value;
}
예제 #12
0
ofxWidgetFps & ofxWFrame::addFps(string controlName){
	controlName=getControlName(controlName,"fps");
	ofxWidgetFps * fps = new ofxWidgetFps(controlName);

	/*fps->setEnabledStyle(buttonStyle);
	fps->setDisabledStyle(buttonStyle);
	fps->setFocusedStyle(buttonFocusedStyle);
	fps->setPressedStyle(buttonPressedStyle);
	fps->setOutStyle(buttonPressedStyle);*/


	fps->setPosition(getNextPosition());


	addWidget(fps,controlName);
	return *fps;
}
예제 #13
0
void CamConfig::listControls() {
    std::map<uint32_t, struct CamCtrl>::iterator it;

    printf("CAMERA CONTROLS\n");
    for(it = mCamCtrls.begin(); it != mCamCtrls.end(); it++) {
        struct v4l2_queryctrl* pq = &(it->second.mCtrl);
        std::string name;
        getControlName(it->first, &name);
        printf("0x%x(%d): %s, values: %d to %d (step %d), default: %d, current: %d, writeable: %s, readable: %s\n", 
            pq->id, pq->id, name.c_str(), pq->minimum, pq->maximum, pq->step, pq->default_value, it->second.mValue,
            it->second.mWriteable ? "true" : "false", it->second.mReadable ? "true" : "false");
        if(it->second.mMenuItems.size() > 0) {
            printf("\tMenu-Entries\n");
        }
        for(unsigned int i=0; i < it->second.mMenuItems.size(); i++) {
            printf("\t%d: %s\n", i, it->second.mMenuItems[i].c_str());
        }
    }  
    printf("\n");
}
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;
}
예제 #16
0
void CamConfig::writeControlValue(uint32_t const id, int32_t value, bool just_write) {
    std::string control_name;
    getControlName(id, &control_name);
    LOG_DEBUG("CamConfig: writeControlValue %s (%d) to %d", control_name.c_str(), id, value);
    struct v4l2_control control;
    control.id = id;
    control.value = value;

    // Problem setting control parameter V4L2_CID_WHITE_BALANCE_TEMPERATURE
    // on Microsoft LifeCam Cinema(TM), will be ignored.
    /* Should be handled by read/write only parameters.
    if(id == V4L2_CID_WHITE_BALANCE_TEMPERATURE) {
        LOG_WARN("Writing of control V4L2_CID_WHITE_BALANCE_TEMPERATURE is ignored!");
        return;
    }
    */
    std::map<uint32_t, struct CamCtrl>::iterator it;
    if(!just_write) { 
        // Request internally stored control.
        it = mCamCtrls.find(id);

        // id unknown?
        if(it == mCamCtrls.end()) {
            throw std::runtime_error("Passed id unknown");
        }

        // read-only control?
        if(!it->second.mWriteable) {
            std::stringstream ss;
            ss << "Writing is deactivated for control " << control_name << std::endl;
            throw std::runtime_error(ss.str().c_str());
        }

        // Check borders.
        if(value < it->second.mCtrl.minimum) {
            LOG_INFO("Control %s (%d) value %d set to minimum %d", 
                    control_name.c_str(), id, value, it->second.mCtrl.minimum);
            control.value = it->second.mCtrl.minimum;
        }
        if(value > it->second.mCtrl.maximum) {
            LOG_INFO("Control %s (%d) value %d set to maximum %d", 
                    control_name.c_str(), id, value, it->second.mCtrl.maximum);
            control.value = it->second.mCtrl.maximum;
        }
    }

    if(0 == ioctl (mFd, VIDIOC_S_CTRL, &control)) {
        if(!just_write) {
            // Change internally stored value as well.
            it->second.mValue = value;
        }
        LOG_DEBUG("Control value %s (0x%x (%d)) set to %d", control_name.c_str(), id, id, value);
    } else {
        std::string err_str(strerror(errno));
        
        // ID unknown? Should not happen or data would be out of sync.
        if(errno == EINVAL) {
            throw CamConfigException(err_str.insert(0, 
                    "VIDIOC_S_CTRL is not supported by device driver: "));
        }
        
        // Some controls may only be changed in manual mode. This is not an error.
        if(mAutoManualDependentControlIds.find(id) != mAutoManualDependentControlIds.end()) {
            LOG_WARN("Control value %s (0x%x (%d)) cannot be changed, auto-mode active?", control_name.c_str(), id, id);
        } else {
            throw std::runtime_error(err_str.insert(0, "Could not write control object: ")); 
        }
    }
}