/**
    \fn updateVu
*/
bool GUIPlayback::updateVu(void)
{
 uint64_t time=  ticktock.getElapsedMS();
    // Refresh vumeter every 50 ms
    if(!playbackAudio)  return true;
    if(time>(vuMeterPts+50))
    {
        uint32_t stat[6];
        AVDM_getStats(stat);
        UI_setVUMeter(stat);
        vuMeterPts=time;
    }
    return true;
}
/**
    \fn initializeAudio
    \brief Initialize audio
*/
bool  GUIPlayback::initializeAudio(void)

{
    uint32_t state,latency, preload;
    uint32_t small_;
    uint32_t channels,frequency;

    wavbuf = 0;
    uint64_t startPts=firstPts;
    int32_t shift=0; // unit is ms, + => delay audio, -=> advance audio
    
    // if audio shift is activated, take it into account
    //
    EditableAudioTrack *ed=video_body->getDefaultEditableAudioTrack();
    if(ed->audioEncodingConfig.shiftEnabled)
        shift=ed->audioEncodingConfig.shiftInMs;
    playbackAudio = createPlaybackFilter(startPts,shift);
    if(!playbackAudio) 
    {
        ADM_info("No audio\n");
        return false;
    }

    channels= playbackAudio->getInfo()->channels;
    frequency=playbackAudio->getInfo()->frequency;
    preload=  (frequency * channels)/5;	// 200 ms preload
    // 4 sec buffer..
    wavbuf =  (float *)  ADM_alloc((20*sizeof(float)*preload)); // 4 secs buffers
    ADM_assert(wavbuf);
    // Read a at least one block to have the proper channel mapping
    uint32_t fill=0;
    AUD_Status status;
    small_ = playbackAudio->fill(channels, wavbuf,&status);
    fill+=small_;
    // Call it twice to be sure it is properly setup
     state = AVDM_AudioSetup(frequency,  channels ,playbackAudio->getChannelMapping());
     AVDM_AudioClose();
     state = AVDM_AudioSetup(frequency,  channels ,playbackAudio->getChannelMapping());
     latency=AVDM_GetLayencyMs();
     printf("[Playback] Latency : %d ms\n",latency);
     audioLatency=latency; // ms -> us
      if (!state)
      {
          GUI_Error_HIG(QT_TR_NOOP("Trouble initializing audio device"), NULL);
          cleanupAudio();
          return false;
      }
    while(fill<preload)
    {
      if (!(small_ = playbackAudio->fill(preload-fill, wavbuf+fill,&status)))
      {
        break;
      }
      fill+=small_;
    }
    nbSamplesSent = fill/channels;  // In sample
    AVDM_AudioPlay(wavbuf, fill);
    // Let audio latency sets in...
    ticktock.reset();
    uint32_t slice=(frequency * channels)/100; // 10 ms
    // pump data until latency is over
    updateVu();
    #if 0
    while(ticktock.getElapsedMS()<latency)
    {
        if(AVDM_getMsFullness()<AUDIO_PRELOAD)
        {
          if (!(small_ = playbackAudio->fill(slice, wavbuf,&status)))
          {
            printf("[Playback] Compensating for latency failed\n");
            break;
          }
          AVDM_AudioPlay(wavbuf, slice);
        }
       ADM_usleep(10*1000);
       updateVu();
    }
    #endif
    printf("[Playback] Latency is now %u\n",ticktock.getElapsedMS());
    return true;
}
/**
    \fn    localInit
    \brief Take & initialize the device

*/
bool pulseSimpleAudioDevice::localInit(void) 
{
ADM_info("Pulse, initiliazing channel=%d samplerate=%d\n",(int)_channels,(int)_frequency);
pa_simple *s;
pa_sample_spec ss;
int er;
pa_buffer_attr attr;
pa_channel_map map,*pmap=NULL;
    attr.maxlength = (uint32_t) -1;
    attr.tlength = (uint32_t )-1;
    attr.prebuf =(uint32_t) -1;
    attr.minreq = (uint32_t) -1;
    attr.fragsize =(uint32_t) -1;

  // We want something like 20 ms latency
   uint64_t bufSize=_frequency;
            bufSize*=_channels;
            bufSize*=2;      // 1 second worth of audio

  bufSize=bufSize/1000;
  bufSize*=ADM_PULSE_LATENCY;
  attr.tlength=bufSize;       // Latency in bytes
 

  // Channel mapping
  if(_channels>2)
    {
        pmap=&map;
        map.channels=_channels;
        map.map[0]=PA_CHANNEL_POSITION_FRONT_LEFT;
        map.map[1]=PA_CHANNEL_POSITION_FRONT_RIGHT;
        map.map[2]=PA_CHANNEL_POSITION_FRONT_CENTER;
        map.map[3]=PA_CHANNEL_POSITION_REAR_LEFT;
        map.map[4]=PA_CHANNEL_POSITION_REAR_RIGHT;
        map.map[5]=PA_CHANNEL_POSITION_SUBWOOFER;
  }

  ss.format = PA_SAMPLE_S16LE;
  ss.channels = _channels;
  ss.rate =_frequency;
 
  instance= pa_simple_new(NULL,               // Use the default server.
                    "Avidemux2",           // Our application's name.
                    PA_STREAM_PLAYBACK,
                    NULL,               // Use the default device.
                    "Sound",            // Description of our stream.
                    &ss,                // Our sample format.
                    pmap,               // Use default channel map
                    &attr ,             // Use default buffering attributes.
                    &er               // Ignore error code.
                    );
  if(!instance)
    {
        ADM_info("[PulseSimple] open failed :%s\n",pa_strerror(er));
        return 0;
    }
#if 0
    pa_usec_t l=0;
    // Latency...
    Clock    ticktock;
    ticktock.reset();
    if(0>pa_simple_write(INSTANCE,silence, sizeOf10ms,&er))
    {
      fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(er));
    }
    pa_simple_drain(INSTANCE,&er);
    latency=ticktock.getElapsedMS();
    ADM_info("[Pulse] Latency :%"PRIu32", total %"PRIu32"\n",latency,pa_simple_get_latency(INSTANCE,&er)/1000);
#endif
    ADM_info("[PulseSimple] open ok for fq=%d channels=%d\n",ss.rate,ss.channels);
    return 1;

}
bool GUIPlayback::run(void)
{

    uint32_t movieTime;
    uint32_t systemTime;
    uint32_t fn;
    int refreshCounter=0;
    ticktock.reset();
    vuMeterPts=0;
    ADMImage *previewBuffer=admPreview::getBuffer();
    ADM_HW_IMAGE hwImageFormat=admPreview::getPreferedHwImageFormat();

    do
    {

        admPreview::displayNow();;
        GUI_setCurrentFrameAndTime(firstPts);
        if(false==videoFilter->getNextFrameAs(hwImageFormat,&fn,previewBuffer))
        {
            printf("[Play] Cancelling playback, nextPicture failed\n");
            break;
        }
        audioPump(false);
        lastPts=admPreview::getCurrentPts();
        systemTime = ticktock.getElapsedMS();
        movieTime=(uint32_t)((lastPts-firstPts*0)/1000);
        movieTime+=audioLatency;
       // printf("[Playback] systemTime: %lu movieTime : %lu  \r",systemTime,movieTime);
        if(systemTime>movieTime) // We are late, the current PTS is after current closk
        {
            if(systemTime >movieTime+20)
            {
                refreshCounter++;
            }
            if(refreshCounter>15)
            {
                UI_purge();
                UI_purge();
                refreshCounter=0;
            }
        }
	    else
	    {
            int32_t delta;
                delta=movieTime-systemTime;
                // a call to whatever sleep function will last at leat 10 ms
                // give some time to GTK
                while(delta > 10)
                {
                    if(delta>10)
                    {
                        audioPump(true);
                    }else
                        audioPump(false);

                    UI_purge();
                    refreshCounter=0;
                    systemTime = ticktock.getElapsedMS();
                    delta=movieTime-systemTime;
                }
        }
      }
    while (!stop_req);

abort_play:
        return true;
};
Exemple #5
0
int main (int argc, char **argv) {
  // TODO: Create a separate test suit executable instead of this code block.
  #ifndef NDEBUG
    testStringTokenizer();
  #endif

  UserSettings::load();

  Game::Window window;

  int r = glewInit();
  assert (r == GLEW_OK);

  // Setup an orthographic projection.
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D (0.0, Game::Window::get_width(), 0.0, Game::Window::get_height());

  // Enable color blending for transparent parts of PNG images.
  glEnable (GL_BLEND);
  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  glMatrixMode (GL_MODELVIEW);

  Font disclaimer_text (10);
  Font controls_text (12);

  int fps;

  static const GLfloat PADDING = 10.0F; // in pixels

  #ifndef NDEBUG
    static const std::string FPS_LABEL = "FPS: ";

    // Create the FPS rectangle.
    static const std::string FPS_LONGEST_STR = FPS_LABEL + "000";
    Rectangle fps_rect;
    fps_rect.w = PADDING + disclaimer_text.get_width (FPS_LONGEST_STR) + PADDING;
    fps_rect.h = PADDING + disclaimer_text.get_line_height() + PADDING;
    fps_rect.x = Window::get_width() - fps_rect.w;
    fps_rect.y = Window::get_height() - fps_rect.h;
  #endif

  // Create the menu.
  static const int ITEM_WIDTH = 200, ITEM_HEIGHT = 50; // in pixels
  menu = new Menu (ITEM_WIDTH, ITEM_HEIGHT);
  menu->consume (new MenuTextItem ("Start Game", start_game, MenuTextItem::LARGE));
  menu->consume (new MenuTextItem ("Controls",  display_controls, MenuTextItem::LARGE));
  menu->consume (new MenuTextItem ("Options", display_options, MenuTextItem::LARGE));
  menu->consume (new MenuTextItem ("Credits", display_credits, MenuTextItem::LARGE));
  menu->consume (new MenuTextItem ("Exit", exit_game, MenuTextItem::LARGE));
  menu_rect.w = ITEM_WIDTH;
  menu_rect.h = ITEM_HEIGHT * menu->get_item_count();
  menu_rect.x = 400;
  menu_rect.y = (Window::get_height() - menu_rect.h) / 2;
  menu->set_position (menu_rect);
  UI::Manager menu_ui_manager;
  menu_ui_manager.consume (menu);

  display_menu (NULL);

  UserSettingsPanel *user_settings_widget = NULL;

  // Main game loop.
  const int DESIRED_FPS = 60;
  static const unsigned int DESIRED_FRAME_DURATION = 1000 / DESIRED_FPS;
  Clock clock;
  do {
    unsigned int start_tick = clock.getElapsedMS();

    Controllers::Manager::update (window);

    // Update, draw, and eventually terminate the world.
    if (activity == WORLD) {
      if (Controllers::Manager::is_escape_pressed()) {
        display_menu (NULL);
      } else {
        world->update (start_tick);
        if (world->get_status() == World::PLAYER_WON) {
          delete world;
          world = NULL;
          display_credits (NULL);
        } else if (world->get_status() == World::PLAYER_LOST) {
          delete world;
          world = NULL;
          start_game (NULL);
        } else if (world->get_status() == World::RUNNING) {
          world->draw();
        }
      }
    } else if (activity == CREDITS) {
      credits->update (start_tick);
      if (credits->is_done() || Controllers::Manager::is_escape_pressed()) {
        delete credits;
        credits = NULL;
        display_menu (NULL);
      } else {
        credits->draw (window);
      }
    } else {
      // Draw the backdrop.
      if (world) {
        world->draw();

        // Blacken the world by 80%.
        glColor4f (0.0F, 0.0F, 0.0F, 0.8F);
        glPushMatrix();
        glLoadIdentity();
        glRecti (0, 0, Window::get_width(), Window::get_height());
        glPopMatrix();
      } else {
        // Draw the background.
        glPushMatrix();
        glLoadIdentity();
        static Animation background ("ui/main_menu.png");
        static const GLfloat BG_SCALE =
            (GLfloat)Game::Window::get_width() / background.get_width();
        glScalef (BG_SCALE, BG_SCALE, 0.0F);
        background.draw();
        glPopMatrix();

        glMatrixMode (GL_MODELVIEW);
        glColor3ub (64, 40, 196); // dark purple

        // Draw the disclaimer.
        static const std::string INFO_STR = "Contributions copyright (2011) by their "
            "respective authors listed in the credits.  Not a finished work.";
        static const int INFO_X =
            (Game::Window::get_width() - disclaimer_text.get_width (INFO_STR)) / 2;
        glLoadIdentity();
        glTranslatef (INFO_X, PADDING, 0.0F);
        disclaimer_text.draw (INFO_STR);

        // Draw the version.
        static const std::string VER_STR = "v 0.7";
        static const int VER_X = Window::get_width() - PADDING - disclaimer_text.get_width (VER_STR);
        glLoadIdentity();
        glTranslatef (VER_X, PADDING, 0.0F);
        disclaimer_text.draw (VER_STR);
      }

      // Draw the title.
      glPushMatrix();
      glLoadIdentity();
      glTranslatef (title_x, title_y, 0.0F);
      glColor3ub (64, 40, 196); // dark purple
      title_text.draw (title);
      glPopMatrix();

      if (activity == CONTROLS) {
        if (Controllers::Manager::is_escape_pressed()) {
          display_menu (NULL);
        } else {
          // Draw the controls.
          glPushMatrix();
          glLoadIdentity();
          glTranslatef (menu_rect.x,
                        menu_rect.get_top() - controls_text.get_line_height(),
                        0.0F);
          glColor3ub (156, 120, 252); // light purple
          controls_text.draw (
              "Arrows: Move, aim\n"
              "z: fire weapon, select menu item\n"
              "a, s: Select weapon\n"
              "x: Jump\n"
              "Down: Use door, talk, etc\n"
              "Esc: Back\n"
              "\n"
              "F1: Editor\n"
              "Mouse buttons 3, 4: Select map layer\n"
              "Mouse wheel: Select brush\n"
              "Left click: Select or use brush\n"
              "Right click: Copy brush\n"
              "\n"
              "F2 Terminal");
          glPopMatrix();
        }
      } else if (activity == OPTIONS) {
        if (!user_settings_widget) {
          user_settings_widget = new UserSettingsPanel();
        }
        user_settings_widget->update (start_tick);
        user_settings_widget->draw();
        if (Controllers::Manager::is_escape_pressed()) {
          delete user_settings_widget;
          user_settings_widget = NULL;
          display_menu (NULL);
        }
      } else if (activity == MAIN_MENU) {
        // Select a menu item by hot key.
        static Controllers::Player pc;
        if (pc.is_up_pressed()) {
          menu->decrement_highlight();
        }
        if (pc.is_down_pressed()) {
          menu->increment_highlight();
        }
        if (pc.is_weapon_fire_pressed()) {
          menu->select_highlighted();
        }

        menu_ui_manager.update (start_tick);
        menu_ui_manager.draw();
      }
    }

    // Draw FPS if compiled for debugging.
    #ifndef NDEBUG
      // Create the FPS string.
      std::stringstream fps_ss;
      fps_ss << FPS_LABEL << fps;
      std::string fps_str = fps_ss.str();

      // Move to the FPS label's location.
      glLoadIdentity();
      glTranslatef (fps_rect.x, fps_rect.y, 0.0F);

      // Draw the FPS label's background.
      glColor4f (0.0F, 0.0F, 0.0F, 0.8F); // 80% black
      glRecti (0, 0, fps_rect.w, fps_rect.h);

      // Draw the FPS label.
      glTranslatef (PADDING, PADDING, 0.0F);
      glColor3ub (64, 40, 196); // dark purple
      disclaimer_text.draw (fps_str);
    #endif

    window.refresh();

    unsigned int frame_duration = clock.getElapsedMS() - start_tick;
    if (frame_duration >= DESIRED_FRAME_DURATION) {
      fps = 1000 / frame_duration;
    } else { // if the frame duration is less than desired
      fps = DESIRED_FPS;
      clock.sleep (DESIRED_FRAME_DURATION - frame_duration);
    }
  } while (activity != EXIT && !Controllers::Manager::is_app_closed());

  delete world;
  delete credits;
  delete user_settings_widget;

  return EXIT_SUCCESS;
}