static int processRequest(char *request) { int count = 0; int responseTotal = 0; config_setting_t *responseConfig = NULL; config_setting_t *responseCurrent = NULL; const char *responseValue = NULL; const char *requestName = NULL; const char *requestValue = NULL; long volume; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_mutex_lock(&lockConfig); responseConfig = config_lookup(&config, "response"); responseTotal = config_setting_length(responseConfig); for(count = 0; count < responseTotal; count++) { responseCurrent = config_setting_get_elem(responseConfig, count); if((responseValue = config_setting_get_string_elem(responseCurrent, 1)) != NULL && strcmp(responseValue, request) == 0) { responseValue = config_setting_get_string_elem(responseCurrent, 2); if(config_setting_get_bool_elem(responseCurrent, 0) == 1) { // formulating default response pthread_mutex_unlock(&lockConfig); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); common_data.interface->reply(responseValue, strlen(responseValue)); } else { // attempt to formulate custom response requestName = config_setting_name(responseCurrent); pthread_mutex_unlock(&lockConfig); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); if(strcmp(requestName, "volume") == 0) { if(getMixer(&volume) == EXIT_FAILURE) { return EXIT_FAILURE; } replyVolumeCommand(&volume); } else { statusInfo.retrieve(requestName, &requestValue); if(requestValue != NULL) replyDeviceCommand((char *)requestName, (char *)requestValue); else // custom response not possible, reverting to default value replyDeviceCommand((char *)requestName, (char *)responseValue); } } syslog(LOG_DEBUG, "Successfully processed request: %s", request); return EXIT_SUCCESS; // command is matched, returning } else { pthread_mutex_unlock(&lockConfig); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); } } syslog(LOG_DEBUG, "Could not identify request: %s", request); return EXIT_SUCCESS; }
int AmeSystemSound::setupMixer(QString card, QString device) { char *name; long int a, b; long alsa_min_vol = 0, alsa_max_vol = 100; int err, index; mixer_element = 0; qDebug("AmeSystemSound::SoundOutput: setupMixer()"); if ((err = getMixer(&mixer, card)) < 0) return err; parseMixerName(device.toAscii().data(), &name, &index); mixer_element = getMixerElem(mixer, name, index); free(name); if (!mixer_element) { qWarning("SoundOutput: Failed to find mixer element"); return -1; } /* This hack was copied from xmms. * Work around a bug in alsa-lib up to 1.0.0rc2 where the * new range don't take effect until the volume is changed. * This hack should be removed once we depend on Alsa 1.0.0. */ snd_mixer_selem_get_playback_volume(mixer_element, SND_MIXER_SCHN_FRONT_LEFT, &a); snd_mixer_selem_get_playback_volume(mixer_element, SND_MIXER_SCHN_FRONT_RIGHT, &b); snd_mixer_selem_get_playback_volume_range(mixer_element, &alsa_min_vol, &alsa_max_vol); snd_mixer_selem_set_playback_volume_range(mixer_element, 0, 100); if (alsa_max_vol == 0) { mixer_element = NULL; return -1; } setVolume(a * 100 / alsa_max_vol); qDebug("SoundOutput: setupMixer() success"); return 0; }
int VolumeALSA::setupMixer(QString card, QString device) { char *name; int err, index; pcm_element = 0; qDebug("OutputALSA: setupMixer()"); if ((err = getMixer(&m_mixer, card)) < 0) return err; parseMixerName(device.toAscii().data(), &name, &index); pcm_element = getMixerElem(m_mixer, name, index); free(name); if (!pcm_element) { qWarning("OutputALSA: Failed to find mixer element"); return -1; } if((err = snd_mixer_selem_set_playback_volume_range(pcm_element, 0, 100)) < 0) { qWarning("OutputALSA: Unable to set volume range: %s", snd_strerror(-err)); pcm_element = NULL; return -1; } // setup socket notifiers to monitor the state changes of the mixer int n = snd_mixer_poll_descriptors_count(m_mixer); if(n > 0) { struct pollfd* fds = new struct pollfd[n]; n = snd_mixer_poll_descriptors(m_mixer, fds, n); for(int i = 0; i < n; ++i) { int sock = fds[i].fd; QSocketNotifier* sn = new QSocketNotifier(sock, QSocketNotifier::Read, this); connect(sn, SIGNAL(activated(int)), SIGNAL(changed())); } delete []fds; } qDebug("OutputALSA: setupMixer() success"); return 0; }
int main(int argc, char *argv[]) { /***** * boolean value indicates when to break main loop * (and thus finish this configuration tool) *****/ int request_finish = 0; int current = 0; /***** menu related variables */ int menu_items = 7; enum state status[] = {invalid, invalid, inactive, inactive, inactive, inactive, invalid}; WINDOW *mainscr; /***** ncurses related variables */ int i, j; /* ***** detect available mixer devices */ mixer_devices = scanMixerDevices(); if (mixer_devices == NULL || mixer_devices->count == 0) { /* ***** no mixer devices available -> exit! */ fprintf(stderr, "No mixer devices available!\n"); fprintf(stderr, "Please purchase a sound card and install it!\n"); exit(-1); } else { if (mixer_devices->count == 1) /***** exactly one mixer device available */ { setMixer(mixer_devices->name[0]); /***** set this mixer */ if (initMixer() == MIXER_OK) /***** if mixer is ok, keep it */ { status[0] = ok; status[2] = invalid; } else /***** otherwise, exit!*/ { fprintf(stderr, "Couldn't init the only available mixer device: /dev/%s\n", mixer_devices->name[0]); exit(-1); } } else /* ***** more than one device available! */ { /* ***** use /dev/mixer as default if it exists */ for (i = 0; i < mixer_devices->count; i++) { if (strcmp(mixer_devices->name[i], "mixer") == 0) { setMixer("mixer"); if (initMixer() == MIXER_OK) { status[0] = ok; status[2] = invalid; } else noMixer(); break; } } } } /* ***** detect available audio devices */ audio_devices = scanAudioDevices(); if (audio_devices == NULL || audio_devices->count == 0) { /* ***** no audio devices available! */ fprintf(stderr, "No audio device available that\n"); fprintf(stderr, "supports 16bit recording!\n"); fprintf(stderr, "Please purchase a sound card and install it!\n"); exit(-1); } else { if (audio_devices->count == 1) /***** exactly one audio device available */ { setAudio(audio_devices->name[0]); /***** set this audio device */ if (initAudio() == AUDIO_OK) /***** if audio device is ok, keep it */ { status[1] = ok; } else /***** otherwise, exit!*/ { fprintf(stderr, "Couldn't init the only available audio device: /dev/%s\n", audio_devices->name[0]); exit(-1); } } else /* ***** more than one device available! */ { /* ***** use /dev/dspW as default if it exists */ for (i = 0; i < audio_devices->count; i++) { if (strcmp(audio_devices->name[i], "dspW") == 0) { setAudio("dspW"); if (initAudio() == AUDIO_OK) status[1] = ok; else noAudio(); break; } } } } /***** * if mixer and audio device have been selected successfully, * set menu cursor to next available menu item *****/ if (status[0] == ok && status[1] == ok) current = 2; /***** ignore Ctrl-C */ signal(SIGINT, SIG_IGN); /* ***** ncurses stuff */ initscr(); /* initialize the curses library */ if (color_term != -1) /***** define dialog color pairs if terminal supports colors */ { start_color (); if ((color_term = has_colors ())) { color_term = 1; init_pair (1, COLOR_WHITE, COLOR_BLUE); init_pair (2, COLOR_YELLOW, COLOR_BLUE); init_pair (3, COLOR_BLUE, COLOR_YELLOW); init_pair (4, COLOR_YELLOW, COLOR_CYAN); } } else color_term = 0; keypad(stdscr, TRUE); /* enable keyboard mapping */ scrollok (stdscr, FALSE); cbreak(); /* take input chars one at a time, no wait for \n */ noecho(); /* don't echo input */ refresh(); mainscr = popupWindow(COLS, LINES); /***** dialog window that contains the main menu */ leaveok (mainscr, FALSE); while (!request_finish) { wattrset (mainscr, color_term ? COLOR_PAIR(2) | A_BOLD : A_NORMAL); /***** set bg color of the dialog */ /***** * draw a box around the dialog window * and empty it. *****/ box(mainscr, 0, 0); for (i = 1; i < COLS-1; i++) for (j = 1; j < LINES-1; j++) mvwaddch(mainscr, j, i, ' '); /***** dialog header */ mvwaddstr(mainscr, 1, 2, "CVoiceControl"); mvwaddstr(mainscr, 1, COLS - strlen("(c) 2000 Daniel Kiecza") - 2, "(c) 2000 Daniel Kiecza"); mvwaddseparator(mainscr, 2, COLS); mvwaddstr(mainscr, 3, (COLS / 2) - (strlen ("Recording Device Configuration Tool") / 2), "Recording Device Configuration Tool"); mvwaddseparator(mainscr, 4, COLS); /***** main menu */ mvwaddstr(mainscr, 5, 2, "Please Select:"); setHighlight(mainscr, status[0], current == 0); mvwaddstr(mainscr, 7,5,"Select Mixer Device"); if (mixerOK() == MIXER_OK) { mvwaddstr(mainscr, 7,24," ("); waddstr(mainscr, getMixer()); waddstr(mainscr, ")"); } else mvwaddstr(mainscr, 7,24," (none selected!)"); setHighlight(mainscr, status[1], current == 1); mvwaddstr(mainscr, 8,5,"Select Audio Device"); if (audioOK() == AUDIO_OK) { mvwaddstr(mainscr, 8,24," ("); waddstr(mainscr, getAudio()); waddstr(mainscr, ")"); } else mvwaddstr(mainscr, 8,24," (none selected!)"); setHighlight(mainscr, status[2], current == 2); mvwaddstr(mainscr, 9,5,"Adjust Mixer Levels"); setHighlight(mainscr, status[3], current == 3); mvwaddstr(mainscr, 10,5,"Calculate Recording Thresholds"); setHighlight(mainscr, status[4], current == 4); mvwaddstr(mainscr, 11,5,"Estimate Characteristics of Recording Channel"); setHighlight(mainscr, status[5], current == 5); mvwaddstr(mainscr, 12,5,"Write Configuration"); setHighlight(mainscr, status[6], current == 6); mvwaddstr(mainscr, 13,5,"Exit"); wmove(mainscr, 5, 17); /***** set cursor to an appropriate location */ wrefresh(mainscr); /***** refresh the dialog */ /* process the command keystroke */ switch(getch()) { case KEY_UP: /***** cursor up */ current = (current == 0 ? menu_items - 1 : current - 1); while(status[current] == inactive) current = (current == 0 ? menu_items - 1 : current - 1); break; case KEY_DOWN: /***** cursor down */ current = (current == menu_items-1 ? 0 : current + 1); while(status[current] == inactive) current = (current == menu_items-1 ? 0 : current + 1); break; case ENTER: /***** handle menu selections */ case BLANK: switch (current) { case 0: /***** select mixer device */ status[0] = invalid; status[2] = inactive; status[3] = inactive; status[4] = inactive; status[5] = inactive; noMixer(); if (selectMixer() == MIXER_OK) { status[0] = ok; status[2] = invalid; } break; case 1: /***** select audio device */ status[1] = invalid; status[3] = inactive; status[4] = inactive; status[5] = inactive; noAudio(); if (selectAudio() == AUDIO_OK) status[1] = ok; break; case 2: /***** adjust mixer levels */ if (adjustMixerLevels()) { status[2] = ok; status[3] = invalid; status[4] = invalid; } break; case 3: /***** calculate recording thresholds */ if (calculateThresholds()) status[3] = ok; else status[3] = invalid; break; case 4: /***** estimate the characteristics of the recording channel */ if (estimateChannelMean()) status[4] = ok; else status[4] = invalid; break; case 5: /***** save configuration! */ if (saveConfiguration()) { status[5] = ok; status[6] = ok; } break; case 6: /***** leave program */ if (status[6] == ok || (status[6] != ok && safeExit())) { wrefresh(mainscr); /***** refresh the dialog */ request_finish = 1; delwin(mainscr); /***** delete ncurses dialog window */ } break; } break; } /***** if the configuration is done, activate the menu item "Save Configuration" */ if (status[0] != ok || status[1] != ok || status[2] != ok || status[3] != ok || status[4] != ok) status[5] = inactive; else if (status[5] != ok) status[5] = invalid; } endwin(); /* we're done */ /***** free memory used by the list of mixer and audio devices */ if (mixer_devices != NULL) { for (i = 0; i < mixer_devices->count; i++) free(mixer_devices->name[i]); free(mixer_devices->name); free(mixer_devices); } if (audio_devices != NULL) { for (i = 0; i < audio_devices->count; i++) free(audio_devices->name[i]); free(audio_devices->name); free(audio_devices); } exit(0); }
int saveConfiguration() { char *home; /***** config file related variables */ char *config_dir; char *config_file; FILE *f; int retval = 0; /***** return value */ int width = 60, height = 11, i, j; /***** ncurses related variables */ WINDOW *savescr = popupWindow (width, height); wattrset (savescr, color_term ? COLOR_PAIR(2) | A_BOLD : A_NORMAL); /***** set bg color of the dialog */ /***** * draw a box around the dialog window * and empty it. *****/ werase (savescr); box (savescr, 0, 0); for (i = 1; i < width-1; i++) for (j = 1; j < height-1; j++) mvwaddch(savescr, j, i, ' '); /***** dialog header */ mvwaddstr(savescr, 1, 2, "Save Configuration:"); mvwaddseparator(savescr, 2, width); /***** dialog message */ mvwaddstr(savescr, 4, 2, "Your configuration will be saved to"); mvwaddstrcntr(savescr, 6, width, "~/.cvoicecontrol/config"); mvwaddstrcntr(savescr, 8, width, "Press any key to proceed ..."); wmove(savescr, 1, 22); /***** set cursor to an appropriate location */ wrefresh (savescr); /***** refresh the dialog */ getch(); /***** wait for keyboard reaction */ /***** clear dialog */ for (i = 1; i < width-1; i++) for (j = 3; j < height-1; j++) mvwaddch(savescr, j, i, ' '); wmove(savescr, 1, 22); /***** set cursor to an appropriate location */ wrefresh (savescr); /***** refresh the dialog */ /***** retrieve home directory */ home = getenv("HOME"); if (home != NULL) { FILE *f; /***** make sure the config_dir "~/.cvoicecontrol/" exists */ config_dir = malloc(strlen(home) + strlen("/.cvoicecontrol/") + 1); strcpy(config_dir, home); strcat(config_dir, "/.cvoicecontrol/"); if ((f = fopen(config_dir, "r")) == NULL) { char *command = malloc(strlen("mkdir ") + strlen(config_dir) + 1); strcpy(command, "mkdir "); strcat(command, config_dir); system(command); if ((f = fopen(config_dir, "r")) == NULL) { free(config_dir); config_dir = malloc(strlen("/tmp/") + 1); strcpy(config_dir, "/tmp/"); } free(command); } fclose(f); free(home); } else /***** couldn't retrieve home directory -> store results in /tmp/ */ { config_dir = malloc(strlen("/tmp/") + 1); strcpy(config_dir, "/tmp/"); } /***** tell user if home directory couldn't be retrieved and /tmp/ is used instead */ if (strcmp(config_dir, "/tmp/") == 0) { mvwaddstr(savescr, 4, 2, "Failed to retrieve your home directory,"); mvwaddstr(savescr, 5, 2, "please contact your local system admin!"); mvwaddstr(savescr, 6, 2, "Configuration will be stored to /tmp/ instead!"); wmove(savescr, 1, 22); /***** set cursor to an appropriate location */ wrefresh (savescr); /***** refresh the dialog */ getch(); /***** wait for keyboard reaction */ } /***** config_file = config_dir+"config" */ config_file = malloc(strlen(config_dir) + strlen("config") + 1); strcpy(config_file, config_dir); strcat(config_file, "config"); free (config_dir); if ((f = fopen(config_file, "w")) == NULL) /***** failed to write config file */ { /***** clear dialog */ for (i = 1; i < width-1; i++) for (j = 3; j < height-1; j++) mvwaddch(savescr, j, i, ' '); /***** dialog message */ mvwaddstr(savescr, 5, 2, "Failed to create your configuration file! Oops!"); mvwaddstr(savescr, 6, 2, "What's going on?"); mvwaddstrcntr(savescr, 8, width, "Press any key to return to menu ..."); wmove(savescr, 1, 22); /***** set cursor to an appropriate location */ wrefresh (savescr); /***** refresh the dialog */ getch(); /***** wait for keyboard reaction */ retval = 0; /***** set return value to ERROR */ goto saveConfigurationReturn; } /***** output configuration information to config file */ fprintf(f, "Mixer Device = %s\n", getMixer()); fprintf(f, "Audio Device = %s\n", getAudio()); fprintf(f, "Mic Level = %d\n", mic_level); fprintf(f, "IGain Level = %d\n", igain_level); fprintf(f, "Record Level = %d\n", rec_level); fprintf(f, "Stop Level = %d\n", stop_level); fprintf(f, "Silence Level = %d\n", silence_level); fprintf(f, "Channel Mean ="); for (i = 0; i < FEAT_VEC_SIZE; i++) fprintf(f, " %6.5f", channel_mean[i]); fprintf(f, "\n"); fclose(f); /***** clear dialog */ for (i = 1; i < width-1; i++) mvwaddch(savescr, 1, i, ' '); for (i = 1; i < width-1; i++) for (j = 3; j < height-1; j++) mvwaddch(savescr, j, i, ' '); /***** update dialog to tell user that the configuration has been saved successfully */ mvwaddstr(savescr, 1, 2, "Success!"); mvwaddstr(savescr, 4, 2, "Your configuration has been saved successfully to"); mvwaddstr(savescr, 5, 4, config_file); mvwaddstr(savescr, 7, 2, "CVoiceControl is now ready to use!"); mvwaddstrcntr(savescr, 9, width, "Press any key to return to menu ..."); retval = 1; /***** set return value to ok */ wmove(savescr, 1, 11); /***** set cursor to an appropriate location */ wrefresh (savescr); /***** refresh the dialog */ getch(); /***** wait for keyboard reaction */ saveConfigurationReturn: free(config_file); return(retval); }
Workflow::OutputBuffer* TrackWorkflow::getOutput( qint64 currentFrame, qint64 subFrame, bool paused ) { QReadLocker lock( m_clipsLock ); QMap<qint64, ClipWorkflow*>::iterator it = m_clips.begin(); QMap<qint64, ClipWorkflow*>::iterator end = m_clips.end(); bool needRepositioning; Workflow::OutputBuffer *ret = NULL; Workflow::Frame *frames[EffectsEngine::MaxFramesForMixer]; quint32 frameId = 0; bool renderOneFrame = false; if ( m_lastFrame == -1 ) m_lastFrame = currentFrame; { QMutexLocker lock2( m_renderOneFrameMutex ); if ( m_renderOneFrame == true ) { m_renderOneFrame = false; renderOneFrame = true; } } { // This is a bit hackish : when we want to pop a frame in renderOneFrame mode, // we also set the position to avoid the stream to be missynchronized. // this frame setting will most likely toggle the next condition as true // If this condition is true, the clipworkflow will flush all its buffer // as we need to resynchronize after a setTime, so this condition has to remain // false. Easy ain't it? if ( paused == true && subFrame != m_lastFrame && renderOneFrame == false) needRepositioning = true; else needRepositioning = ( abs( subFrame - m_lastFrame ) > 1 ) ? true : false; } memset( frames, 0, sizeof(*frames) * EffectsEngine::MaxFramesForMixer ); while ( it != end ) { qint64 start = it.key(); ClipWorkflow* cw = it.value(); //Is the clip supposed to render now? if ( start <= currentFrame && currentFrame <= start + cw->getClipHelper()->length() ) { ret = renderClip( cw, currentFrame, start, needRepositioning, renderOneFrame, paused ); if ( m_trackType == Workflow::VideoTrack ) { frames[frameId] = static_cast<Workflow::Frame*>( ret ); ++frameId; } } //Is it about to be rendered? else if ( start > currentFrame && start - currentFrame < TrackWorkflow::nbFrameBeforePreload ) preloadClip( cw ); //Is it supposed to be stopped? else stopClipWorkflow( cw ); ++it; } //Handle mixers: if ( m_trackType == Workflow::VideoTrack ) { EffectHelper* mixer = getMixer( currentFrame ); if ( mixer != NULL && frames[0] != NULL ) //There's no point using the mixer if there's no frame rendered. { //FIXME: We don't handle mixer3 yet. mixer->effectInstance()->process( currentFrame * 1000.0 / m_fps, frames[0]->buffer(), frames[1] != NULL ? frames[1]->buffer() : MainWorkflow::getInstance()->blackOutput()->buffer(), NULL, m_mixerBuffer->buffer() ); m_mixerBuffer->ptsDiff = frames[0]->ptsDiff; ret = m_mixerBuffer; } else //If there's no mixer, just use the first frame, ignore the rest. It will be cleaned by the responsible ClipWorkflow. ret = frames[0]; //Now handle filters : quint32 *newFrame = applyFilters( ret != NULL ? static_cast<const Workflow::Frame*>( ret ) : MainWorkflow::getInstance()->blackOutput(), currentFrame, currentFrame * 1000.0 / m_fps ); if ( newFrame != NULL ) { if ( ret != NULL ) static_cast<Workflow::Frame*>( ret )->setBuffer( newFrame ); else //Use the m_mixerBuffer as the frame to return. Ugly but avoid another attribute. { m_mixerBuffer->setBuffer( newFrame ); ret = m_mixerBuffer; } } } m_lastFrame = subFrame; return ret; }