void osd_init(running_machine *machine) { int watchdog = options_get_int(mame_options(), WINOPTION_WATCHDOG); const char *stemp; // thread priority if (!(machine->debug_flags & DEBUG_FLAG_OSD_ENABLED)) SetThreadPriority(GetCurrentThread(), options_get_int(mame_options(), WINOPTION_PRIORITY)); // ensure we get called on the way out add_exit_callback(machine, osd_exit); // get number of processors stemp = options_get_string(mame_options(), WINOPTION_NUMPROCESSORS); osd_num_processors = 0; if (strcmp(stemp, "auto") != 0) { osd_num_processors = atoi(stemp); if (osd_num_processors < 1) { mame_printf_warning("Warning: numprocessors < 1 doesn't make much sense. Assuming auto ...\n"); osd_num_processors = 0; } } // initialize the subsystems winvideo_init(machine); winsound_init(machine); wininput_init(machine); winoutput_init(machine); // hook up the debugger log if (options_get_bool(mame_options(), WINOPTION_OSLOG)) add_logerror_callback(machine, output_oslog); // crank up the multimedia timer resolution to its max // this gives the system much finer timeslices timeresult = timeGetDevCaps(&caps, sizeof(caps)); if (timeresult == TIMERR_NOERROR) timeBeginPeriod(caps.wPeriodMin); // set our multimedia tasks if we can // if (av_set_mm_thread_characteristics != NULL) // mm_task = (*av_set_mm_thread_characteristics)(TEXT("Playback"), &task_index); start_profiler(); // if a watchdog thread is requested, create one if (watchdog != 0) { watchdog_reset_event = CreateEvent(NULL, FALSE, FALSE, NULL); assert_always(watchdog_reset_event != NULL, "Failed to create watchdog reset event"); watchdog_exit_event = CreateEvent(NULL, TRUE, FALSE, NULL); assert_always(watchdog_exit_event != NULL, "Failed to create watchdog exit event"); watchdog_thread = CreateThread(NULL, 0, watchdog_thread_entry, (LPVOID)(FPTR)watchdog, 0, NULL); assert_always(watchdog_thread != NULL, "Failed to create watchdog thread"); } }
int options_get_int_range(const char *name, int minval, int maxval) { options_data *data = find_entry_data(name, FALSE); int value = 0; if (data == NULL) mame_printf_error("Unexpected integer option %s queried\n", name); else if (data->data == NULL || sscanf(data->data, "%d", &value) != 1) { if (data->defdata != NULL) { options_set_string(name, data->defdata); value = options_get_int(name); } if (!data->error_reported) { mame_printf_error("Illegal integer value for %s; reverting to %d\n", data->names[0], value); data->error_reported = TRUE; } } else if (value < minval || value > maxval) { options_set_string(name, data->defdata); value = options_get_int(name); if (!data->error_reported) { mame_printf_error("Invalid %s value (must be between %d and %d); reverting to %d\n", data->names[0], minval, maxval, value); data->error_reported = TRUE; } } return value; }
/* Make a title from the file name for the item. If hide extension != 0, strip * the file name from extension. */ void make_file_title (struct plist *plist, const int num, const int hide_extension) { assert (plist != NULL); assert (num >= 0 && num < plist->num); assert (!plist_deleted(plist, num)); if (file_type(plist->items[num].file) != F_URL) { char *file = xstrdup (plist->items[num].file); if (hide_extension) { char *dot = strrchr (file, '.'); if (dot) *dot = 0; } if (options_get_int ("FileNamesIconv")) { char *old_title = file; file = files_iconv_str (file); free (old_title); } plist_set_title_file (plist, num, file); free (file); } else plist_set_title_file (plist, num, plist->items[num].file); }
static void *mp3_open_stream (struct io_stream *stream) { struct mp3_data *data; data = (struct mp3_data *)xmalloc (sizeof(struct mp3_data)); data->ok = 1; decoder_error_init (&data->error); /* Reset information about the file */ data->freq = 0; data->channels = 0; data->skip_frames = 0; data->bitrate = -1; data->io_stream = stream; data->duration = -1; data->size = (off_t)-1; mad_stream_init (&data->stream); mad_frame_init (&data->frame); mad_synth_init (&data->synth); if (options_get_int("Mp3IgnoreCRCErrors")) mad_stream_options (&data->stream, MAD_OPTION_IGNORECRC); return data; }
void osd_init(running_machine *machine) { // thread priority if (!options_get_bool(mame_options(), OPTION_DEBUG)) SetThreadPriority(GetCurrentThread(), options_get_int(mame_options(), WINOPTION_PRIORITY)); // ensure we get called on the way out add_exit_callback(machine, osd_exit); // initialize the subsystems winvideo_init(machine); winsound_init(machine); wininput_init(machine); winoutput_init(machine); // hook up the debugger log if (options_get_bool(mame_options(), WINOPTION_OSLOG)) add_logerror_callback(machine, output_oslog); // crank up the multimedia timer resolution to its max // this gives the system much finer timeslices timeresult = timeGetDevCaps(&caps, sizeof(caps)); if (timeresult == TIMERR_NOERROR) timeBeginPeriod(caps.wPeriodMin); // set our multimedia tasks if we can // if (av_set_mm_thread_characteristics != NULL) // mm_task = (*av_set_mm_thread_characteristics)(TEXT("Playback"), &task_index); start_profiler(); }
/* Read the content of the directory, make an array of absolute paths for * all recognized files. Put directories, playlists and sound files * in proper structures. Return 0 on error.*/ int read_directory (const char *directory, struct file_list *dirs, struct file_list *playlists, struct plist *plist) { DIR *dir; struct dirent *entry; int show_hidden = options_get_int ("ShowHiddenFiles"); int dir_is_root; assert (directory != NULL); assert (*directory == '/'); assert (dirs != NULL); assert (playlists != NULL); assert (plist != NULL); if (!(dir = opendir(directory))) { error ("Can't read directory: %s", strerror(errno)); return 0; } if (!strcmp(directory, "/")) dir_is_root = 1; else dir_is_root = 0; while ((entry = readdir(dir))) { char file[PATH_MAX]; enum file_type type; if (user_wants_interrupt()) { error ("Interrupted! Not all files read!"); break; } if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) continue; if (!show_hidden && entry->d_name[0] == '.') continue; if (snprintf(file, sizeof(file), "%s/%s", dir_is_root ? "" : directory, entry->d_name) >= (int)sizeof(file)) { error ("Path too long!"); return 0; } type = file_type (file); if (type == F_SOUND) plist_add (plist, file); else if (type == F_DIR) file_list_add (dirs, file); else if (type == F_PLAYLIST) file_list_add (playlists, file); } closedir (dir); return 1; }
static struct mp3_data *mp3_open_internal (const char *file, const int buffered) { struct mp3_data *data; data = (struct mp3_data *)xmalloc (sizeof(struct mp3_data)); data->ok = 0; decoder_error_init (&data->error); /* Reset information about the file */ data->freq = 0; data->channels = 0; data->skip_frames = 0; data->bitrate = -1; data->avg_bitrate = -1; /* Open the file */ data->io_stream = io_open (file, buffered); if (io_ok(data->io_stream)) { data->ok = 1; data->size = io_file_size (data->io_stream); mad_stream_init (&data->stream); mad_frame_init (&data->frame); mad_synth_init (&data->synth); if (options_get_int("Mp3IgnoreCRCErrors")) mad_stream_options (&data->stream, MAD_OPTION_IGNORECRC); data->duration = count_time_internal (data); mad_frame_mute (&data->frame); data->stream.next_frame = NULL; data->stream.sync = 0; data->stream.error = MAD_ERROR_NONE; if (io_seek(data->io_stream, SEEK_SET, 0) == (off_t)-1) { decoder_error (&data->error, ERROR_FATAL, 0, "seek failed"); io_close (data->io_stream); mad_stream_finish (&data->stream); mad_frame_finish (&data->frame); mad_synth_finish (&data->synth); data->ok = 0; } data->stream.error = MAD_ERROR_BUFLEN; } else { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open: %s", io_strerror(data->io_stream)); io_close (data->io_stream); } return data; }
void sound_init(running_machine *machine) { attotime update_frequency = SOUND_UPDATE_FREQUENCY; const char *filename; /* handle -nosound */ nosound_mode = !options_get_bool(mame_options(), OPTION_SOUND); if (nosound_mode) Machine->sample_rate = 11025; /* count the speakers */ for (totalspeakers = 0; Machine->drv->speaker[totalspeakers].tag; totalspeakers++) ; VPRINTF(("total speakers = %d\n", totalspeakers)); /* allocate memory for mix buffers */ leftmix = auto_malloc(Machine->sample_rate * sizeof(*leftmix)); rightmix = auto_malloc(Machine->sample_rate * sizeof(*rightmix)); finalmix = auto_malloc(Machine->sample_rate * sizeof(*finalmix)); /* allocate a global timer for sound timing */ sound_update_timer = timer_alloc(sound_update, NULL); timer_adjust(sound_update_timer, update_frequency, 0, update_frequency); /* initialize the streams engine */ VPRINTF(("streams_init\n")); streams_init(machine, update_frequency.attoseconds); /* now start up the sound chips and tag their streams */ VPRINTF(("start_sound_chips\n")); start_sound_chips(); /* then create all the speakers */ VPRINTF(("start_speakers\n")); start_speakers(); /* finally, do all the routing */ VPRINTF(("route_sound\n")); route_sound(); /* open the output WAV file if specified */ filename = options_get_string(mame_options(), OPTION_WAVWRITE); if (filename[0] != 0) wavfile = wav_open(filename, machine->sample_rate, 2); /* enable sound by default */ global_sound_enabled = TRUE; sound_muted = FALSE; sound_set_attenuation(options_get_int(mame_options(), OPTION_VOLUME)); /* register callbacks */ config_register("mixer", sound_load, sound_save); add_pause_callback(machine, sound_pause); add_reset_callback(machine, sound_reset); add_exit_callback(machine, sound_exit); }
static char *get_tag (struct id3_tag *tag, const char *what) { struct id3_frame *frame; union id3_field *field; const id3_ucs4_t *ucs4; char *comm = NULL; frame = id3_tag_findframe (tag, what, 0); if (frame && (field = &frame->fields[1])) { ucs4 = id3_field_getstrings (field, 0); if (ucs4) { /* Workaround for ID3 tags v1/v1.1 where the encoding * is latin1. */ union id3_field *encoding_field = &frame->fields[0]; if ((id3_tag_options(tag, 0, 0) & ID3_TAG_OPTION_ID3V1) || ((options_get_int ("EnforceTagsEncoding") && (id3_field_gettextencoding((encoding_field)) == ID3_FIELD_TEXTENCODING_ISO_8859_1)))) { char *t; comm = (char *)id3_ucs4_latin1duplicate (ucs4); #ifdef HAVE_RCC if (options_get_int("UseRCC")) comm = do_rcc (comm); else { #endif /* HAVE_RCC */ t = comm; comm = id3v1_fix (comm); free (t); #ifdef HAVE_RCC } #endif /* HAVE_RCC */ } else comm = (char *)id3_ucs4_utf8duplicate (ucs4); } } return comm; }
/* Switch playlist titles to title_file */ void switch_titles_file (struct plist *plist) { int i; int hide_extension = options_get_int("HideFileExtension"); for (i = 0; i < plist->num; i++) if (!plist_deleted(plist, i)) { if (!plist->items[i].title_file) make_file_title (plist, i, hide_extension); assert (plist->items[i].title_file != NULL); plist->items[i].title = plist->items[i].title_file; } }
static int options_get(lua_State * L) { name k = to_name_ext(L, 2); auto it = get_option_declarations().find(k); if (it == get_option_declarations().end()) { throw exception(sstream() << "unknown option '" << k.to_string().c_str() << "'"); } else { option_declaration const & d = it->second; switch (d.kind()) { case BoolOption: return options_get_bool(L); case IntOption: return options_get_int(L); case UnsignedOption: return options_get_unsigned(L); case DoubleOption: return options_get_double(L); case StringOption: return options_get_string(L); default: throw exception(sstream() << "unsupported option kind for '" << k.to_string().c_str() << "'"); } } }
void sound_init(running_machine *machine) { sound_private *global; const char *filename; machine->sound_data = global = auto_alloc_clear(machine, sound_private); /* handle -nosound */ global->nosound_mode = !options_get_bool(machine->options(), OPTION_SOUND); if (global->nosound_mode) machine->sample_rate = 11025; /* count the speakers */ VPRINTF(("total speakers = %d\n", speaker_output_count(machine->config))); /* allocate memory for mix buffers */ global->leftmix = auto_alloc_array(machine, INT32, machine->sample_rate); global->rightmix = auto_alloc_array(machine, INT32, machine->sample_rate); global->finalmix = auto_alloc_array(machine, INT16, machine->sample_rate); /* allocate a global timer for sound timing */ global->update_timer = timer_alloc(machine, sound_update, NULL); timer_adjust_periodic(global->update_timer, STREAMS_UPDATE_ATTOTIME, 0, STREAMS_UPDATE_ATTOTIME); /* finally, do all the routing */ VPRINTF(("route_sound\n")); route_sound(machine); /* open the output WAV file if specified */ filename = options_get_string(machine->options(), OPTION_WAVWRITE); if (filename[0] != 0) global->wavfile = wav_open(filename, machine->sample_rate, 2); /* enable sound by default */ global->enabled = TRUE; global->muted = FALSE; sound_set_attenuation(machine, options_get_int(machine->options(), OPTION_VOLUME)); /* register callbacks */ config_register(machine, "mixer", sound_load, sound_save); machine->add_notifier(MACHINE_NOTIFY_PAUSE, sound_pause); machine->add_notifier(MACHINE_NOTIFY_RESUME, sound_resume); machine->add_notifier(MACHINE_NOTIFY_RESET, sound_reset); machine->add_notifier(MACHINE_NOTIFY_EXIT, sound_exit); }
void oipmi_main_loop() { if (options.singleiter_mode) { mce_process_log(); return; } log_msg("herd daemon started"); int timer = options_get_int("check_timer_secs"); if (timer <= 0) timer = 30; while (!self.do_exit) { mce_process_log(); sleep(timer); } }
static void set_realtime_prio () { #ifdef HAVE_SCHED_GET_PRIORITY_MAX int rc; if (options_get_int("UseRealtimePriority")) { struct sched_param param; param.sched_priority = sched_get_priority_max(SCHED_RR); rc = pthread_setschedparam (pthread_self (), SCHED_RR, ¶m); if (rc != 0) logit ("Can't set realtime priority: %s", strerror (rc)); } #else logit ("No sched_get_priority_max() function: realtime priority not " "used."); #endif }
/* Switch playlist titles to title_tags */ void switch_titles_tags (struct plist *plist) { int i; for (i = 0; i < plist->num; i++) if (!plist_deleted(plist, i)) { if (plist->items[i].title_tags) plist->items[i].title = plist->items[i].title_tags; else { if (!plist->items[i].title_file) make_file_title (plist, i, options_get_int("HideFileExtension")); plist->items[i].title = plist->items[i].title_file; } } }
static void *timidity_open (const char *file) { struct timidity_data *data = make_timidity_data(file); if(data->midisong) { data->length = mid_song_get_total_time(data->midisong); } if(data->midisong) { debug ("Opened file %s", file); mid_song_set_volume(data->midisong, options_get_int("TiMidity_Volume")); mid_song_start(data->midisong); } return data; }
/* The playlist may have deleted items. */ int plist_load (struct plist *plist, const char *fname, const char *cwd, const int load_serial) { int num; int read_tags = options_get_int ("ReadTags"); const char *ext = ext_pos (fname); if (ext && !strcasecmp(ext, "pls")) num = plist_load_pls (plist, fname, cwd); else num = plist_load_m3u (plist, fname, cwd, load_serial); if (read_tags) switch_titles_tags (plist); else switch_titles_file (plist); return num; }
/* Make a title from the tags for the item. */ void make_tags_title (struct plist *plist, const int num) { assert (plist != NULL); assert (num >= 0 && num < plist->num); assert (!plist_deleted(plist, num)); if (file_type(plist->items[num].file) == F_URL) make_file_title (plist, num, 0); else if (!plist->items[num].title_tags) { char *title; assert (plist->items[num].file != NULL); if (plist->items[num].tags->title) { title = build_title (plist->items[num].tags); plist_set_title_tags (plist, num, title); free (title); } else make_file_title (plist, num, options_get_int("HideFileExtension")); } }
/* Send requested option value to the client. Return 1 if OK. */ static int send_option (struct client *cli) { char *name; if (!(name = get_str(cli->socket))) return 0; /* We can send only a few options, others make no sense here. */ if (!valid_sync_option(name)) { logit ("Client wanted to get invalid option '%s'", name); free (name); return 0; } /* All supported options are integer type. */ if (!send_data_int(cli, options_get_int(name))) { free (name); return 0; } free (name); return 1; }
/* Move to the next file depending on the options set, the user * request and whether or not there are files in the queue. */ static void go_to_another_file () { int shuffle = options_get_int ("Shuffle"); int go_next = (play_next || options_get_int("AutoNext")); int curr_playing_curr_pos; /* XXX: Shouldn't play_next be protected by mutex? */ LOCK (curr_playing_mut); LOCK (plist_mut); /* If we move forward in the playlist and there are some songs in * the queue, then play them. */ if (plist_count(&queue) && go_next) { logit ("Playing file from queue"); if (!before_queue_fname && curr_playing_fname) before_queue_fname = xstrdup (curr_playing_fname); curr_plist = &queue; curr_playing = plist_next (&queue, -1); server_queue_pop (queue.items[curr_playing].file); plist_delete (&queue, curr_playing); } else { /* If we just finished playing files from the queue and the * appropriate option is set, continue with the file played * before playing the queue. */ if (before_queue_fname && options_get_int("QueueNextSongReturn")) { free (curr_playing_fname); curr_playing_fname = before_queue_fname; before_queue_fname = NULL; } if (shuffle) { curr_plist = &shuffled_plist; if (plist_count(&playlist) && !plist_count(&shuffled_plist)) { plist_cat (&shuffled_plist, &playlist); plist_shuffle (&shuffled_plist); if (curr_playing_fname) plist_swap_first_fname (&shuffled_plist, curr_playing_fname); } } else curr_plist = &playlist; curr_playing_curr_pos = plist_find_fname (curr_plist, curr_playing_fname); /* If we came from the queue and the last file in * queue wasn't in the playlist, we try to revert to * the QueueNextSongReturn = 1 behaviour. */ if (curr_playing_curr_pos == -1 && before_queue_fname) { curr_playing_curr_pos = plist_find_fname (curr_plist, before_queue_fname); } if (play_prev && plist_count(curr_plist)) { logit ("Playing previous..."); if (curr_playing_curr_pos == -1 || started_playing_in_queue) { curr_playing = plist_prev (curr_plist, -1); started_playing_in_queue = 0; } else curr_playing = plist_prev (curr_plist, curr_playing_curr_pos); if (curr_playing == -1) { if (options_get_int("Repeat")) curr_playing = plist_last (curr_plist); logit ("Beginning of the list."); } else logit ("Previous item."); } else if (go_next && plist_count(curr_plist)) { logit ("Playing next..."); if (curr_playing_curr_pos == -1 || started_playing_in_queue) { curr_playing = plist_next (curr_plist, -1); started_playing_in_queue = 0; } else curr_playing = plist_next (curr_plist, curr_playing_curr_pos); if (curr_playing == -1 && options_get_int("Repeat")) { if (shuffle) { plist_clear (&shuffled_plist); plist_cat (&shuffled_plist, &playlist); plist_shuffle (&shuffled_plist); } curr_playing = plist_next (curr_plist, -1); logit ("Going back to the first item."); } else if (curr_playing == -1) logit ("End of the list"); else logit ("Next item"); } else if (!options_get_int("Repeat")) { curr_playing = -1; } else debug ("Repeating file"); if (before_queue_fname) free (before_queue_fname); before_queue_fname = NULL; } UNLOCK (plist_mut); UNLOCK (curr_playing_mut); }
running_machine::running_machine(const game_driver &driver, const machine_config &_config, core_options &options, bool exit_to_game_select) : m_regionlist(m_respool), m_devicelist(m_respool), config(&_config), m_config(_config), firstcpu(NULL), gamedrv(&driver), m_game(driver), primary_screen(NULL), palette(NULL), pens(NULL), colortable(NULL), shadow_table(NULL), priority_bitmap(NULL), sample_rate(options_get_int(&options, OPTION_SAMPLERATE)), debug_flags(0), ui_active(false), mame_data(NULL), timer_data(NULL), state_data(NULL), memory_data(NULL), palette_data(NULL), tilemap_data(NULL), streams_data(NULL), devices_data(NULL), romload_data(NULL), sound_data(NULL), input_data(NULL), input_port_data(NULL), ui_input_data(NULL), cheat_data(NULL), debugcpu_data(NULL), generic_machine_data(NULL), generic_video_data(NULL), generic_audio_data(NULL), m_debug_view(NULL), driver_data(NULL), m_logerror_list(NULL), m_scheduler(*this), m_options(options), m_basename(driver.name), m_current_phase(MACHINE_PHASE_PREINIT), m_paused(false), m_hard_reset_pending(false), m_exit_pending(false), m_exit_to_game_select(exit_to_game_select), m_new_driver_pending(NULL), m_soft_reset_timer(NULL), m_saveload_schedule(SLS_NONE), m_saveload_schedule_time(attotime_zero), m_saveload_searchpath(NULL), m_rand_seed(0x9d14abd7) { memset(gfx, 0, sizeof(gfx)); memset(&generic, 0, sizeof(generic)); memset(m_notifier_list, 0, sizeof(m_notifier_list)); memset(&m_base_time, 0, sizeof(m_base_time)); /* attach this machine to all the devices in the configuration */ m_devicelist.import_config_list(m_config.m_devicelist, *this); /* allocate the driver data (after devices) */ if (m_config.m_driver_data_alloc != NULL) driver_data = (*m_config.m_driver_data_alloc)(*this); /* find devices */ primary_screen = screen_first(*this); for (device_t *device = m_devicelist.first(); device != NULL; device = device->next()) if (dynamic_cast<cpu_device *>(device) != NULL) { firstcpu = downcast<cpu_device *>(device); break; } cpu[0] = firstcpu; for (cpunum = 1; cpunum < ARRAY_LENGTH(cpu) && cpu[cpunum - 1] != NULL; cpunum++) cpu[cpunum] = cpu[cpunum - 1]->typenext(); /* fetch core options */ if (options_get_bool(&m_options, OPTION_DEBUG)) debug_flags = (DEBUG_FLAG_ENABLED | DEBUG_FLAG_CALL_HOOK) | (options_get_bool(&m_options, OPTION_DEBUG_INTERNAL) ? 0 : DEBUG_FLAG_OSD_ENABLED); }
/* Play a file (disk file) using the given decoder. next_file is precached. */ static void play_file (const char *file, const struct decoder *f, const char *next_file, struct out_buf *out_buf) { void *decoder_data; struct sound_params sound_params = { 0, 0, 0 }; float already_decoded_time; struct md5_data md5; #if !defined(NDEBUG) && defined(DEBUG) md5.okay = true; md5.len = 0; md5_init_ctx (&md5.ctx); #endif out_buf_reset (out_buf); precache_wait (&precache); if (precache.ok && strcmp(precache.file, file)) { logit ("The precached file is not the file we want."); precache.f->close (precache.decoder_data); precache_reset (&precache); } if (precache.ok && !strcmp(precache.file, file)) { struct decoder_error err; logit ("Using precached file"); assert (f == precache.f); sound_params = precache.sound_params; decoder_data = precache.decoder_data; set_info_channels (sound_params.channels); set_info_rate (sound_params.rate / 1000); if (!audio_open(&sound_params)) { md5.okay = false; precache.f->close (precache.decoder_data); precache_reset (&precache); return; } #if !defined(NDEBUG) && defined(DEBUG) md5.len += precache.buf_fill; md5_process_bytes (precache.buf, precache.buf_fill, &md5.ctx); #endif audio_send_buf (precache.buf, precache.buf_fill); precache.f->get_error (precache.decoder_data, &err); if (err.type != ERROR_OK) { md5.okay = false; if (err.type != ERROR_STREAM || options_get_int( "ShowStreamErrors")) error ("%s", err.err); decoder_error_clear (&err); } already_decoded_time = precache.decoded_time; if(f->get_avg_bitrate) set_info_avg_bitrate (f->get_avg_bitrate(decoder_data)); else set_info_avg_bitrate (0); bitrate_list_init (&bitrate_list); bitrate_list.head = precache.bitrate_list.head; bitrate_list.tail = precache.bitrate_list.tail; /* don't free list elements when reseting precache */ precache.bitrate_list.head = NULL; precache.bitrate_list.tail = NULL; } else { struct decoder_error err; status_msg ("Opening..."); decoder_data = f->open(file); f->get_error (decoder_data, &err); if (err.type != ERROR_OK) { f->close (decoder_data); status_msg (""); error ("%s", err.err); decoder_error_clear (&err); logit ("Can't open file, exiting"); return; } already_decoded_time = 0.0; if(f->get_avg_bitrate) set_info_avg_bitrate (f->get_avg_bitrate(decoder_data)); bitrate_list_init (&bitrate_list); } audio_plist_set_time (file, f->get_duration(decoder_data)); audio_state_started_playing (); precache_reset (&precache); decode_loop (f, decoder_data, next_file, out_buf, &sound_params, &md5, already_decoded_time); #if !defined(NDEBUG) && defined(DEBUG) if (md5.okay) { uint8_t buf[MD5_DIGEST_SIZE]; md5_finish_ctx (&md5.ctx, buf); log_md5_sum (file, sound_params, f, buf, md5.len); } #endif }
/* Decoder loop for already opened and probably running for some time decoder. * next_file will be precached at eof. */ static void decode_loop (const struct decoder *f, void *decoder_data, const char *next_file, struct out_buf *out_buf, struct sound_params *sound_params, struct md5_data *md5, const float already_decoded_sec) { bool eof = false; bool stopped = false; char buf[PCM_BUF_SIZE]; int decoded = 0; struct sound_params new_sound_params; bool sound_params_change = false; float decode_time = already_decoded_sec; /* the position of the decoder (in seconds) */ out_buf_set_free_callback (out_buf, buf_free_callback); LOCK (curr_tags_mut); curr_tags = tags_new (); UNLOCK (curr_tags_mut); if (f->get_stream) { LOCK (decoder_stream_mut); decoder_stream = f->get_stream (decoder_data); UNLOCK (decoder_stream_mut); } else logit ("No get_stream() function"); status_msg ("Playing..."); while (1) { debug ("loop..."); LOCK (request_cond_mutex); if (!eof && !decoded) { struct decoder_error err; UNLOCK (request_cond_mutex); if (decoder_stream && out_buf_get_fill(out_buf) < PREBUFFER_THRESHOLD) { prebuffering = 1; io_prebuffer (decoder_stream, options_get_int("Prebuffering") * 1024); prebuffering = 0; status_msg ("Playing..."); } decoded = f->decode (decoder_data, buf, sizeof(buf), &new_sound_params); if (decoded) decode_time += decoded / (float)(sfmt_Bps( new_sound_params.fmt) * new_sound_params.rate * new_sound_params.channels); f->get_error (decoder_data, &err); if (err.type != ERROR_OK) { md5->okay = false; if (err.type != ERROR_STREAM || options_get_int( "ShowStreamErrors")) error ("%s", err.err); decoder_error_clear (&err); } if (!decoded) { eof = true; logit ("EOF from decoder"); } else { debug ("decoded %d bytes", decoded); if (!sound_params_eq(new_sound_params, *sound_params)) sound_params_change = true; bitrate_list_add (&bitrate_list, decode_time, f->get_bitrate(decoder_data)); update_tags (f, decoder_data, decoder_stream); } } /* Wait, if there is no space in the buffer to put the decoded * data or EOF occurred and there is something in the buffer. */ else if (decoded > out_buf_get_free(out_buf) || (eof && out_buf_get_fill(out_buf))) { debug ("waiting..."); if (eof && !precache.file && next_file && file_type(next_file) == F_SOUND && options_get_int("Precache") && options_get_bool("AutoNext")) start_precache (&precache, next_file); pthread_cond_wait (&request_cond, &request_cond_mutex); UNLOCK (request_cond_mutex); } else UNLOCK (request_cond_mutex); /* When clearing request, we must make sure, that another * request will not arrive at the moment, so we check if * the request has changed. */ if (request == REQ_STOP) { logit ("stop"); stopped = true; md5->okay = false; out_buf_stop (out_buf); LOCK (request_cond_mutex); if (request == REQ_STOP) request = REQ_NOTHING; UNLOCK (request_cond_mutex); break; } else if (request == REQ_SEEK) { int decoder_seek; logit ("seeking"); md5->okay = false; req_seek = MAX(0, req_seek); if ((decoder_seek = f->seek(decoder_data, req_seek)) == -1) logit ("error when seeking"); else { out_buf_stop (out_buf); out_buf_reset (out_buf); out_buf_time_set (out_buf, decoder_seek); bitrate_list_empty (&bitrate_list); decode_time = decoder_seek; eof = false; decoded = 0; } LOCK (request_cond_mutex); if (request == REQ_SEEK) request = REQ_NOTHING; UNLOCK (request_cond_mutex); } else if (!eof && decoded <= out_buf_get_free(out_buf) && !sound_params_change) { debug ("putting into the buffer %d bytes", decoded); #if !defined(NDEBUG) && defined(DEBUG) if (md5->okay) { md5->len += decoded; md5_process_bytes (buf, decoded, &md5->ctx); } #endif audio_send_buf (buf, decoded); decoded = 0; } else if (!eof && sound_params_change && out_buf_get_fill(out_buf) == 0) { logit ("Sound parameters have changed."); *sound_params = new_sound_params; sound_params_change = false; set_info_channels (sound_params->channels); set_info_rate (sound_params->rate / 1000); out_buf_wait (out_buf); if (!audio_open(sound_params)) { md5->okay = false; break; } } else if (eof && out_buf_get_fill(out_buf) == 0) { logit ("played everything"); break; } } status_msg (""); LOCK (decoder_stream_mut); decoder_stream = NULL; f->close (decoder_data); UNLOCK (decoder_stream_mut); bitrate_list_destroy (&bitrate_list); LOCK (curr_tags_mut); if (curr_tags) { tags_free (curr_tags); curr_tags = NULL; } UNLOCK (curr_tags_mut); out_buf_wait (out_buf); if (precache.ok && (stopped || !options_get_bool ("AutoNext"))) { precache_wait (&precache); precache.f->close (precache.decoder_data); precache_reset (&precache); } }
//============================================================ // sdl_init //============================================================ static int sdl_init(running_machine *machine) { int n_channels = 2; int audio_latency; SDL_AudioSpec aspec, obtained; char audio_driver[16] = ""; if (initialized_audio) { sdl_cleanup_audio(*machine); } mame_printf_verbose("Audio: Start initialization\n"); #if (SDL_VERSION_ATLEAST(1,3,0)) strncpy(audio_driver, SDL_GetCurrentAudioDriver(), sizeof(audio_driver)); #else SDL_AudioDriverName(audio_driver, sizeof(audio_driver)); #endif mame_printf_verbose("Audio: Driver is %s\n", audio_driver); initialized_audio = 0; sdl_xfer_samples = SDL_XFER_SAMPLES; stream_in_initialized = 0; stream_loop = 0; // set up the audio specs aspec.freq = machine->sample_rate; aspec.format = AUDIO_S16SYS; // keep endian independent aspec.channels = n_channels; aspec.samples = sdl_xfer_samples; aspec.callback = sdl_callback; aspec.userdata = 0; if (SDL_OpenAudio(&aspec, &obtained) < 0) goto cant_start_audio; initialized_audio = 1; snd_enabled = 1; mame_printf_verbose("Audio: frequency: %d, channels: %d, samples: %d\n", obtained.freq, obtained.channels, obtained.samples); sdl_xfer_samples = obtained.samples; audio_latency = options_get_int(machine->options(), SDLOPTION_AUDIO_LATENCY); // pin audio latency if (audio_latency > MAX_AUDIO_LATENCY) { audio_latency = MAX_AUDIO_LATENCY; } else if (audio_latency < 1) { audio_latency = 1; } // compute the buffer sizes stream_buffer_size = machine->sample_rate * 2 * sizeof(INT16) * audio_latency / MAX_AUDIO_LATENCY; stream_buffer_size = (stream_buffer_size / 1024) * 1024; if (stream_buffer_size < 1024) stream_buffer_size = 1024; // create the buffers if (sdl_create_buffers()) goto cant_create_buffers; mame_printf_verbose("Audio: End initialization\n"); return 0; // error handling cant_create_buffers: cant_start_audio: mame_printf_verbose("Audio: Initialization failed. SDL error: %s\n", SDL_GetError()); return 0; }
/* Initialize the server - return fd of the listening socket or -1 on error */ int server_init (int debugging, int foreground) { struct sockaddr_un sock_name; int server_sock; int pid; logit ("Starting MOC Server"); pid = check_pid_file (); if (pid && valid_pid(pid)) { fprintf (stderr, "\nIt seems that the server is already running" " with pid %d.\n", pid); fprintf (stderr, "If it is not true, remove the pid file (%s)" " and try again.\n", create_file_name(PID_FILE)); fatal ("Exiting!"); } if (foreground) log_init_stream (stdout, "stdout"); else { FILE *logfp; logfp = NULL; if (debugging) { logfp = fopen (SERVER_LOG, "a"); if (!logfp) fatal ("Can't open server log file: %s", strerror (errno)); } log_init_stream (logfp, SERVER_LOG); } if (pipe(wake_up_pipe) < 0) fatal ("pipe() failed: %s", strerror(errno)); unlink (socket_name()); /* Create a socket */ if ((server_sock = socket (PF_LOCAL, SOCK_STREAM, 0)) == -1) fatal ("Can't create socket: %s", strerror(errno)); sock_name.sun_family = AF_LOCAL; strcpy (sock_name.sun_path, socket_name()); /* Bind to socket */ if (bind(server_sock, (struct sockaddr *)&sock_name, SUN_LEN(&sock_name)) == -1) fatal ("Can't bind() to the socket: %s", strerror(errno)); if (listen(server_sock, 1) == -1) fatal ("listen() failed: %s", strerror(errno)); audio_initialize (); tags_cache_init (&tags_cache, options_get_int("TagsCacheSize")); tags_cache_load (&tags_cache, create_file_name("cache")); clients_init (); server_tid = pthread_self (); thread_signal (SIGTERM, sig_exit); thread_signal (SIGINT, foreground ? sig_exit : SIG_IGN); thread_signal (SIGHUP, SIG_IGN); thread_signal (SIGQUIT, sig_exit); thread_signal (SIGPIPE, SIG_IGN); write_pid_file (); if (!foreground) { setsid (); redirect_output (stdin); redirect_output (stdout); redirect_output (stderr); } return server_sock; }
static void extract_video_config(void) { const char *stemp; // performance options: extract the data video_config.autoframeskip = options_get_bool("autoframeskip"); video_config.frameskip = options_get_int_range("frameskip", 0, FRAMESKIP_LEVELS); video_config.throttle = options_get_bool("throttle"); video_config.sleep = options_get_bool("sleep"); // misc options: extract the data video_config.framestorun = options_get_int("frames_to_run"); // global options: extract the data video_config.windowed = options_get_bool("window"); video_config.prescale = options_get_int("prescale"); video_config.keepaspect = options_get_bool("keepaspect"); video_config.numscreens = options_get_int_range("numscreens", 1, MAX_WINDOWS); #ifdef MAME_DEBUG // if we are in debug mode, never go full screen if (options.mame_debug) video_config.windowed = TRUE; #endif stemp = options_get_string("effect"); if (stemp != NULL && strcmp(stemp, "none") != 0) load_effect_overlay(stemp); // configure layers video_config.layerconfig = LAYER_CONFIG_DEFAULT; if (!options_get_bool("use_backdrops")) video_config.layerconfig &= ~LAYER_CONFIG_ENABLE_BACKDROP; if (!options_get_bool("use_overlays")) video_config.layerconfig &= ~LAYER_CONFIG_ENABLE_OVERLAY; if (!options_get_bool("use_bezels")) video_config.layerconfig &= ~LAYER_CONFIG_ENABLE_BEZEL; if (options_get_bool("artwork_crop")) video_config.layerconfig |= LAYER_CONFIG_ZOOM_TO_SCREEN; // per-window options: extract the data get_resolution("resolution0", &video_config.window[0], TRUE); get_resolution("resolution1", &video_config.window[1], TRUE); get_resolution("resolution2", &video_config.window[2], TRUE); get_resolution("resolution3", &video_config.window[3], TRUE); // video options: extract the data stemp = options_get_string("video"); if (strcmp(stemp, "d3d") == 0) video_config.mode = VIDEO_MODE_D3D; else if (strcmp(stemp, "ddraw") == 0) video_config.mode = VIDEO_MODE_DDRAW; else if (strcmp(stemp, "gdi") == 0) video_config.mode = VIDEO_MODE_GDI; else if (strcmp(stemp, "none") == 0) { video_config.mode = VIDEO_MODE_NONE; if (video_config.framestorun == 0) fprintf(stderr, "Warning: -video none doesn't make much sense without -frames_to_run\n"); } else { fprintf(stderr, "Invalid video value %s; reverting to gdi\n", stemp); video_config.mode = VIDEO_MODE_GDI; } video_config.waitvsync = options_get_bool("waitvsync"); video_config.syncrefresh = options_get_bool("syncrefresh"); video_config.triplebuf = options_get_bool("triplebuffer"); video_config.switchres = options_get_bool("switchres"); // ddraw options: extract the data video_config.hwstretch = options_get_bool("hwstretch"); // d3d options: extract the data video_config.filter = options_get_bool("filter"); if (video_config.prescale == 0) video_config.prescale = 1; // misc options: sanity check values // per-window options: sanity check values // d3d options: sanity check values options_get_int_range("d3dversion", 8, 9); options_get_float_range("full_screen_brightness", 0.1f, 2.0f); options_get_float_range("full_screen_contrast", 0.1f, 2.0f); options_get_float_range("full_screen_gamma", 0.1f, 3.0f); }
/* Initialize the server - return fd of the listening socket or -1 on error */ void server_init (int debugging, int foreground) { struct sockaddr_un sock_name; pid_t pid; logit ("Starting MOC Server"); assert (server_sock == -1); pid = check_pid_file (); if (pid && valid_pid(pid)) { fprintf (stderr, "\nIt seems that the server is already running" " with pid %d.\n", pid); fprintf (stderr, "If it is not true, remove the pid file (%s)" " and try again.\n", create_file_name(PID_FILE)); fatal ("Exiting!"); } if (foreground) log_init_stream (stdout, "stdout"); else { FILE *logfp; logfp = NULL; if (debugging) { logfp = fopen (SERVER_LOG, "a"); if (!logfp) fatal ("Can't open server log file: %s", xstrerror (errno)); } log_init_stream (logfp, SERVER_LOG); } if (pipe(wake_up_pipe) < 0) fatal ("pipe() failed: %s", xstrerror (errno)); unlink (socket_name()); /* Create a socket. * For reasons why AF_UNIX is the correct constant to use in both * cases, see the commentary the SVN log for commit r9999. */ server_sock = socket (AF_UNIX, SOCK_STREAM, 0); if (server_sock == -1) fatal ("Can't create socket: %s", xstrerror (errno)); sock_name.sun_family = AF_UNIX; strcpy (sock_name.sun_path, socket_name()); /* Bind to socket */ if (bind(server_sock, (struct sockaddr *)&sock_name, SUN_LEN(&sock_name)) == -1) fatal ("Can't bind() to the socket: %s", xstrerror (errno)); if (listen(server_sock, 1) == -1) fatal ("listen() failed: %s", xstrerror (errno)); /* Log stack sizes so stack overflows can be debugged. */ log_process_stack_size (); log_pthread_stack_size (); clients_init (); audio_initialize (); tags_cache = tags_cache_new (options_get_int("TagsCacheSize")); tags_cache_load (tags_cache, create_file_name("cache")); server_tid = pthread_self (); xsignal (SIGTERM, sig_exit); xsignal (SIGINT, foreground ? sig_exit : SIG_IGN); xsignal (SIGHUP, SIG_IGN); xsignal (SIGQUIT, sig_exit); xsignal (SIGPIPE, SIG_IGN); xsignal (SIGCHLD, sig_chld); write_pid_file (); if (!foreground) { setsid (); redirect_output (stdin); redirect_output (stdout); redirect_output (stderr); } return; }
static HRESULT dsound_init(running_machine *machine) { HRESULT result; // create the DirectSound object result = DirectSoundCreate(NULL, &dsound, NULL); if (result != DS_OK) { mame_printf_error("Error creating DirectSound: %08x\n", (UINT32)result); goto error; } // get the capabilities dsound_caps.dwSize = sizeof(dsound_caps); result = IDirectSound_GetCaps(dsound, &dsound_caps); if (result != DS_OK) { mame_printf_error("Error getting DirectSound capabilities: %08x\n", (UINT32)result); goto error; } // set the cooperative level result = IDirectSound_SetCooperativeLevel(dsound, win_window_list->hwnd, DSSCL_PRIORITY); if (result != DS_OK) { mame_printf_error("Error setting DirectSound cooperative level: %08x\n", (UINT32)result); goto error; } // make a format description for what we want stream_format.wBitsPerSample = 16; stream_format.wFormatTag = WAVE_FORMAT_PCM; stream_format.nChannels = 2; stream_format.nSamplesPerSec = machine->sample_rate; stream_format.nBlockAlign = stream_format.wBitsPerSample * stream_format.nChannels / 8; stream_format.nAvgBytesPerSec = stream_format.nSamplesPerSec * stream_format.nBlockAlign; // compute the buffer size based on the output sample rate stream_buffer_size = stream_format.nSamplesPerSec * stream_format.nBlockAlign * options_get_int(machine->options(), WINOPTION_AUDIO_LATENCY) / 10; stream_buffer_size = (stream_buffer_size / 1024) * 1024; if (stream_buffer_size < 1024) stream_buffer_size = 1024; LOG(("stream_buffer_size = %d\n", stream_buffer_size)); // create the buffers result = dsound_create_buffers(); if (result != DS_OK) goto error; // start playing result = IDirectSoundBuffer_Play(stream_buffer, 0, 0, DSBPLAY_LOOPING); if (result != DS_OK) { mame_printf_error("Error playing: %08x\n", (UINT32)result); goto error; } return DS_OK; // error handling error: dsound_destroy_buffers(); dsound_kill(); return result; }
void softmixer_shutdown() { if(options_get_int(SOFTMIXER_SAVE_OPTION)) softmixer_write_config(); logit ("Softmixer stopped"); }
static void extract_video_config(running_machine *machine) { const char *stemp; // global options: extract the data video_config.windowed = options_get_bool(&machine->options(), WINOPTION_WINDOW); video_config.prescale = options_get_int(&machine->options(), WINOPTION_PRESCALE); video_config.keepaspect = options_get_bool(&machine->options(), WINOPTION_KEEPASPECT); video_config.numscreens = options_get_int(&machine->options(), WINOPTION_NUMSCREENS); // if we are in debug mode, never go full screen if (machine->debug_flags & DEBUG_FLAG_OSD_ENABLED) video_config.windowed = TRUE; // per-window options: extract the data get_resolution(machine->options(), WINOPTION_RESOLUTION0, &video_config.window[0], TRUE); get_resolution(machine->options(), WINOPTION_RESOLUTION1, &video_config.window[1], TRUE); get_resolution(machine->options(), WINOPTION_RESOLUTION2, &video_config.window[2], TRUE); get_resolution(machine->options(), WINOPTION_RESOLUTION3, &video_config.window[3], TRUE); // video options: extract the data stemp = options_get_string(&machine->options(), WINOPTION_VIDEO); if (strcmp(stemp, "d3d") == 0) video_config.mode = VIDEO_MODE_D3D; else if (strcmp(stemp, "ddraw") == 0) video_config.mode = VIDEO_MODE_DDRAW; else if (strcmp(stemp, "gdi") == 0) video_config.mode = VIDEO_MODE_GDI; else if (strcmp(stemp, "none") == 0) { video_config.mode = VIDEO_MODE_NONE; if (options_get_int(&machine->options(), OPTION_SECONDS_TO_RUN) == 0) mame_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n"); } else { mame_printf_warning("Invalid video value %s; reverting to gdi\n", stemp); video_config.mode = VIDEO_MODE_GDI; } video_config.waitvsync = options_get_bool(&machine->options(), WINOPTION_WAITVSYNC); video_config.syncrefresh = options_get_bool(&machine->options(), WINOPTION_SYNCREFRESH); video_config.triplebuf = options_get_bool(&machine->options(), WINOPTION_TRIPLEBUFFER); video_config.switchres = options_get_bool(&machine->options(), WINOPTION_SWITCHRES); // ddraw options: extract the data video_config.hwstretch = options_get_bool(&machine->options(), WINOPTION_HWSTRETCH); // d3d options: extract the data video_config.filter = options_get_bool(&machine->options(), WINOPTION_FILTER); if (video_config.prescale == 0) video_config.prescale = 1; // misc options: sanity check values // per-window options: sanity check values // d3d options: sanity check values options_get_int(&machine->options(), WINOPTION_D3DVERSION); options_get_float(&machine->options(), WINOPTION_FULLSCREENBRIGHTNESS); options_get_float(&machine->options(), WINOPTION_FULLLSCREENCONTRAST); options_get_float(&machine->options(), WINOPTION_FULLSCREENGAMMA); }