void DIALOG_DRC_CONTROL::OnStartdrcClick( wxCommandEvent& event )
{
    wxString reportName;

    bool make_report = m_CreateRptCtrl->IsChecked();

    if( make_report )      // Create a rpt file
    {
        reportName = m_RptFilenameCtrl->GetValue();

        if( reportName.IsEmpty() )
        {
            wxCommandEvent dummy;
            OnButtonBrowseRptFileClick( dummy );
        }

        if( !reportName.IsEmpty() )
            reportName = makeValidFileNameReport();
    }

    SetDrcParmeters();
    m_tester->SetSettings( true,        // Pad to pad DRC test enabled
                           true,        // unconnected pads DRC test enabled
                           true,        // DRC test for zones enabled
                           true,        // DRC test for keepout areas enabled
                           reportName, make_report );

    DelDRCMarkers();

    wxBeginBusyCursor();

    // run all the tests, with no UI at this time.
    m_Messages->Clear();
    wxSafeYield();                          // Allows time slice to refresh the m_Messages window
    m_brdEditor->GetBoard()->m_Status_Pcb = 0; // Force full connectivity and ratsnest recalculations
    m_tester->RunTests(m_Messages);
    m_Notebook->ChangeSelection( 0 );       // display the 1at tab "...Markers ..."


    // Generate the report
    if( !reportName.IsEmpty() )
    {
        if( writeReport( reportName ) )
        {
            wxString        msg;
            msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) );

            wxString        caption( _( "Disk File Report Completed" ) );
            wxMessageDialog popupWindow( this, msg, caption );
            popupWindow.ShowModal();
        }
        else
            DisplayError( this, wxString::Format( _( "Unable to create report file '%s' "),
                          GetChars( reportName ) ) );
    }

    wxEndBusyCursor();

    RedrawDrawPanel();
}
Esempio n. 2
0
void DIALOG_DRC_CONTROL::OnListUnconnectedClick( wxCommandEvent& event )
{
    wxString reportName;

    bool make_report = m_CreateRptCtrl->IsChecked();

    if( make_report )      // Create a file rpt
    {
        reportName = m_RptFilenameCtrl->GetValue();

        if( reportName.IsEmpty() )
        {
            wxCommandEvent junk;
            OnButtonBrowseRptFileClick( junk );
        }

        if( !reportName.IsEmpty() )
            reportName = makeValidFileNameReport();
    }

    SetDrcParmeters();

    m_tester->SetSettings( true,        // Pad to pad DRC test enabled
                           true,        // unconnected pads DRC test enabled
                           true,        // DRC test for zones enabled
                           true,        // DRC test for keepout areas enabled
                           reportName, make_report );

    DelDRCMarkers();

    wxBeginBusyCursor();

    m_Messages->Clear();
    m_tester->ListUnconnectedPads();

    m_Notebook->ChangeSelection( 1 );       // display the 2nd tab "Unconnected..."

    // Generate the report
    if( !reportName.IsEmpty() )
    {
        if( writeReport( reportName ) )
        {
            wxString        msg;
            msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) );
            wxString        caption( _( "Disk File Report Completed" ) );
            wxMessageDialog popupWindow( this, msg, caption );
            popupWindow.ShowModal();
        }
        else
            DisplayError( this, wxString::Format( _( "Unable to create report file '%s' "),
                          GetChars( reportName ) ) );
    }

    wxEndBusyCursor();

    /* there is currently nothing visible on the DrawPanel for unconnected pads
     *  RedrawDrawPanel();
     */
}
Esempio n. 3
0
void DIALOG_DRC_CONTROL::OnStartdrcClick( wxCommandEvent& event )
{
    wxString reportName;

    if( m_CreateRptCtrl->IsChecked() )      // Create a file rpt
    {
        reportName = m_RptFilenameCtrl->GetValue();

        if( reportName.IsEmpty() )
        {
            wxCommandEvent junk;
            OnButtonBrowseRptFileClick( junk );
        }

        reportName = m_RptFilenameCtrl->GetValue();
    }

    SetDrcParmeters();

    m_tester->SetSettings( true,        // Pad to pad DRC test enabled
                           true,        // unconnected pdas DRC test enabled
                           true,        // DRC test for zones enabled
                           true,        // DRC test for keepout areas enabled
                           reportName, m_CreateRptCtrl->IsChecked() );

    DelDRCMarkers();

    wxBeginBusyCursor();

    // run all the tests, with no UI at this time.
    m_Messages->Clear();
    wxSafeYield();                          // Allows time slice to refresh the m_Messages window
    m_tester->m_pcb->m_Status_Pcb = 0;      // Force full connectivity and ratsnest recalculations
    m_tester->RunTests(m_Messages);

    m_Notebook->ChangeSelection( 0 );       // display the 1at tab "...Markers ..."


    // Generate the report
    if( !reportName.IsEmpty() )
    {
        FILE* fp = wxFopen( reportName, wxT( "w" ) );
        writeReport( fp );
        fclose( fp );

        wxString        msg;
        msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) );

        wxString        caption( _( "Disk File Report Completed" ) );
        wxMessageDialog popupWindow( this, msg, caption );

        popupWindow.ShowModal();
    }

    wxEndBusyCursor();

    RedrawDrawPanel();
}
int safeExit()
{
  int retval = 0;  /***** return value */

  int width = 45, height = 11, i, j;               /***** ncurses related variables */
  WINDOW *resetscr = popupWindow (width, height);

  wattrset (resetscr, color_term ? COLOR_PAIR(3) | A_BOLD : A_REVERSE); /***** set bg color of the dialog */

  /*****
   * draw a box around the dialog window
   * and empty it.
   *****/
  werase(resetscr);
  box (resetscr, 0, 0);
  for (i = 1; i < width-1; i++)
    for (j = 1; j < height-1; j++)
      mvwaddch(resetscr, j, i, ' ');

  /***** dialog header */

  mvwaddstr(resetscr, 1, 2, "Warning!");
  mvwaddseparator(resetscr, 2, width);

  /***** dialog message */

  mvwaddstr(resetscr, 4, 2,"You did not finish the configuration");
  mvwaddstr(resetscr, 5, 2,"process and no data has been written");
  mvwaddstr(resetscr, 6, 2,"to your configuration file. Do you");
  mvwaddstr(resetscr, 7, 2,"really want to quit!? Press 'y' to quit,");
  mvwaddstr(resetscr, 8, 2,"any other key to continue .....");

  wmove(resetscr, 1, 11);  /***** set cursor to an appropriate location */
  wrefresh (resetscr);     /***** refresh the dialog */

  if (getch() == 'y') /***** if user hits 'y' */
    retval = 1;       /***** return ok */
  else
    retval = 0;       /***** any other key -> don't quit program! */

  delwin(resetscr);   /***** delete ncurses dialog window */
  return(retval);
}
Esempio n. 5
0
void DIALOG_DRC_CONTROL::OnStartdrcClick( wxCommandEvent& event )
{
    wxString reportName, msg;

    bool make_report = m_CreateRptCtrl->IsChecked();

    if( make_report )      // Create a rpt file
    {
        reportName = m_RptFilenameCtrl->GetValue();

        if( reportName.IsEmpty() )
        {
            wxCommandEvent dummy;
            OnButtonBrowseRptFileClick( dummy );
        }

        if( !reportName.IsEmpty() )
            reportName = makeValidFileNameReport();
    }

    SetDrcParmeters();
    m_tester->m_doZonesTest            = m_cbReportTracksToZonesErrors->GetValue();
    m_tester->m_rptFilename            = reportName;
    m_tester->m_doCreateRptFile        = make_report;
    m_tester->m_refillZones            = m_cbRefillZones->GetValue();
    m_tester->m_drcInLegacyRoutingMode = false;
    m_tester->m_reportAllTrackErrors   = m_cbReportAllTrackErrors->GetValue();
    m_tester->m_testFootprints         = m_cbTestFootprints->GetValue();

    DelDRCMarkers();

    wxBeginBusyCursor();
    wxWindowDisabler disabler;

    // run all the tests, with no UI at this time.
    m_Messages->Clear();
    wxSafeYield();                             // Allows time slice to refresh the Messages
    m_brdEditor->GetBoard()->m_Status_Pcb = 0; // Force full connectivity and ratsnest calculations
    m_tester->RunTests(m_Messages);
    m_Notebook->ChangeSelection( 0 );          // display the "Problems/Markers" tab

    // Generate the report
    if( !reportName.IsEmpty() )
    {
        if( writeReport( reportName ) )
        {
            msg.Printf( _( "Report file \"%s\" created" ), GetChars( reportName ) );
            wxMessageDialog popupWindow( this, msg, _( "Disk File Report Completed" ) );
            popupWindow.ShowModal();
        }
        else
        {
            msg.Printf( _( "Unable to create report file \"%s\"" ), GetChars( reportName ) );
            DisplayError( this, msg );
        }
    }

    wxEndBusyCursor();

    RedrawDrawPanel();
}
int estimateChannelMean()
{
  int result;
  int retval = 0;  /***** return value */

  int width = 45, height = 11, i, j;               /***** ncurses related variables */
  WINDOW *channelscr = popupWindow (width, height);

  wattrset (channelscr, 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 (channelscr);
  box (channelscr, 0, 0);
  for (i = 1; i < width-1; i++)
    for (j = 1; j < height-1; j++)
      mvwaddch(channelscr, j, i, ' ');

  /***** dialog header */

  mvwaddstr(channelscr, 1, 2, "Estimating Channel Characteristics:");
  mvwaddseparator(channelscr, 2, width);

  /***** dialog message */

  mvwaddstr(channelscr, 4, 2, "I'll calculate the characteristics of");
  mvwaddstr(channelscr, 5, 2, "the recording channel now. Please remain");
  mvwaddstr(channelscr, 6, 2, "silent until I say I'm done:");
  mvwaddstrcntr(channelscr, 8, width, "Press any key to start ...");
  wmove(channelscr, 1, 38);  /***** set cursor to an appropriate location */
  wrefresh (channelscr);     /***** 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(channelscr, j, i, ' ');

  /***** update dialog */

  mvwaddstrcntr(channelscr, 5, width, "stand by ...");
  wmove(channelscr, 1, 38);  /***** set cursor to an appropriate location */
  wrefresh (channelscr);     /***** refresh the dialog */

  if (openAudio() == AUDIO_ERR)
  {
    /*****
     * if the audio device could not be opened,
     * show a warning dialog and return to main menu
     *****/

    /***** clear dialog */

    for (i = 1; i < width-1; i++)
      mvwaddch(channelscr, 1, i, ' ');
    for (i = 1; i < width-1; i++)
      for (j = 3; j < height-1; j++)
	mvwaddch(channelscr, j, i, ' ');

    /***** show header and message */

    mvwaddstr(channelscr, 1, 2, "Warning!");

    mvwaddstr(channelscr, 5, 2, "Failed to open sound device!!");
    mvwaddstrcntr(channelscr, 8, width, "Press any key to return to menu ...");
    wmove(channelscr, 1, 11);  /***** set cursor to an appropriate location */
    wrefresh (channelscr);     /***** refresh the dialog */
    getch();                   /***** wait for keyboard reaction */

    retval = 0;                /***** set return value to ERROR */
    goto estimateChannelMeanReturn;
  }

  result = calculateChannelMean(); /***** calculate the characteristics of the recording channel */

  closeAudio(); /***** disconnect from the microphone */

  /***** clear dialog */

  for (i = 1; i < width-1; i++)
    mvwaddch(channelscr, 1, i, ' ');
  for (i = 1; i < width-1; i++)
    for (j = 3; j < height-1; j++)
      mvwaddch(channelscr, j, i, ' ');

  if (result == AUDIO_ERR)
  {
    /***** if an error occurred during the calculation of the channel mean ... */

    retval = 0; /***** set return value to ERROR */

    /***** dialog header and message */

    mvwaddstr(channelscr, 1, 2, "Error!");

    mvwaddstr(channelscr, 3, 2, "I didn't manage to estimate the channel");
    mvwaddstr(channelscr, 4, 2, "characteristics for some unknown reason!");
    mvwaddstr(channelscr, 5, 2, "Make sure that no application uses the");
    mvwaddstr(channelscr, 6, 2, "sound card and then try again!");
    mvwaddstrcntr(channelscr, 8, width, "Press any key to return to menu ...");

    wmove(channelscr, 1, 9);  /***** set cursor to an appropriate location */
    wrefresh (channelscr);     /***** refresh the dialog */
    getch();                  /***** wait for keyboard reaction */
  }
  else /***** channel mean calculation was ok */
  {
    retval = 1; /***** set return value to ok */

    /***** dialog header and message */

    mvwaddstr(channelscr, 1, 2, "Success!");

    mvwaddstr(channelscr, 4, 2, "You may stop talking now! The channel");
    mvwaddstr(channelscr, 5, 2, "characteristics have been estimated!");
    mvwaddstrcntr(channelscr, 8, width, "Press any key to return to menu ...");

    wmove(channelscr, 1, 11);  /***** set cursor to an appropriate location */
    wrefresh (channelscr);     /***** refresh the dialog */
    getch();                  /***** wait for keyboard reaction */
  }

 estimateChannelMeanReturn:
  delwin(channelscr);   /***** delete ncurses dialog window */
  return(retval);
}
int calculateThresholds()
{
  int samples;
  int max = 0, value;
  int silence_level_tmp; /***** need int (instead of short) to sum up several values */
  int silence_max;

  int retval = 0;  /***** return value */

  int width = 45, height = 11, i, j;               /***** ncurses related variables */
  WINDOW *threshscr = popupWindow (width, height);

  /*****
   * first step: define silence level
   *****/

  wattrset (threshscr, 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 (threshscr);
  box (threshscr, 0, 0);
  for (i = 1; i < width-1; i++)
    for (j = 1; j < height-1; j++)
      mvwaddch(threshscr, j, i, ' ');

  /***** dialog header */

  mvwaddstr(threshscr, 1, 2, "Calculate Thresholds:");
  mvwaddseparator(threshscr, 2, width);

  /***** dialog message */

  mvwaddstr(threshscr, 3, 2, "I'll calculate some values now. First,");
  mvwaddstr(threshscr, 4, 2, "I need to know the silence level of the");
  mvwaddstr(threshscr, 5, 2, "microphone. Please be silent until I");
  mvwaddstr(threshscr, 6, 2, "say I'm done:");
  mvwaddstrcntr(threshscr, 8, width, "Press any key to start ...");

  wmove(threshscr, 1, 24);  /***** set cursor to an appropriate location */
  wrefresh (threshscr);     /***** refresh the dialog */
  getch();                  /***** wait for keyboard reaction */

  /***** clear dialog window */

  for (i = 1; i < width-1; i++)
    for (j = 3; j < height-1; j++)
      mvwaddch(threshscr, j, i, ' ');

  mvwaddstrcntr(threshscr, 5, width, "stand by ..."); /***** update dialog */
  wmove(threshscr, 1, 24);  /***** set cursor to an appropriate location */
  wrefresh (threshscr);     /***** refresh the dialog */

  if (openAudio() == AUDIO_ERR)
  {
    /*****
     * if the audio device could not be opened,
     * show a warning dialog and return to main menu
     *****/

    /***** clear dialog */

    for (i = 1; i < width-1; i++)
      mvwaddch(threshscr, 1, i, ' ');
    for (i = 1; i < width-1; i++)
      for (j = 3; j < height-1; j++)
	mvwaddch(threshscr, j, i, ' ');

    /***** show header and message */

    mvwaddstr(threshscr, 1, 2, "Warning!");

    mvwaddstr(threshscr, 5, 2, "Failed to open sound device!!");
    mvwaddstrcntr(threshscr, 8, width, "Press any key to return to menu ...");
    wmove(threshscr, 1, 11);  /***** set cursor to an appropriate location */
    wrefresh (threshscr);     /***** refresh the dialog */
    getch();                  /***** wait for keyboard reaction */

    retval = 0;               /***** set return value to ERROR */
    goto calculateThresholdsReturn;
  }

  /*****
   * define the silence_level as the average of a specified number
   * of subsequent block maxima
   *****/
  samples           = 40;
  silence_level_tmp = 0;
  silence_max   = 0;
  for (i = 0; i < samples; i++)
  {
    int value = getBlockMax(); /***** should check for value == -1 (case of an error!) */
      silence_level_tmp += value;
    if (value > silence_max)
      silence_max = value;
  }
  silence_level_tmp /= samples;
  silence_level = silence_level_tmp;

  /***** rec_level and stop_level */

  /***** clear dialog */

  for (i = 1; i < width-1; i++)
    for (j = 3; j < height-1; j++)
      mvwaddch(threshscr, j, i, ' ');

  /***** update dialog */

  mvwaddstr(threshscr, 3, 2, "Now, I'll define the thresholds at which");
  mvwaddstr(threshscr, 4, 2, "to start/stop recording. Please talk");
  mvwaddstr(threshscr, 5, 2, "at a conversational volume (speech");
  mvwaddstr(threshscr, 6, 2, "recognition volume) until I say stop!");
  mvwaddstrcntr(threshscr, 8, width, "Press any key to start ...");

  wmove(threshscr, 1, 24);  /***** set cursor to an appropriate location */
  wrefresh (threshscr);     /***** 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(threshscr, j, i, ' ');

  mvwaddstrcntr(threshscr, 5, width, "keep on talking ..."); /***** update dialog */
  wmove(threshscr, 1, 24);  /***** set cursor to an appropriate location */
  wrefresh (threshscr);     /***** refresh the dialog */

  /***** get maximum value 'max' of a prespecified number of subsequent block maxima */

  samples = 80;
  for (i = 0; i < samples; i++)
  {
    value = getBlockMax(); /***** should check for value == -1 (case of an error!) */
    if (value > max)
      max = value;
  }

  /***** set the rec_level  to be the average of silence_level and 'max' */
  /***** set the stop_level to be three quarters of silence_level plus one quarter of 'max' */

  rec_level =  (silence_level + max) / 2;
  stop_level = (3*silence_level + max) / 4;

  closeAudio(); /***** disconnect from microphone */

  /***** clear dialog */

  for (i = 1; i < width-1; i++)
    mvwaddch(threshscr, 1, i, ' ');
  for (i = 1; i < width-1; i++)
    for (j = 3; j < height-1; j++)
      mvwaddch(threshscr, j, i, ' ');

  /***** check that the thresholds are reasonable */

  if (silence_level >= stop_level ||
      silence_max >= stop_level    ||
      silence_level < 0 || stop_level < 0 || rec_level < 0)
  {
    /***** dialog header */

    mvwaddstr(threshscr, 1, 2, "Warning!");

    /***** dialog message */

    mvwaddstr(threshscr, 4, 2, "You have to run this step once again!");
    mvwaddstr(threshscr, 5, 2, "The calculated thresholds don't look");
    mvwaddstr(threshscr, 6, 2, "reasonable to me!");
    mvwaddstrcntr(threshscr, 8, width, "Press any key to return to menu ...");
    wmove(threshscr, 1, 11);  /***** set cursor to an appropriate location */
    wrefresh (threshscr);     /***** refresh the dialog */
    getch();                  /***** wait for keyboard reaction */

    retval = 0;
  }
  else /***** the values seem ok */
  {
    /***** dialog header */

    mvwaddstr(threshscr, 1, 2, "Success!");

    /***** dialog message */

    mvwaddstr(threshscr, 4, 2, "You may stop talking now! The thresholds");
    mvwaddstr(threshscr, 5, 2, "have been defined!");

    /* Debugging stuff:
       mvwaddint(threshscr, 6, 2, silence_level);
       mvwaddint(threshscr, 6,10, stop_level);
       mvwaddint(threshscr, 6,20, rec_level);
       */
    
    mvwaddstrcntr(threshscr, 8, width, "Press any key to return to menu ...");

    wmove(threshscr, 1, 11);  /***** set cursor to an appropriate location */
    wrefresh (threshscr);     /***** refresh the dialog */
    getch();                  /***** wait for keyboard reaction */

    retval = 1; /***** set return value = ok */
  }

 calculateThresholdsReturn:
  delwin(threshscr);   /***** delete ncurses dialog window */
  return(retval);
}
int adjustMixerLevels()
{
  int mic_level    = 99; /***** initial values for Microphone and */

  int igain_level  = 0;  /***** Input Gain level */
  
  int max_sample   = 32500; /***** max 16-bit sample value coming from the sound card */

  int count;           /**** temporary variables */
  int max_gain;
  char tmp_string[10];

  int width = 45, height = 11, i, j;               /***** ncurses related variables */
  WINDOW *adjustscr = popupWindow (width, height);

  int retval = 0;  /***** return value */

  /* ***** display information */

  wattrset (adjustscr, 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 (adjustscr);
  box (adjustscr, 0, 0);
  for (i = 1; i < width-1; i++)
    for (j = 1; j < height-1; j++)
      mvwaddch(adjustscr, j, i, ' ');

  setMicLevel(mic_level);

  if (mixerHasIGain() == MIXER_OK)
  {
    igain_level = 1;
    setIGainLevel(igain_level); /***** set initial levels in mixer */
  }
  else
    goto no_igain;

  /***** dialog header */

  mvwaddstr(adjustscr, 1, 2, "Adjust Input Gain Level:");
  mvwaddseparator(adjustscr, 2, width);

  /***** dialog message */

  mvwaddstr(adjustscr, 3, 2, "Please grab your microphone and speak");
  mvwaddstr(adjustscr, 4, 2, "nonsense at a conversational volume");
  mvwaddstr(adjustscr, 5, 2, "(speech recognition volume) until I");
  mvwaddstr(adjustscr, 6, 2, "say stop:");
  mvwaddstrcntr(adjustscr, 8, width, "Press any key to start ...");

  wmove(adjustscr, 1, 27);  /***** set cursor to an appropriate location */
  wrefresh (adjustscr);     /***** refresh the dialog */
  getch();                  /***** wait for keyboard reaction */

  /***** update dialog */

  mvwaddstr(adjustscr, 8, 2, "Current Gain Level:               ");
  sprintf(tmp_string, "%d", igain_level);
  mvwaddstr(adjustscr, 8, 22, tmp_string);

  wmove(adjustscr, 1, 27);  /***** set cursor to an appropriate location */
  wrefresh (adjustscr);     /***** refresh the dialog */

  count    = 0;
  max_gain = 0;

  if (openAudio() == AUDIO_ERR)
  {
    /*****
     * if the audio device could not be opened,
     * show a warning dialog and return to main menu
     *****/

    /***** empty dialog */

    for (i = 1; i < width-1; i++)
      mvwaddch(adjustscr, 1, i, ' ');
    for (i = 1; i < width-1; i++)
      for (j = 3; j < height-1; j++)
	mvwaddch(adjustscr, j, i, ' ');

    /***** show header and message */

    mvwaddstr(adjustscr, 1, 2, "Warning!");

    mvwaddstr(adjustscr, 5, 2, "Failed to open sound device!!");
    mvwaddstrcntr(adjustscr, 8, width, "Press any key to return to menu ...");
    wmove(adjustscr, 1, 11);  /***** set cursor to an appropriate location */
    wrefresh (adjustscr);     /***** refresh the dialog */
    getch();                  /***** wait for keyboard reaction */

    retval = 0;               /***** set return value to ERROR */
    goto adjustMixerLevelsReturn;
  }

  /***** repeat until the input gain level has been adjusted properly */

  while (1)
  {
    int max;          /***** maximum sample value in a sequence of audio samples */
    int samples = 10; /***** number of blocks to get from the audio device */

    count++;

    /*****
     * get the maximum values of 'samples' blocks of data from the sound card
     * the maximum of these values is stored in 'max'9
     *****/
    max = 0;
    for (i = 0; i < samples; i++)
    {
      int value = getBlockMax(); /***** should check for value == -1 (case of an error!) */
      if (value > max)
	max = value;
    }

    /***** max_gain holds the highest maximum sample found */

    if (max > max_gain)
      max_gain = max;

    if (count == 5) /***** after five iterations, check the value of 'max_gain' */
    {
      /*****
       * if max_gain is too low (i.e. it is between silence and low_volume)
       * the input gain level is increased
       *****/
      if (max_gain >= silence * max_sample && max_gain < low_volume * max_sample)
      {
	igain_level++;
	if (igain_level > 99)
	  igain_level = 99;
	setIGainLevel(igain_level);

	sprintf(tmp_string, "%d", igain_level); /***** update display of igain level */
	mvwaddstr(adjustscr, 8, 22, tmp_string);

	wmove(adjustscr, 1, 27);  /***** set cursor to an appropriate location */
	wrefresh (adjustscr);     /***** refresh the dialog */
      }
      /*****
       * if the level is above 'low_volume'
       * we assume that the input gain is high enough and break the current while loop
       *****/
      else if (max_gain >= low_volume * max_sample)
	break;

      /***** reset count and max_gain */

      count    = 0;
      max_gain = 0;
    }
  }
  closeAudio(); /***** disconnect from microphone */

  /***** update dialog window */

  for (i = 1; i < width-1; i++)
    for (j = 3; j < height-1; j++)
      mvwaddch(adjustscr, j, i, ' ');
  mvwaddstrcntr(adjustscr, 5, width, "STOP!!");
  mvwaddstrcntr(adjustscr, 8, width, "Press any key to continue ...");

  wmove(adjustscr, 1, 27);  /***** set cursor to an appropriate location */
  wrefresh (adjustscr);     /***** refresh the dialog */
  getch();                  /***** wait for keyboard reaction */

 no_igain:
  
  count = 0; /***** reset count */

  /***** adjusting microphone level */

  /***** dialog header */

  for (i = 1; i < width-1; i++)
    for (j = 3; j < height-1; j++)
      mvwaddch(adjustscr, j, i, ' ');
  mvwaddstr(adjustscr, 1, 2, "Adjust Microphone Level:");

  /***** dialog message */

  mvwaddstr(adjustscr, 3, 2, "Please grab your microphone and speak");
  mvwaddstr(adjustscr, 4, 2, "very loudly (laughing loudly is good)");
  mvwaddstr(adjustscr, 5, 2, "until I say stop:");
  mvwaddstrcntr(adjustscr, 8, width, "Press any key to start ...");

  wmove(adjustscr, 1, 27);  /***** set cursor to an appropriate location */
  wrefresh (adjustscr);     /***** refresh the dialog */
  getch();                  /***** wait for keyboard reaction */

  /***** update dialog */

  mvwaddstr(adjustscr, 8, 2, "Current Microphone Level:               ");
  sprintf(tmp_string, "%d", mic_level);
  mvwaddstr(adjustscr, 8, 28, tmp_string);

  wmove(adjustscr, 1, 27);  /***** set cursor to an appropriate location */
  wrefresh (adjustscr);     /***** refresh the dialog */

  if (openAudio() == AUDIO_ERR)
  {
    /*****
     * if the audio device could not be opened,
     * show a warning dialog and return to main menu
     *****/

    /***** empty dialog */

    for (i = 1; i < width-1; i++)
      mvwaddch(adjustscr, 1, i, ' ');
    for (i = 1; i < width-1; i++)
      for (j = 3; j < height-1; j++)
	mvwaddch(adjustscr, j, i, ' ');

    /***** show header and message */

    mvwaddstr(adjustscr, 1, 2, "Warning!");

    mvwaddstr(adjustscr, 5, 2, "Failed to open sound device!!");
    mvwaddstrcntr(adjustscr, 8, width, "Press any key to return to menu ...");
    wmove(adjustscr, 1, 11);  /***** set cursor to an appropriate location */
    wrefresh (adjustscr);     /***** refresh the dialog */
    getch();                  /***** wait for keyboard reaction */

    retval = 0;               /***** set return value to ERROR */
    goto adjustMixerLevelsReturn;
  }

  /***** repeat until the microphone level has been adjusted properly */

  while (1)
  {
    int max;         /***** maximum sample value in a sequence of audio samples */
    int samples = 4; /***** number of blocks to get from the audio device */

    /*****
     * get the maximum values of 'samples' blocks of data from the sound card
     * the maximum of these values is stored in 'max'9
     *****/
    max = 0;
    for (i = 0; i < samples; i++)
    {
      int value = getBlockMax(); /***** should check for value == -1 (case of an error!) */
      if (value > max)
	max = value;
    }

    if (max >= high_volume * max_sample)
    {
      /*****
       * if max is too high (i.e. above high_volume)
       * the microphone level is dereased
       *****/
      mic_level -= 1;
      if (mic_level < 5)
	mic_level = 5;
      setMicLevel(mic_level);

      count = 0; /***** reset count */

      sprintf(tmp_string, "%d", mic_level); /***** update display of mic level */
      mvwaddstr(adjustscr, 8, 28, tmp_string);

      wmove(adjustscr, 1, 27);  /***** set cursor to an appropriate location */
      wrefresh (adjustscr);     /***** refresh the dialog */
    }
    else if (max >= silence * max_sample)
    {
      /*****
       * if there is a signal above silence coming in,
       * increase count
       * if count >= a specified constant, we assume that
       * the microphone level is not too high any more and
       * thus, break the while loop
       ****/
      count++;

      if (count >= 20)
	break;
    }
    else
    {
      /*****
       * this was a silence frame, decrease count if it is > 0
       *****/
      if (count > 0)
	count--;
    }
  }
  closeAudio(); /***** disconnect from microphone */

  /***** clear dialog window */

  for (i = 1; i < width-1; i++)
    mvwaddch(adjustscr, 1, i, ' ');
  for (i = 1; i < width-1; i++)
    for (j = 3; j < height-1; j++)
      mvwaddch(adjustscr, j, i, ' ');

  /***** check the mixer values, to make sure they look reasonable */

  if (igain_level >= mic_level ||
      mic_level < MIN_REASONABLE_MIC_LEVEL ||
      igain_level > MAX_REASONABLE_IGAIN_LEVEL)
  {
    int pos = 0;

    /***** dialog header */

    mvwaddstr(adjustscr, 1, 2, "Warning!");

    /***** dialog message */

    mvwaddstr(adjustscr, 3, 2, "You have to run this step once again!");
    mvwaddstr(adjustscr, 4, 2, "The estimated level results don't look");
    mvwaddstr(adjustscr, 5, 2, "reasonable to me!");
    if (igain_level >= mic_level || igain_level > MAX_REASONABLE_IGAIN_LEVEL)
      mvwaddstr(adjustscr, 6+(pos++), 2, "- Input gain level looks too high!");
    if (igain_level >= mic_level || mic_level < MIN_REASONABLE_MIC_LEVEL)
      mvwaddstr(adjustscr, 6+(pos++), 2, "- Microphone level looks too low?!");
    mvwaddstrcntr(adjustscr, 8, width, "Press any key to return to menu ...");

    wmove(adjustscr, 1, 11);  /***** set cursor to an appropriate location */
    wrefresh (adjustscr);     /***** refresh the dialog */
    getch();                  /***** wait for keyboard reaction */

    retval = 0;
  }
  else /***** the mixer values seem ok */
  {
    /***** dialog header */

    mvwaddstr(adjustscr, 1, 2, "Success!");

    /***** dialog message */

    mvwaddstrcntr(adjustscr, 4, width, "The mixer levels have been");
    mvwaddstrcntr(adjustscr, 5, width, "adjusted successfully!");
    mvwaddstrcntr(adjustscr, 8, width, "Press any key to return to menu ...");

    wmove(adjustscr, 1, 11);  /***** set cursor to an appropriate location */
    wrefresh (adjustscr);     /***** refresh the dialog */
    getch();                  /***** wait for keyboard reaction */

    retval = 1; /***** set return value = ok */
  }

 adjustMixerLevelsReturn:
  delwin(adjustscr);   /***** delete ncurses dialog window */
  return(retval);
}
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);
}
Esempio n. 10
0
int selectAudio()
{
  int top = 0, current = 0; /***** selection menu related variables */
  int max_view = 9;

  int retval = 0;           /***** return value */

  int request_finish = 0;   /***** leave current dialog, if request_finish is set to 1 */

  int width = 45, height = 15, i, j;               /***** ncurses related variables */
  WINDOW *audioscr = popupWindow (width, height);

  while (!request_finish)
  {
    wattrset (audioscr, 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 (audioscr);
    box (audioscr, 0, 0);
    for (i = 1; i < width-1; i++)
      for (j = 1; j < height-1; j++)
	mvwaddch(audioscr, j, i, ' ');

    /***** dialog header */

    mvwaddstr(audioscr, 1, 2, "Select Audio Device:");
    mvwaddseparator(audioscr, 2, width);

    /***** selection area */

    for (i = 0; i < MIN2(audio_devices->count, max_view); i++)
    {
      setHighlight(audioscr, ok, i == current);
      mvwaddstr(audioscr, 4+i, 4, "/dev/");
      waddstr(audioscr, audio_devices->name[top+i]);
    }
    wattroff(audioscr, A_REVERSE);

    /*****
     * show up/down arrow to the left, if more items are available
     * than can be displayed
     *****/
    if (top > 0)
    {
      mvwaddch(audioscr,4, 2, ACS_UARROW);
      mvwaddch(audioscr,4+1, 2, ACS_VLINE);
    }
    if (audio_devices->count > max_view && top+max_view <= audio_devices->count-1)
    {
      mvwaddch(audioscr,4+max_view-2, 2, ACS_VLINE);
      mvwaddch(audioscr,4+max_view-1, 2, ACS_DARROW);
    }

    wmove(audioscr, 1, 23);  /***** set cursor to an appropriate location */
    wrefresh (audioscr);     /***** refresh the dialog */

    /* process the command keystroke */

    switch(getch())
    {
    case KEY_UP:   /***** cursor up */
      if (current > 0)
	current--;
      else
	top = (top > 0 ? top-1 : 0);
      break;
    case KEY_DOWN: /***** cursor down */
      if (top+current < audio_devices->count-1)
      {
	if (current < max_view-1)
	 current++;
	else
	  top++;
      }
      break;
    case ESCAPE:   /***** Hit Escape to leave dialog */
      retval = AUDIO_ERR;
      request_finish = 1;
      break;
    case ENTER:   /***** make selection with Enter or Space bar */
    case BLANK:
      setAudio(audio_devices->name[top+current]); /***** set audio device to highlighted item */
      retval = initAudio();                       /***** retval is ok, if initAudio() returned ok */
      if (retval == AUDIO_ERR)
	noAudio();
      request_finish = 1;                         /***** leave dialog */
      break;
    }
  }

  delwin(audioscr);   /***** delete ncurses dialog window */
  return(retval);
}
Esempio n. 11
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);
}
Esempio n. 12
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 selection related variables */
  int menu_items      = 5;
  enum state status[] = {active, active, active, active, active};

  WINDOW *mainscr; /***** ncurses related variables */
  int i, j;

  /***** load configuration */

  if (loadConfiguration() == 0)
  {
    fprintf(stderr, "couldn't load configuration!");
    exit(-1);
  }

  /***** setup speaker model */

  model = (Model *) malloc(sizeof(Model));
  initModel(model);

  /***** 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");
    mvwaddstrrght(mainscr, 1, COLS, "(c) 2000 Daniel Kiecza");
    mvwaddseparator(mainscr, 2, COLS);
    mvwaddstrcntr(mainscr, 3, COLS, "Speaker Model Editor");
    mvwaddseparator(mainscr, 4, COLS);

    /***** display main menu */

    mvwaddstr(mainscr, 5, 2, "Please Select:");
    mvwaddstr(mainscr, 5, 35, "Model:");

    if (model_file_name != NULL)
      mvwaddstr(mainscr, 5, 42, model_file_name);
    else
      mvwaddstr(mainscr, 5, 42, "(none)");

    setHighlight(mainscr, status[0], current == 0);
    mvwaddstr(mainscr,  7, 5,"New Speaker Model");
    setHighlight(mainscr, status[1], current == 1);
    mvwaddstr(mainscr,  8, 5,"Load Speaker Model");
    setHighlight(mainscr, status[2], current == 2);
    mvwaddstr(mainscr,  9, 5,"Edit Speaker Model");
    setHighlight(mainscr, status[3], current == 3);
    mvwaddstr(mainscr, 10, 5,"Save Speaker Model");
    setHighlight(mainscr, status[4], current == 4);
    mvwaddstr(mainscr, 11, 5,"Exit");

    wmove(mainscr, 5, 17); /***** move cursor to an appropriate location */
    wrefresh(mainscr);     /***** refresh dialog window */

    /* process the command keystroke */

    switch(getch())
    {
    case KEY_UP:   /***** cursor up */
      current = (current == 0 ? menu_items - 1 : current - 1);
      break;
    case KEY_DOWN: /***** cursor down */
      current = (current == menu_items-1 ? 0 : current + 1);
      break;
    case ENTER:    /***** handle menu selections */
    case BLANK:
      switch (current)
      {
      case 0: /***** reset model, but make sure no data gets lost */
	safeResetModel();
	break;
      case 1: /***** load model */
	if (safeResetModel())
	{
	  int max_file_length = 80;
	  char *file_name;
	  char show_file_name[82];
	
	  int width = 45, height = 11, i, j;             /***** ncurses related variables */
	  WINDOW *loadscr = popupWindow (width, height);

	  wattrset (loadscr, 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 (loadscr);
	  box (loadscr, 0, 0);
	  for (i = 1; i < width-1; i++)
	    for (j = 1; j < height-1; j++)
	      mvwaddch(loadscr, j, i, ' ');

	  /***** dialog header */
	
	  mvwaddstr(loadscr, 1, 2, "Please enter file name:");
	  mvwaddseparator(loadscr, 2, width);

	  wrefresh (loadscr);
	  wattroff(loadscr, A_BOLD);
	
	  file_name = wstringInput(loadscr, 4, 2, max_file_length, width-5, ""); /***** get file name */

	  /*****
	   * show_file_name is set to "file" if the file_name is longer
	   * than 15 characters. That way dialog messages stay within the
	   * boundaries of the dialog
	   *****/
	  if (strlen(file_name) <= 15)
	    strcpy(show_file_name, file_name);
	  else
	    strcpy(show_file_name, "file");

	  /***** display information that model is being loaded */
	
	  wattrset (loadscr, color_term ? COLOR_PAIR(2) | A_BOLD : A_NORMAL);
	  mvwaddstr(loadscr, 6,  2, "Loading");
	  mvwaddstr(loadscr, 6, 10, show_file_name);
	  mvwaddstr(loadscr, 6, 11+strlen(show_file_name), "...");
	  wrefresh(loadscr);

	  if (loadModel(model, file_name, 1) == 1) /***** loading model is successful */
	  {
	    mvwaddstr(loadscr, 6, 15+strlen(show_file_name), "success!");

	    /***** set variable model_file_name */
	
	    if (strstr(file_name, model_file_extension) !=
		file_name+strlen(file_name)-strlen(model_file_extension))
	    {
	      model_file_name = malloc(strlen(file_name) + strlen(model_file_extension) + 1);
	      strcpy(model_file_name, file_name);
	      strcat(model_file_name, model_file_extension);
	    }
	    else
	    {
	      model_file_name = malloc(strlen(file_name) + 1);
	      strcpy(model_file_name, file_name);
	    }
	  }
	  else /***** loading model has failed */
	    mvwaddstr(loadscr, 6, 15+strlen(show_file_name), "failed!");
	  mvwaddstrcntr(loadscr, 8, width,"Press <Space> to return to menu ...");
	  wrefresh(loadscr); /***** refresh dialog */
	  getch();           /***** wait for keyboard input */

	  delwin(loadscr);   /***** delete ncurses dialog window */
	  free (file_name);
	}
	break;
      case 2: /***** edit the speaker model */
	editModel();
	break;
      case 3: /***** save the speaker model */
	if (model->number_of_items > 0)
	{
	  char *file_name;
	  int max_file_length = 84;
	
	  int width = 45, 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, ' ');

	  /***** display dialog header */
	
	  mvwaddstr(savescr, 1, 2, "Please enter file name:");
	  mvwaddseparator(savescr, 2, width);

	  wrefresh (savescr);
	  wattroff(savescr, A_BOLD);
	
	  file_name = wstringInput(savescr, 4, 2, max_file_length,
				   width-5, model_file_name); /***** get file name */
	
	  /***** display information that model is being saved */

	  wattrset (savescr, color_term ? COLOR_PAIR(2) | A_BOLD : A_NORMAL);
	  mvwaddstr(savescr, 6,  2, "Saving ...");
	  wrefresh(savescr);

	  if (saveModel(model, file_name) == 1) /***** saving successful */
	  {
	    mvwaddstr(savescr, 6, 13, "success!");

	    /***** update model_file_name if necessary */

	    if (model_file_name != NULL && strcmp(model_file_name, file_name) != 0)
	    {
	      free(model_file_name);
	      model_file_name = malloc(strlen(file_name) + 1);
	      strcpy(model_file_name, file_name);
	    }
	
	    modified = 0; /***** switch modified to '0' */
	  }
	  else /***** saving failed */
	    mvwaddstr(savescr, 6, 13, "failed!");
	  mvwaddstrcntr(savescr, 8, width,"Press <Space> to return to menu ...");
	  wrefresh(savescr); /***** refresh dialog */
	  getch();           /***** wait for keyboard input */

	  delwin(savescr);   /***** delete ncurses dialog window */
	  free (file_name);
	}
	break;
      case 4: /***** quit program */
	if (safeResetModel())
	{
	  wrefresh(mainscr);
  	  request_finish = 1;
	  delwin(mainscr);   /***** delete ncurses dialog window */
	}
	break;
      }
      break;
    }
  }

  endwin(); /***** wrap up ncurses stuff */
  exit(0);  /***** exit program */
}
Esempio n. 13
0
int safeResetModel()
{
  int retval = 0; /***** return value */

  /*****
   * if speaker model has been modified,
   * display a "warning" dialog to avoid an accidental loss of data
   *****/

  if (modified)
  {
    int width = 45, height = 11, i, j;               /***** ncurses related variables */
    WINDOW *resetscr = popupWindow (width, height);

    wattrset (resetscr, 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(resetscr);
    box (resetscr, 0, 0);
    for (i = 1; i < width-1; i++)
      for (j = 1; j < height-1; j++)
	mvwaddch(resetscr, j, i, ' ');

    /***** dialog header */

    mvwaddstr(resetscr, 1, 2, "Warning!");
    mvwaddseparator(resetscr, 2, width);

    /***** dialog message */

    mvwaddstr(resetscr, 4, 2,"You did not save the current model!");
    mvwaddstr(resetscr, 5, 2,"Press 'y' to proceed.  **Caution**");
    mvwaddstr(resetscr, 6, 2,"All data in the model will be lost!!");
    mvwaddstr(resetscr, 7, 2,"Press any other key to return to the");
    mvwaddstr(resetscr, 8, 2,"menu ...");

    wmove(resetscr, 1, 11); /***** set cursor to a convenient location */
    wrefresh (resetscr);    /***** and display dialog */

    /***** wait for keyboard input */

    if (getch() == 'y') /***** if user hits 'y' */
    {
      modified = 0;     /***** we reset the speaker model */
      resetModel(model);
      if (model_file_name != NULL) /***** if a file name had been specified, ... */
        free(model_file_name);     /***** free any memory used by it */
      model_file_name = NULL;
      retval = 1;                  /***** return ok */
    }
    else                /***** any other key -> keep speaker model */
      retval = 0;

    delwin(resetscr);   /***** delete ncurses dialog window */
  }
  else
    retval = 1; /***** if speaker model hasn't been modified, return ok */

  return(retval);
}
Esempio n. 14
0
void editModel()
{
  int width = 65, height = 22, i, j;            /***** ncurses related variables */
  WINDOW *editscr = popupWindow(width, height);

  int top = 0, current = 0;  /***** menu selection related variables */
  int max_view = 10;

  int request_finish = 0;    /***** request_finish = 1 breaks the main while loop */

  while (!request_finish)
  {
    wattrset (editscr, 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 (editscr);
    box (editscr, 0, 0);
    for (i = 1; i < width-1; i++)
      for (j = 1; j < height-1; j++)
	mvwaddch(editscr, j, i, ' ');

    /***** dialog header */

    mvwaddstr(editscr, 1, 2, "Edit Speaker Model");
    mvwaddseparator(editscr, 2, width);

    /***** display help at the bottom */

    mvwaddseparator(editscr, height-4, width);
    mvwaddstr(editscr, height-3, 2, "a = add item, d = delete item, Enter = edit item");
    mvwaddstr(editscr, height-2, 2, "b = back to main menu");

    /***** display information about current speaker model in a table */

    mvwaddstr(editscr, 4, 2, "Number of items:");
    mvwaddint(editscr, 4, 19, model->number_of_items);

    mvwaddstr(editscr, 6, 4, "Label");
    mvwaddch(editscr,  6,25, ACS_VLINE);
    mvwaddstr(editscr, 6,27, "Command");
    mvwaddch(editscr,  6,48, ACS_VLINE);
    mvwaddstr(editscr, 6,50, "Samples");

    /***** display table */

    for (i = 0; i < 55; i++)
      mvwaddch(editscr, 7, 3+i, ACS_HLINE);
    mvwaddch(editscr,  7,25, ACS_PLUS);
    mvwaddch(editscr,  7,48, ACS_PLUS);
    for (i = 0; i < max_view; i++)
    {
      mvwaddch(editscr,  8+i, 25, ACS_VLINE);
      mvwaddch(editscr,  8+i, 48, ACS_VLINE);
    }

    /***** fill table */

    for (i = 0; i < MIN2(model->number_of_items, max_view); i++)
    {
      setHighlight(editscr, active, i == current);
      mvwaddstr(editscr, 8+i,  3, "                      ");
      mvwaddstr(editscr, 8+i, 26, "                      ");
      mvwaddstr(editscr, 8+i, 49, "         ");
      mvwaddnstr(editscr, 8+i,  4, getModelItem(model, top+i)->label, 20);
      mvwaddnstr(editscr, 8+i, 27, getModelItem(model, top+i)->command, 20);
      mvwaddint(editscr, 8+i, 53, getModelItem(model, top+i)->number_of_samples);
    }
    wattroff(editscr, A_REVERSE);

    /***** up/down arrows indicate that not all items can be displayed */

    if (top > 0)
    {
      mvwaddch(editscr, 8, 2, ACS_UARROW);
      mvwaddch(editscr, 8+1, 2, ACS_VLINE);
    }
    if (model->number_of_items > max_view && top+max_view <= model->number_of_items-1)
    {
      mvwaddch(editscr, 8+max_view-2, 2, ACS_VLINE);
      mvwaddch(editscr, 8+max_view-1, 2, ACS_DARROW);
    }

    wmove(editscr, 1,21); /***** move cursor to an appropriate location */
    wrefresh(editscr);    /***** refresh dialog window */

    /* process the command keystroke */

    switch(getch())
    {
    case KEY_UP: /***** cursor up */
      if (top+current > 0)
      {
	if (current > 0)
	 current--;
	else
	  top--;
      }
      break;
    case KEY_DOWN: /***** cursor down */
      if (top+current < model->number_of_items-1)
      {
	if (current < max_view-1)
	 current++;
	else
	  top++;
      }
      break;
    case 'b':
      /*****
       * allow leaving of the menu only if a predefined minimum amount of
       * sample utterances has been donated for each model item
       *****/
      j = MIN_NR_SAMPLES_PER_ITEM;
      for (i = 0; i < model->number_of_items; i++)
	if (getModelItem(model, i)->number_of_samples < j)
	{
	  j = 0;
	  break;
	}
      if (j < MIN_NR_SAMPLES_PER_ITEM) /***** at least one model item doesn't meet requirements */
      {
	int width = 42, height = 10, i, j;             /***** ncurses related variables */
	WINDOW *warnscr = popupWindow (width, height);

	char tmp_string[80];

	wattrset (warnscr, 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 (warnscr);
	box (warnscr, 0, 0);
	for (i = 1; i < width-1; i++)
	  for (j = 1; j < height-1; j++)
	    mvwaddch(warnscr, j, i, ' ');

	/***** dialog header */
	
	mvwaddstr(warnscr, 1, 2, "Warning!");
	mvwaddseparator(warnscr, 2, width);

	/***** dialog message */
	
	sprintf(tmp_string, "We need at least %d sample utterances", MIN_NR_SAMPLES_PER_ITEM);
	mvwaddstr(warnscr, 3, 2, tmp_string);
	mvwaddstr(warnscr, 4, 2,"for each speaker model item!!!");
	mvwaddstr(warnscr, 5, 2,"Please donate the minimum number of ");
	mvwaddstr(warnscr, 6, 2,"samples before leaving this menu!");
	mvwaddstrcntr(warnscr, 8, width, "Press any key to continue ...");
	
	wmove(warnscr, 1, 11); /***** move cursor to an appropriate location */
	wrefresh (warnscr);    /***** refresh dialog window */
	
	getch();           /***** wait for keyboard input */
	delwin(warnscr);   /***** delete ncurses dialog window */
      }
      else
	request_finish = 1; /***** otherwise prepare to leave menu */
      break;
    case ENTER: /***** edit the currently selected model item */
      if (model->number_of_items > 0)
	editModelItem(getModelItem(model, top+current));
      break;
    case 'a':   /***** append a new item to the speaker model */
      appendEmptyModelItem(model, "New Item", "New Command");
      modified = 1; /***** switch 'modified' to 1 */

      /***** set cursor to show new item */

      current = model->number_of_items-1 - top;
      while (current > max_view-1)
      {
	current--;
	top++;
      }
      break;
    case 'd':    /***** delete currently selected item from model */
      deleteModelItem(model, top+current);
      modified = 1; /***** switch 'modified' to 1 */

      /***** set cursor to a valid value */

      if (top+current == model->number_of_items)
      {
	if (top > 0)
	  top--;
	else if (current > 0)
	  current--;
      }
      break;
    }
  }
}
Esempio n. 15
0
void editModelItem(ModelItem *model_item)
{
  int width = 65, height = 22, i, j;             /***** ncurses related variables */
  WINDOW *itemscr = popupWindow (width, height);

  int top = 0, current = 0;   /***** menu selection related variables */
  int max_view = 6;

  int input_field_width = 40; /***** width of string input field */

  int request_finish = 0;     /***** request_finish = 1 breaks the main while loop */

  while (!request_finish)
  {
    wattrset (itemscr, 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 (itemscr);
    box (itemscr, 0, 0);
    for (i = 1; i < width-1; i++)
      for (j = 1; j < height-1; j++)
	mvwaddch(itemscr, j, i, ' ');

    /***** dialog header */

    mvwaddstr(itemscr, 1, 2, "Edit Speaker Model Item");
    mvwaddseparator(itemscr, 2, width);

    /***** display help at the bottom */

    mvwaddseparator(itemscr, height-4, width);
    mvwaddstr(itemscr, height-3, 2, "r = record sample, d = delete sample, enter = play sample");
    mvwaddstr(itemscr, height-2, 2, "b = back to model menu, l = edit label, c = edit command");

    /***** display information about current speaker item */

    mvwaddstr(itemscr, 4, 2, "Label   :");
    mvwaddnstr(itemscr, 4, 12, model_item->label, input_field_width);
    mvwaddstr(itemscr, 5, 2, "Command :");
    mvwaddnstr(itemscr, 5, 12, model_item->command, input_field_width);

    mvwaddstr(itemscr, 7, 2, "Number of samples:");
    mvwaddint(itemscr, 7, 21, model_item->number_of_samples);

    /***** show sample utterances in a list. */

    mvwaddstr(itemscr, 9, 4, "ID"); /***** header */
    for (i = 0; i < 28; i++)
      mvwaddch(itemscr,10, 3+i, ACS_HLINE);

    /***** list items */

    for (i = 0; i < MIN2(model_item->number_of_samples, max_view); i++)
    {
      setHighlight(itemscr, active, i == current);
      mvwaddstr(itemscr,11+i,  3, "                            ");
      mvwaddstr(itemscr,11+i,  4, getModelItemSample(model_item, top+i)->id);
    }
    wattroff(itemscr, A_REVERSE);

    /***** up/down arrows indicate that not all items can be displayed */

    if (top > 0)
    {
      mvwaddch(itemscr,11, 2, ACS_UARROW);
      mvwaddch(itemscr,11+1, 2, ACS_VLINE);
    }
    if (model_item->number_of_samples > max_view && top+max_view <= model_item->number_of_samples-1)
    {
      mvwaddch(itemscr,11+max_view-2, 2, ACS_VLINE);
      mvwaddch(itemscr,11+max_view-1, 2, ACS_DARROW);
    }

    wmove(itemscr, 1,26); /***** move cursor to a convenient location */
    wrefresh(itemscr);    /***** refresh dialog window */

    /* process the command keystroke */

    switch(getch())
    {
    case KEY_UP: /***** cursor up */
      if (top+current > 0)
      {
	if (current > 0)
	 current--;
	else
	  top--;
      }
      break;
    case KEY_DOWN: /***** cursor down */
      if (top+current < model_item->number_of_samples-1)
      {
	if (current < max_view-1)
	 current++;
	else
	  top++;
      }
      break;
    case 'b':      /***** leave menu */
      request_finish = 1;
      break;
    case ENTER:    /***** play selected utterance */
      if (model_item->number_of_samples > 0)
      {
	int width = 42, height = 8, i, j;                  /* ncurses related variables */
	WINDOW *playbackscr = popupWindow (width, height);

	wattrset (playbackscr, 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 (playbackscr);
	box (playbackscr, 0, 0);
	for (i = 1; i < width-1; i++)
	  for (j = 1; j < height-1; j++)
	    mvwaddch(playbackscr, j, i, ' ');

	/***** dialog header */
	
	mvwaddstr(playbackscr, 1, 2, "Playback");
	mvwaddseparator(playbackscr, 2, width);

	/***** play wave if present */
	
	if (getModelItemSample(model_item, top+current)->has_wav)
	{
	  /***** dialog message */
	
	  mvwaddstr(playbackscr, 3, 2,"Utterance is being played ...      ");
	  /* mvwaddstrcntr(playbackscr, 6, width, "Press any key to cancel ..."); */
	
	  wmove(playbackscr, 1, 11); /***** move cursor to an appropriate location */
	  wrefresh (playbackscr);    /***** refresh dialog window */

	  /***** if play fails or was cancelled ....*/
	
	  if (playSample(getModelItemSample(model_item, top+current)) != AUDIO_OK)
	  {
	    /***** display information */
	
	    mvwaddstr(playbackscr, 1, 2, "Warning!    ");
	    mvwaddstr(playbackscr, 3, 2,"Either playback has been cancelled  ");
	    mvwaddstr(playbackscr, 4, 2,"or wave couldn't be sent to your    ");
	    mvwaddstr(playbackscr, 5, 2,"soundcard !                         ");
	    mvwaddstrcntr(playbackscr, 6, width, "Press any key to continue ...");

	    wmove(playbackscr, 1, 11); /***** move cursor to an appropriate location */
	    wrefresh (playbackscr);    /***** refresh dialog window */
	    getch();                   /***** wait for keyboard input */
	  }
	}
	else /***** no wave data present! */
	{
	  mvwaddstr(playbackscr, 3, 2,"Utterance can't be played! No wave  ");
	  mvwaddstr(playbackscr, 4, 2,"data available! Note: KvoiceControl ");
	  mvwaddstr(playbackscr, 5, 2,"did NOT save the original wave data!");
	  mvwaddstrcntr(playbackscr, 6, width, "Press any key to cancel ...");
	
	  wmove(playbackscr, 1, 11); /***** move cursor to an appropriate location */
	  wrefresh (playbackscr);    /***** refresh dialog window */
	  getch();                   /***** wait for keyboard input */
	}
	
	delwin(playbackscr);   /***** delete ncurses dialog window */
      }
      break;
    case 'r':   /***** record sample utterance */
      {
	int width = 42, height = 8, i, j;   /***** ncurses related variables */
	WINDOW *recordscr = popupWindow (width, height);

	ModelItemSample *new_sample; /***** temporary pointer to new utterance */
	
	wattrset (recordscr, 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 (recordscr);
	box (recordscr, 0, 0);
	for (i = 1; i < width-1; i++)
	  for (j = 1; j < height-1; j++)
	    mvwaddch(recordscr, j, i, ' ');

	/***** dialog header */
	
	mvwaddstr(recordscr, 1, 2, "Recording");
	mvwaddseparator(recordscr, 2, width);

	/***** dialog message */
	
	mvwaddstr(recordscr, 3, 2,"Utterance is recorded automatically!");
	mvwaddstr(recordscr, 4, 2,"Please say what you want to say ...");
	mvwaddstrcntr(recordscr, 6, width, "Press any key to cancel ...");
	
	wmove(recordscr, 1, 12); /***** move cursor to a convenient location */
	wrefresh (recordscr);    /***** refresh dialog screen */
	
	new_sample = recordSample(); /***** auto record a sample utterance */
	
	if (new_sample != NULL) /***** if the recording was successful ... */
	{
	  appendModelItemSample(model_item, new_sample); /***** add the sample to the model */

	  /***** set cursor to be over new sample utterance */
	
	  current = model_item->number_of_samples-1 - top;
	  while (current > max_view-1)
	  {
	    current--;
	    top++;
	  }
	}
	else /***** recording has failed or was cancelled */
	{
	  /***** dialog message */
	
	  mvwaddstr(recordscr, 1, 2, "Cancel!    ");
	  mvwaddstr(recordscr, 3, 2,"Nothing has been recorded! Either   ");
	  mvwaddstr(recordscr, 4, 2,"you cancelled or no data could be   ");
	  mvwaddstr(recordscr, 5, 2,"recorded !                          ");
	  mvwaddstrcntr(recordscr, 6, width, "Press any key to continue ...");

	  wmove(recordscr, 1, 10); /***** move cursor to a convenient location */
	  wrefresh (recordscr);    /***** refresh dialog screen   */
	  getch();                 /***** wait for keyboard input */
	}
	
	delwin(recordscr);   /***** delete ncurses dialog window */
      }
      break;
    case 'l': /***** edit label */
      {
	/*****
	 * use wstringInput to edit the label of the current utterance
	 * if the label has changed, switch 'modified' to 1
	 *****/
	char tmp_string[1000];
	strcpy(tmp_string, model_item->label);
	free(model_item->label);
	model_item->label = wstringInput(itemscr, 4, 12, 255, input_field_width, tmp_string);
	if (strcmp(tmp_string, model_item->label) != 0)
	  modified = 1;
      }
      break;
    case 'c': /***** edit command */
      {
	/*****
	 * use wstringInput to edit the commandd of the current utterance
	 * if the command has changed, switch 'modified' to 1
	 *****/
	char tmp_string[1000];
	strcpy(tmp_string, model_item->command);
	free(model_item->command);
	model_item->command = wstringInput(itemscr, 5, 12, 255, input_field_width, tmp_string);
	if (strcmp(tmp_string, model_item->command) != 0)
	  modified = 1;
      }
      break;
    case 'd':
      /*****
       * delete currently selected sample utterance from model item
       * and switch 'modified' to 1
       *****/
      deleteModelItemSample(model_item, top+current);
      modified = 1;

      /***** set cursor to a valid value */
	
      if (top+current == model_item->number_of_samples)
      {
	if (top > 0)
	  top--;
	else if (current > 0)
	  current--;
      }
      break;
    }
  }
}