eXine() { /* this should be done once. */ if(!xine_check_version(1, 1, 0)) { int major, minor, sub; xine_get_version (&major, &minor, &sub); eWarning("Require xine library version 1.1.0, found %d.%d.%d.\n", major, minor,sub); return; } else { int major, minor, sub; eDebug("Built with xine library %d.%d.%d (%s)\n", XINE_MAJOR_VERSION, XINE_MINOR_VERSION, XINE_SUB_VERSION, XINE_VERSION); xine_get_version (&major, &minor, &sub); eDebug("Found xine library version: %d.%d.%d (%s).\n", major, minor, sub, xine_get_version_string()); } xine = xine_new(); xine_engine_set_param(xine, XINE_ENGINE_PARAM_VERBOSITY, 1); xine_init(xine); }
bool XineEngine::makeNewStream() { m_currentAudioPlugin = XineCfg::outputPlugin(); m_audioPort = xine_open_audio_driver( m_xine, XineCfg::outputPlugin().local8Bit(), NULL ); if( !m_audioPort ) { //TODO make engine method that is the same but parents the dialog for us KMessageBox::error( 0, i18n("xine was unable to initialize any audio drivers.") ); return false; } m_stream = xine_stream_new( m_xine, m_audioPort, NULL ); if( !m_stream ) { xine_close_audio_driver( m_xine, m_audioPort ); m_audioPort = NULL; KMessageBox::error( 0, i18n("Pana could not create a new xine stream.") ); return false; } if( m_eventQueue ) xine_event_dispose_queue( m_eventQueue ); xine_event_create_listener_thread( m_eventQueue = xine_event_new_queue( m_stream ), &XineEngine::XineEventListener, (void*)this ); #ifndef XINE_SAFE_MODE //implemented in xine-scope.h m_post = scope_plugin_new( m_xine, m_audioPort ); xine_set_param( m_stream, XINE_PARAM_METRONOM_PREBUFFER, 6000 ); xine_set_param( m_stream, XINE_PARAM_IGNORE_VIDEO, 1 ); #endif #ifdef XINE_PARAM_EARLY_FINISHED_EVENT if ( xine_check_version(1,1,1) && !(m_xfadeLength > 0) ) { // enable gapless playback debug() << "gapless playback enabled." << endl; //xine_set_param(m_stream, XINE_PARAM_EARLY_FINISHED_EVENT, 1 ); } #endif return true; }
void music_init () { char *configfile; if (!xine_check_version (XINE_MAJOR_VERSION, XINE_MINOR_VERSION, XINE_SUB_VERSION)) { g_critical (_("Incompatible version of Xine-lib found.")); exit (EXIT_FAILURE); } xine = xine_new (); configfile = g_build_filename (g_get_home_dir (), ".xine", "config", NULL); xine_config_load (xine, configfile); g_free (configfile); xine_init (xine); if (!(ao = xine_open_audio_driver (xine, NULL, NULL))) { g_critical (_("Unable to open audio driver from Xine.")); exit (EXIT_FAILURE); } if (!(vo = xine_open_video_driver (xine, NULL, XINE_VISUAL_TYPE_NONE, NULL))) { g_critical (_("Unable to open video driver from Xine.")); exit (EXIT_FAILURE); } if (!(stream = xine_stream_new (xine, ao, vo))) { g_critical (_("Unable to open a Xine stream.")); exit (EXIT_FAILURE); } events = xine_event_new_queue (stream); xine_event_create_listener_thread (events, music_events, NULL); }
bool Xine::make_new_stream(){ if (stream) xine_dispose(stream); std::string ao_driver = "auto"; GlobalOptions * go = S_GlobalOptions::get_instance(); global_audio_device gad = go->get_audio_device_audio(); if (gad.dev_output != ""){ ao_driver = gad.dev_output; } if (ao_port) xine_close_audio_driver(xine, ao_port); /* fprintf(stderr, "Audio driver: %s (%d)\n", ao_driver.c_str(), gad.pos); */ ao_port = xine_open_audio_driver(xine, ao_driver.c_str(), NULL); if (ao_port == NULL){ DialogWaitPrint pdialog(4000); pdialog.add_line(dgettext("mms-audio-xine", "Audio device unavailable: ") + ao_driver); pdialog.print(); return false; } /* Xine uses its own config file for a lot of stuff */ xine_cfg_entry_t config; /* for some reason this doesn't work for someone if (!xine_config_lookup_entry(xine, "input.cdda_device", &config)) { fprintf(stderr, "Xine: Can't set cdda device\n"); } else{ std::string str = S_Cd::get_instance()->get_device(); config.str_value = const_cast<char*>(str.c_str()); xine_config_update_entry(xine, &config); } */ /* Disable CDDB, we have our own CDDB library */ if (xine_config_lookup_entry(xine, "media.audio_cd.use_cddb", &config)){ config.num_value = 0; xine_config_update_entry(xine, &config); } stream = xine_stream_new(xine, ao_port, NULL); if (stream == NULL){ xine_close_audio_driver(xine, ao_port); ao_port = NULL; return false; } /* xine_set_param(stream, XINE_PARAM_VERBOSITY, XINE_VERBOSITY_DEBUG); */ if (event_queue) xine_event_dispose_queue(event_queue); xine_set_param( stream, XINE_PARAM_METRONOM_PREBUFFER, 6000 ); xine_set_param( stream, XINE_PARAM_IGNORE_VIDEO, 1 ); #ifdef XINE_PARAM_EARLY_FINISHED_EVENT #ifdef XINE_PARAM_GAPLESS_SWITCH if (xine_check_version(1,1,1)) xine_set_param(stream, XINE_PARAM_EARLY_FINISHED_EVENT, 1); #ifdef XINE_PARAM_DELAY_FINISHED_EVENT xine_set_param(stream, XINE_PARAM_DELAY_FINISHED_EVENT, 0); #endif #endif #endif event_queue = xine_event_new_queue(stream); mixer_cap = false; is_muted = xine_get_param(stream, XINE_PARAM_AUDIO_MUTE); if (is_muted == -1){ is_muted = xine_get_param(stream, XINE_PARAM_AUDIO_AMP_MUTE); mixer_cap = true; } xine_event_create_listener_thread(event_queue, &Xine::event_listener, reinterpret_cast<void*>(this)); return true; }
void Xine::run(){ /* this is the main thread */ playing = false; seamless = false; pthread_mutex_lock(&stream_mutex); struct timespec ts = time_helper::compute_interval(5000); Audio_s *audio_state = S_Audio_s::get_instance(); volume = 0; if(validate_stream()) volume = xine_get_param(stream, XINE_PARAM_AUDIO_VOLUME); old_volume = volume; while(!quitting){ xine_request = _XINE_REQUEST_NONE; int ret = pthread_cond_timedwait(&stream_switch, &stream_mutex, &ts); if (!running || quitting){ ts = time_helper::compute_interval(5000); continue; } if (ret != ETIMEDOUT && xine_request == _XINE_REQUEST_NONE) continue; /* we're not done waiting */ /* if (xine_request != _XINE_REQUEST_NONE) fprintf (stderr, "Loop received event request (%d)\n", xine_request); */ switch(xine_request){ case _XINE_REQUEST_PLAY_AT: case _XINE_REQUEST_PLAY:{ retry_track = false; if(!validate_stream()) break; #ifdef XINE_PARAM_EARLY_FINISHED_EVENT if (seamless && xine_check_version(1,1,1) && oldfile.type != "web" && file.type != "web"){ xine_set_param(stream, XINE_PARAM_GAPLESS_SWITCH, 1); } // else{ // xine_close(stream); // } seamless = false; #endif oldfile = file; /* fprintf(stderr, "file.path %s\n", file.path.c_str()); */ std::string _str = file.path; if (file.type == "media-track"){ std::string _path = "cdda:/" + cd_device + "/"; _str = regex_tools::regex_replace(_str, _path.c_str(), "^cdda:/", false, false); /* fprintf(stderr, "%s\n", _str.c_str()); */ } else { vector<string> urls = PlaylistParser::resolve_playlist(_str); if (!urls.empty()) _str = urls[0]; /* TODO: Handle multiple playlist entries here */ } if(!xine_open(stream, _str.c_str())){ #ifdef XINE_PARAM_GAPLESS_SWITCH if (xine_check_version(1,1,1)) xine_set_param(stream, XINE_PARAM_GAPLESS_SWITCH, 0); #endif break; } int len = 0; off_t play_at = 0; const bool has_audio = xine_get_stream_info( stream, XINE_STREAM_INFO_HAS_AUDIO ); const bool audio_handled = xine_get_stream_info( stream, XINE_STREAM_INFO_AUDIO_HANDLED ); if (xine_request == _XINE_REQUEST_PLAY_AT){ xine_get_pos_length(stream, 0, 0, &len); play_at = len > 0 ? static_cast<double>(cur_time*65535)/(len/1000) : 0; } else cur_time = 0; _cur_time = cur_time; total_time = 0; _total_time = 0; if ((has_audio || file.type == "web") && audio_handled && xine_play(stream, play_at, cur_time * 1000)){ playing = true; //gather_info_internal(); audio_state->set_playing(true); buffering_state = 0; } else{ playing = false; audio_state->set_playing(false); xine_close(stream); } audio_state->get_audio()->update_playlist_view(); #ifdef XINE_PARAM_EARLY_FINISHED_EVENT #ifdef XINE_PARAM_GAPLESS_SWITCH if (xine_check_version(1,1,1)){ if (!audio_state->get_audio()->next_helper(false).path.empty()){ xine_set_param(stream, XINE_PARAM_EARLY_FINISHED_EVENT, 1); /* fprintf(stderr, "Not last track\n"); */ #ifdef XINE_PARAM_DELAY_FINISHED_EVENT xine_set_param(stream, XINE_PARAM_DELAY_FINISHED_EVENT, 0); #endif } else { /* If we don't disable XINE_PARAM_DELAY_FINISHED_EVENT for the last track in the playlist, * xine won't play the last couple of seconds of it */ xine_set_param(stream, XINE_PARAM_EARLY_FINISHED_EVENT, 0); /* fprintf(stderr, "Last track\n"); */ } } #endif #endif if (start_paused){ start_paused = false; audio_state->set_pause(true); } else audio_state->set_pause(false); break; } case _XINE_REQUEST_STOP: case _XINE_REQUEST_RELEASE_DEVICE: retry_track = false; seamless = false; if(stream){ xine_close(stream); xine_event_dispose_queue(event_queue); event_queue = NULL; xine_dispose(stream); stream = NULL; } playing = false; audio_state->set_playing(false); if (xine_request == _XINE_REQUEST_RELEASE_DEVICE){ xine_close_audio_driver(xine, ao_port); ao_port = NULL; } break; case _XINE_REQUEST_PAUSE: if(!validate_stream()||!playing) break; if(xine_get_param(stream, XINE_PARAM_SPEED) != XINE_SPEED_PAUSE) { xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); audio_state->set_pause(true); } else { xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL); audio_state->set_pause(false); } break; case _XINE_REQUEST_FF:{ if(!playing || !validate_stream()) break; gather_info_internal(); if (_cur_time + 5 > _total_time) break; _cur_time +=5; off_t pos = _total_time > 0 ? static_cast<double>(_cur_time*65535)/_total_time : 0; xine_play(stream, pos, _cur_time*1000); audio_state->set_pause(false); break; } case _XINE_REQUEST_FB:{ if(!playing || !validate_stream()) break; gather_info_internal(); if (static_cast<int>(_cur_time) - 5 < 0) break; _cur_time -=5; off_t pos = _total_time > 0 ? static_cast<double>(_cur_time*65535)/_total_time : 0; xine_play(stream, pos, _cur_time*1000); audio_state->set_pause(false); break; } default: break; } if (ret == ETIMEDOUT && playing) gather_info_internal(); if (playing) ts = time_helper::compute_interval(500); else ts = time_helper::compute_interval(5000); } if(stream){ xine_close(stream); xine_event_dispose_queue(event_queue); event_queue = NULL; xine_dispose(stream); stream = NULL; } playing = false; if (ao_port) xine_close_audio_driver(xine, ao_port); ao_port = NULL; pthread_mutex_unlock(&stream_mutex); /* bye */ }