예제 #1
0
int main(int argc, char **argv)

{
	
	//Initialize some sounds for high quality sounding moans and SCREAMS from the ACTION!
	srvInit();
	aptInit();
	hidInit();
	csndInit();
	gfxInitDefault();
	consoleInit(GFX_TOP, NULL);



	printf("\x1b[1;5HGuess who is the freshest squid around?");
	wait(10000);
	printf("           ");
	printf("\x1b[5;19H\x1b[32m\ Marie Squid\x1b[0m\n");
	printf("\x1b[16;3HPress Start to know that such fresh exists.");
	printf("\x1b[17;3HPress A to get INTO IT!");

	

	// Main loop
	while (aptMainLoop())
	{
		//Scan all the inputs. This should be done once for each frame mostly for the shoots
		hidScanInput();
		

		//hidKeysDown returns information about which buttons have been just pressed (and they weren't in the previous frame)
		hidScanInput();
		u32 kDown = hidKeysDown();
		if (kDown & KEY_START){   //PRESS START TO RETURN TO HBL
		}
		if (kDown & KEY_A){   // PRESS A TO PLAY
			audio_load("squit.bin");
		}
		
		
		// Flush and swap framebuffers
		gfxFlushBuffers();
		gfxSwapBuffers();

		//Wait for VBlank
		gspWaitForVBlank();
	}

	// Exit services... I know you want to come back...

	audio_stop();
	audio_stop();
	csndExit();
	gfxExit();
	hidExit();
	aptExit();
	srvExit();
	return 0;
}
예제 #2
0
void exitServices() {
    if (titlemenuIsUpdating) {
        //Stop the title menu loading process, causing the thread to exit
        cancelTitleLoading();

        //Wait a little bit (two seconds) longer to allow the thread to actually terminate
        svcSleepThread(2000000000ULL);
    }

    if (titleThreadNeedsRelease) {
        releaseTitleThread();
    }

    // cleanup whatever we have to cleanup
	audio_stop();
	csndExit();

    freeThemeImages();
    netloader_exit();
    titlesExit();
    ptmuExit();
    acExit();
    hidExit();
    gfxExit();
    closeSDArchive();
    exitFilesystem();
    aptExit();
    srvExit();
}
예제 #3
0
파일: main.cpp 프로젝트: Lamobo/Lamobo-D1
static void appExit()
{
	printf("##appExit\n");
	//if (bHasAudio)
	{
		audio_stop();
		audio_close();
		printf("audio_close\n");
	}
	close_encode();
	audio_dec_exit();
	video_process_stop();
	usleep(200 * 1000);
	camera_close();
	printf("camera_close\n");
	encode_close();
	printf("encode_close\n");
	mux_exit();
	printf("mux_close\n");

	encode_destroy();
	akuio_pmem_fini();
	setled_off();
	PTZControlDeinit();
	printf("akuio_pmem_fini\n");
	
    record_rename_file();

}
예제 #4
0
파일: main.c 프로젝트: Ferk/andLess
JNIEXPORT jint JNICALL Java_net_avs234_AndLessSrv_audioInit(JNIEnv *env, jobject obj, msm_ctx *prev_ctx, jint mode) {

  msm_ctx *ctx;

    if(prev_ctx) {
	audio_stop(prev_ctx);
	ctx = prev_ctx;
    } else {
	ctx = (msm_ctx *) malloc(sizeof(msm_ctx));	 	
	if(!ctx) return 0;
	memset(ctx,0,sizeof(msm_ctx));
	ctx->wavbuf = (unsigned char *)  malloc(DEFAULT_WAV_BUFSZ);
	if(!ctx->wavbuf) {
        	free(ctx); return 0;
    	}
        ctx->afd = -1; ctx->fd = -1;
	pthread_mutex_init(&ctx->mutex,0);
	pthread_mutex_init(&ctx->cbmutex,0);
	pthread_cond_init(&ctx->cbcond,0);
	pthread_cond_init(&ctx->cbdone,0);
    }	
    ctx->mode = mode;
    ctx->state = MSM_STOPPED;
    ctx->track_time = 0;	
    return (jint) ctx;	
}
예제 #5
0
int main(int argc, char *argv[])
{
    SDL_Surface* screen = NULL, *menu = NULL;
    SDL_Rect positionMenu;
    SDL_Event event;

    int continuer = 1;

    audio_init();
    audio_play(1);

    SDL_Init(SDL_INIT_VIDEO);

    SDL_WM_SetIcon(IMG_Load("images/Mario.png"), NULL); // L'icône doit être chargée avant SDL_SetVideoMode
    screen = SDL_SetVideoMode(600, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); //Ouvre la page
    SDL_WM_SetCaption("Super Mario BROS", NULL); //Définit le titre

    menu = IMG_Load("images/menu.jpg"); //Charge l'image du menu
    positionMenu.x = screen->w / 2 - menu->w / 2; //Définit le menu au centre de la fenêtre
    positionMenu.y = 0;


    while (continuer)
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                continuer = 0;
                break;
            case SDL_KEYDOWN:
                switch(event.key.keysym.sym)
                {
                    case SDLK_ESCAPE:
                        continuer = 0;
                        break;
                    case SDLK_1:

                        game(screen);
                        screen = SDL_SetVideoMode(600, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
                        break;
                    case SDLK_2:
                        credits(screen);
                        break;
                }
                break;
        }

        SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); //Fond noir
        SDL_BlitSurface(menu, NULL, screen, &positionMenu); //Imprime le menu sur la page
        SDL_Flip(screen);
    }

    audio_stop();
    SDL_FreeSurface(menu); //Efface le menu
    SDL_Quit(); //Quitte

    return EXIT_SUCCESS;
}
예제 #6
0
/**
 * Now, switch to background
 */
static javacall_result video_switch_to_background(javacall_handle handle, int options) {
    audio_handle* pHandle = (audio_handle*)handle;
    pHandle->isForeground = JAVACALL_FALSE;

    // Stop the current playing
    audio_stop(handle);

    return JAVACALL_OK;
}
예제 #7
0
static int connect_callback(slimproto_t *p, bool isConnected, void *user_data) {
    if (!isConnected) {
        DEBUGF("Stopping audio because of disconnection.\n");
        slimaudio_t *audio = (slimaudio_t*)user_data;
        audio_stop(audio);
    }

    return 0;
}
예제 #8
0
static gboolean
quit (void)
{
  check_dirty ();

  g_print ("quit!\n");
  audio_stop ();
  gtk_main_quit ();
  return TRUE;
}
예제 #9
0
파일: machine.c 프로젝트: sronsse/emux
void quit()
{
	/* Stop audio processing */
	audio_stop();

	/* Unregister quit events */
	input_unregister(&input_config);

	/* Deinitialize machine */
	machine_deinit();
}
예제 #10
0
/****************************************************************
  Callback either loading suggested soundset or doing nothing
*****************************************************************/
static void soundset_suggestion_callback(GtkWidget *dlg, gint arg)
{
  if (arg == GTK_RESPONSE_YES) {
    /* User accepted soundset loading */

    audio_stop(); /* Fade down old one */

    sz_strlcpy(sound_set_name, game.control.prefered_soundset);
    audio_real_init(sound_set_name, sound_plugin_name);
  }
}
예제 #11
0
/*
 * Close audio resources
 */
int slimaudio_close(slimaudio_t *audio) {
    audio_stop(audio);

    if (slimaudio_http_close(audio) != 0)
        return -1;
    if (slimaudio_decoder_close(audio) != 0)
        return -1;
    if (slimaudio_output_close(audio) != 0)
        return -1;

    return 0;
}
예제 #12
0
파일: main.c 프로젝트: Ferk/andLess
JNIEXPORT jboolean JNICALL Java_net_avs234_AndLessSrv_audioExit(JNIEnv *env, jobject obj, msm_ctx *ctx) {
    if(!ctx) return false;
    audio_stop(ctx);
    if(ctx->fd >= 0)  close(ctx->fd);
    pthread_mutex_destroy(&ctx->mutex);
    pthread_mutex_destroy(&ctx->cbmutex);
    pthread_cond_destroy(&ctx->cbcond);
    pthread_cond_destroy(&ctx->cbdone);
    if(ctx->wavbuf) free(ctx->wavbuf);
    if(ctx->cbbuf) free(ctx->cbbuf);		
    free(ctx);	
    return true;
}
예제 #13
0
파일: libretro.c 프로젝트: sronsse/emux
void retro_unload_game(void)
{
	/* Return already if machine was not initialized */
	if (!machine_initialized)
		return;

	/* Stop audio processing */
	audio_stop();

	/* Deinitialize machine */
	machine_deinit();
	machine_initialized = false;
}
예제 #14
0
파일: bookmark.c 프로젝트: Rockbox/rockbox
/* ----------------------------------------------------------------------- */
bool bookmark_autobookmark(bool prompt_ok)
{
    char*  bookmark;
    bool update;

    if (!bookmark_is_bookmarkable_state())
        return false;

    audio_pause();    /* first pause playback */
    update = (global_settings.autoupdatebookmark && bookmark_exists());
    bookmark = create_bookmark();
#if CONFIG_CODEC != SWCODEC
    /* Workaround for inability to speak when paused: all callers will
       just do audio_stop() when we return, so we can do it right
       away. This makes it possible to speak the "Create a Bookmark?"
       prompt and the "Bookmark Created" splash. */
    audio_stop();
#endif

    if (update)
        return write_bookmark(true, bookmark);

    switch (global_settings.autocreatebookmark)
    {
        case BOOKMARK_YES:
            return write_bookmark(true, bookmark);

        case BOOKMARK_NO:
            return false;

        case BOOKMARK_RECENT_ONLY_YES:
            return write_bookmark(false, bookmark);
    }
#ifdef HAVE_LCD_BITMAP
    const char *lines[]={ID2P(LANG_AUTO_BOOKMARK_QUERY)};
    const struct text_message message={lines, 1};
#else
    const char *lines[]={ID2P(LANG_AUTO_BOOKMARK_QUERY),
                            str(LANG_CONFIRM_WITH_BUTTON)};
    const struct text_message message={lines, 2};
#endif

    if(prompt_ok && gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES)
    {
        if (global_settings.autocreatebookmark == BOOKMARK_RECENT_ONLY_ASK)
            return write_bookmark(false, bookmark);
        else
            return write_bookmark(true, bookmark);
    }
    return false;
}
예제 #15
0
파일: audio.c 프로젝트: 2085020/freeciv-web
/**************************************************************************
  Call this at end of program only.
**************************************************************************/
void audio_shutdown()
{
  /* avoid infinite loop at end of game */
  audio_stop();

  audio_play_sound("e_game_quit", NULL);
  plugins[selected_plugin].wait();
  plugins[selected_plugin].shutdown();

  if (tagfile) {
    section_file_free(tagfile);
    tagfile = NULL;
  }
}
예제 #16
0
int main()
{
    // Inits
    srvInit();
    aptInit();
    hidInit();
    bool stop = 0;


    csndInit();//start Audio Lib
    u32 kDown;

    while (aptMainLoop()) {

        hidScanInput();
        kDown = hidKeysDown();
        if (kDown & KEY_START) {  //PRESS START TO RETURN TO HBL
            stop=1;
        }
        if (kDown & KEY_A) {  // PRESS A TO PLAY
            audio_load("audio/original_raw.bin");
        }
        if (stop) {
            break;
        }
    }

    audio_stop();
    audio_stop();
    csndExit();

    hidExit();
    aptExit();
    srvExit();

    return 0;
}
예제 #17
0
void setTheme(char * themeName) {
    audio_stop();

    //Save the selected theme in main config
    setConfigString("currentTheme", themeName, configTypeMain);

    //Reload theme config
    loadConfigWithType(configTypeTheme);

    //Reload theme variables for menu
    loadThemeConfig();

    loadSplashImages();

    if (themeImageExists(themeImageSplashTop)) {
        drawThemeImage(themeImageSplashTop, GFX_TOP, 0, 0);
    }
    if (themeImageExists(themeImageSplashBottom)) {
        drawThemeImage(themeImageSplashBottom, GFX_BOTTOM, 0, 0);
    }

    gfxFlip();

    int startMs = osGetTime();
    playBootSound();

    //Reload theme images
    initThemeImages();

	//Load BGM
    initThemeSounds();

    //Re-initialise colours
    initColours();

    //Force reload of GUI elements
    statusbarNeedsUpdate = true;
    toolbarNeedsUpdate = true;
    alphaImagesDrawn = false;

    waitForDurationOfSound(&themeSoundBoot, startMs);

    startBGM();

    panelsDrawn = false;
    pageControlPanelsDrawn = false;
}
예제 #18
0
파일: portplay.c 프로젝트: yoggy/portplay
int main(int argc, char* argv[])
{
    PaError err = paNoError;
    int device_id;
    BOOL rv;

    err = Pa_Initialize();
    if (err != paNoError) {
        fprintf(stderr, "Pa_Initialize() failed...\n");
        exit(1);
    }

    if (argc != 3) {
        printf("usage: %s devide_id wav_file\n\n", argv[0]);
        print_deviceinfo();
        Pa_Terminate();
        return 1;
    }

    rv = wavfile_open(argv[2]);
    if (rv == FALSE) {
        fprintf(stderr, "wav file open failed...\n");
        Pa_Terminate();
        exit(1);
    }

    device_id = atoi(argv[1]);
    rv = audio_start(device_id);
    if (rv == FALSE) {
        fprintf(stderr, "AudioDevice initialize failed...device_id=%d\n", device_id);
        Pa_Terminate();
        return 1;
    }

    while (1) {
        Pa_Sleep(100);
        if (finish_flag == TRUE) break;
    }

    audio_stop();
    Pa_Terminate();

    wavfile_close();

    return 0;
}
예제 #19
0
파일: call.c 프로젝트: sealaunch/baresip
static void call_stream_stop(struct call *call)
{
	if (!call)
		return;

	call->time_stop = time(NULL);

	/* Audio */
	audio_stop(call->audio);

	/* Video */
#ifdef USE_VIDEO
	video_stop(call->video);
#endif

	tmr_cancel(&call->tmr_inv);
}
예제 #20
0
파일: lysdr.c 프로젝트: gordonjcp/lysdr
int main(int argc, char *argv[]) {
	GError *error = NULL;
	GOptionContext *context;


	printf("lysdr starting\n");

	// gtk3 remove threads, see how badly things go wrong
	//gdk_threads_init();
	//gdk_threads_enter();

	gtk_init(&argc, &argv);

	context = g_option_context_new ("-");
	g_option_context_add_main_entries (context, opts, NULL);
	g_option_context_add_group (context, gtk_get_option_group (TRUE));
	if (!g_option_context_parse (context, &argc, &argv, &error)) {
		g_print ("option parsing failed: %s\n", error->message);
		exit (1);
	}

	// create a new SDR, and set up the jack client
	sdr = sdr_new(fft_size);
	audio_start(sdr);

	// define a filter and configure a default shape
	sdr->filter = filter_fir_new(128, sdr->size);

	// hook up the jack ports and start the client
	fft_setup(sdr);
	audio_connect(sdr, connect_input, connect_output);

	sdr->centre_freq = centre_freq;

	gui_display(sdr);
	gtk_adjustment_set_value(GTK_ADJUSTMENT(sdr->tuning), 0);

	gtk_main();
	audio_stop(sdr);
	filter_fir_destroy(sdr->filter);
	fft_teardown(sdr);

	sdr_destroy(sdr);
	//gdk_threads_leave();
}
예제 #21
0
static void
sequence_play_clicked (void)
{
  GtkTreeSelection *selection;
  GtkTreePath *path;
  GtkTreeIter iter;

  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (play_button)) == FALSE)
    {
      g_print ("stopping.\n");
      if (sequence_source_id > 0)
        g_source_remove (sequence_source_id);
      gtk_progress_bar_update (GTK_PROGRESS_BAR (progress_bar), 0);
      sequence_source_id = 0;
      current_step = NULL;
      audio_stop ();
      g_timeout_add (50, audio_stop_timeout, NULL);
      return;
    }

  selection = gtk_tree_view_get_selection (sequence_view);
  if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
    {
      sequence_first ();
      selection = gtk_tree_view_get_selection (sequence_view);
      if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
        return;
    }
  
  path = gtk_tree_model_get_path (GTK_TREE_MODEL (sequence_store), &iter);
  
  gtk_tree_model_get (GTK_TREE_MODEL (sequence_store), &iter,
                      COLUMN_DATA, &current_step,
                      -1);

  current_step->progress = 0;
  last_scene = NULL;
  g_print ("starting...\n");
  sequence_source_id = g_timeout_add (10, (GSourceFunc) sequence_tick, NULL);
}
예제 #22
0
파일: audio.c 프로젝트: mralexgray/baresip
static void audio_destructor(void *arg)
{
	struct audio *a = arg;

	audio_stop(a);

	mem_deref(a->tx.enc);
	mem_deref(a->rx.dec);
	mem_deref(a->tx.ab);
	mem_deref(a->tx.mb);
	mem_deref(a->tx.sampv);
	mem_deref(a->rx.sampv);
	mem_deref(a->rx.ab);
	mem_deref(a->tx.sampv_rs);
	mem_deref(a->tx.resamp);
	mem_deref(a->rx.sampv_rs);
	mem_deref(a->rx.resamp);

	mem_deref(a->strm);
	mem_deref(a->telev);
	list_flush(&a->filtl);
}
예제 #23
0
/*
 * Callback for 'strm' command.
 */
static int strm_callback(slimproto_t *proto, const unsigned char *buf, int buf_len, void *user_data) {
	slimproto_msg_t msg;
	
	slimaudio_t *audio = (slimaudio_t *) user_data;
	slimproto_parse_command(buf, buf_len, &msg);

	DEBUGF("strm cmd %c\n", msg.strm.command);

	switch (msg.strm.command) {
		case 's': /* start */
			slimaudio_http_connect(audio, &msg);
			slimaudio_decoder_connect(audio, &msg);
			slimaudio_output_connect(audio, &msg);
			break;
			
		case 'p': /* pause */
			slimaudio_output_pause(audio);
			break;	
		
		case 'u': /* unpause */
			slimaudio_output_unpause(audio);
			break;	
		
		case 'q': /* stop */
			audio_stop(audio);
			break;	
		
		case 't': /* status */
			break;			
	}
	
	slimaudio_stat(audio, (char *)&msg.strm.cmd);
	
	DEBUGF("DONE strm cmd %c\n", msg.strm.command);
	return 0;
}
예제 #24
0
/*
 * load file/stream.
 */
int internal_output_loadfile(const string spath)
{
	int perror_on_decoder = 1;

	/* history, oh, fading away */

	if(player.state != v_audio_playerstate_init)
		audio_stop();

	
	/* "this is my turn" */

	sys_thread_share_request(&internal_output_share);

	/* this state would be a message to the user */

	player.state = v_audio_playerstate_opening;


	/* load default values */

	player.output_bitdepth = settings.audio_output.bit_depth;
	player.output_float    = settings.audio_output.bit_depth_float;
	player.output_signed   = settings.audio_output.bit_depth_signed;


	/* select input plugin */

	player.input_plugin = audio_input_selectinput(spath);

	/* no! */

	if(player.input_plugin == fennec_invalid_index) goto point_error;


	/* initialize the plugin */

	audio_input_plugin_initialize(player.input_plugin);
	audio_input_plugin_loadfile(player.input_plugin, spath, &player.stream_handle);

	/* file corrupted? ain't implemented? or ... */

	if(player.stream_handle == fennec_invalid_index) goto point_error;

	/* cool to be remembered */

	str_cpy(player.current_file, spath);
	

	/* get format information */


	if(!audio_input_plugin_getformat(player.input_plugin, player.stream_handle, &player.samplerate, &player.bitdepth, &player.channels)) goto point_error;

	/* zero samples a second with zero channels and/or zero bit depth? what a cool sound! */

	if(!player.samplerate || !player.bitdepth || !player.channels) goto point_error;


	/* allocate memory */

	player.prebuffersize = (settings.audio_output.buffer_memory * player.samplerate * player.channels * (player.bitdepth / 8) ) / 1000;
	player.buffersize    = (settings.audio_output.buffer_memory * player.samplerate * player.channels * (player.output_bitdepth/ 8) ) / 1000;

	if(!player.buffersize || !player.prebuffersize) goto point_error;

	player.prebuffer = (char*) sys_mem_alloc(player.prebuffersize);
	player.buffer    = (char*) sys_mem_alloc(player.buffersize);
	
	/* now we've done with decoder stuff */

	perror_on_decoder = 0;

	/* start working with audio output system */

	
	{
		unsigned int devi = v_sys_media_driver_default;

		if(settings.audio_output.output_device_id != -1 && settings.audio_output.output_device_id != 0)
			devi = settings.audio_output.output_device_id - 1; /* cuz the default device replaces 0 */

		player.audio_handle = sys_media_stream_init(devi, player.samplerate, player.channels, player.output_bitdepth);
	
		if(player.audio_handle == v_error_sys_media_stream_init) goto point_error;
	
	}

	/* reset equalizer history */

	equalizer_reset();

	/* the state (remember, the message) */

	player.state           = v_audio_playerstate_loaded;
	player.loaded          = 1;
	player.written_samples = 0;
	player.bufferpos       = 0;
	player.stopping        = 0;

	{
		unsigned long  rlen = player.prebuffersize;

		local_readdata(player.input_plugin, player.stream_handle, &rlen, player.prebuffer, 1, &player);
		local_downsample(player.buffer, player.prebuffer, rlen);
	}

	sys_thread_share_release(&internal_output_share);

	return 1;


	/* - - - - - - - - - - - - - - - */

point_error:

	if(!perror_on_decoder)
		MessageBox(0, text(oooo_e_files_invalid_format), text(oooo_error), MB_ICONEXCLAMATION);

	sys_thread_share_release(&internal_output_share);
	return 0;
}
예제 #25
0
파일: radio.c 프로젝트: Cortexelus/rockbox
void radio_screen(void)
{
    bool done = false;
    int button;
    bool stereo = false, last_stereo = false;
    int update_type = 0;
    bool screen_freeze = false;
    bool keep_playing = false;
    bool talk = false;
#ifdef FM_RECORD_DBLPRE
    int lastbutton = BUTTON_NONE;
    unsigned long rec_lastclick = 0;
#endif
#if CONFIG_CODEC != SWCODEC
    int timeout = current_tick + HZ/10;
#if !defined(SIMULATOR)
    unsigned int last_seconds = 0;
    unsigned int seconds = 0;
    struct audio_recording_options rec_options;
#endif /* SIMULATOR */
#endif /* CONFIG_CODEC != SWCODEC */
#ifndef HAVE_NOISY_IDLE_MODE
    int button_timeout = current_tick + (2*HZ);
#endif

    /* change status to "in screen" */
    push_current_activity(ACTIVITY_FM);
    in_screen = true;

    if(radio_preset_count() <= 0)
    {
        radio_load_presets(global_settings.fmr_file);
    }
    skin_get_global_state()->id3 = NULL;
#ifdef HAVE_ALBUMART
    radioart_init(true);
#endif    

    if(radio_status == FMRADIO_OFF)
        audio_stop();

    fms_fix_displays(FMS_ENTER);

#ifndef SIMULATOR

#if CONFIG_CODEC != SWCODEC
    rec_create_directory();
    audio_init_recording();

    sound_settings_apply();
    /* Yes, we use the D/A for monitoring */
    peak_meter_playback(true);

    peak_meter_enable(true);

    rec_init_recording_options(&rec_options);
    rec_options.rec_source = AUDIO_SRC_LINEIN;
    rec_set_recording_options(&rec_options);

    audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
            sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);

#endif /* CONFIG_CODEC != SWCODEC */
#endif /* ndef SIMULATOR */
    /* turn on radio */
#if CONFIG_CODEC == SWCODEC
    /* This should be done before touching audio settings */
    while (!pcm_is_initialized())
       sleep(0);

    audio_set_input_source(AUDIO_SRC_FMRADIO,
                           (radio_status == FMRADIO_PAUSED) ?
                               SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
#else
    if (radio_status == FMRADIO_OFF)
        radio_start();
#endif

    if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN)))
        presets_scan(NULL);

    preset_set_current(preset_find(curr_freq));
    if(radio_current_preset() != -1)
         radio_mode = RADIO_PRESET_MODE;

    /* Load/update the skin at last, when fully initialzed, so that it can
     * display the right content from the beginning */
    FOR_NB_SCREENS(i)
        skin_update(FM_SCREEN, i, SKIN_REFRESH_ALL);

#ifndef HAVE_NOISY_IDLE_MODE
    cpu_idle_mode(true);
#endif

    while(!done)
    {
        if(search_dir != 0)
        {
            curr_freq = step_freq(curr_freq, search_dir);
            update_type = SKIN_REFRESH_ALL;

            if(tuner_set(RADIO_SCAN_FREQUENCY, curr_freq))
            {
                preset_set_current(preset_find(curr_freq));
                remember_frequency();
                end_search();
                talk = true;
            }
            trigger_cpu_boost();
        }

        if (!update_type)
        {
            cancel_cpu_boost();
        }

        button = fms_do_button_loop(update_type>0);

#ifndef HAVE_NOISY_IDLE_MODE
        if (button != ACTION_NONE)
        {
            cpu_idle_mode(false);
            button_timeout = current_tick + (2*HZ);
        }
#endif
        switch(button)
        {
             case ACTION_FM_STOP:
#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
                if(audio_status() == AUDIO_STATUS_RECORD)
                {
                    audio_stop();
                }
                else
#endif
                {
                    done = true;
                    if(presets_have_changed())
                    {
                        if(yesno_pop(ID2P(LANG_SAVE_CHANGES)))
                        {
                            presets_save();
                        }
                    }
                }
                update_type = SKIN_REFRESH_NON_STATIC;
                break;

#ifdef FM_RECORD
            case ACTION_FM_RECORD:
#ifdef FM_RECORD_DBLPRE
                if (lastbutton != ACTION_FM_RECORD_DBLPRE)
                {
                    rec_lastclick = 0;
                    break;
                }
                if (current_tick - rec_lastclick > HZ/2)
                {
                    rec_lastclick = current_tick;
                    break;
                }
#endif /* FM_RECORD_DBLPRE */
#ifndef SIMULATOR
                if(audio_status() == AUDIO_STATUS_RECORD)
                {
                    rec_command(RECORDING_CMD_START_NEWFILE);
                    update_type = SKIN_REFRESH_ALL;
                }
                else
                {
                    rec_command(RECORDING_CMD_START);
                    update_type = SKIN_REFRESH_ALL;
                }
#if CONFIG_CODEC != SWCODEC
                last_seconds = 0;
#endif
#endif /* SIMULATOR */
                break;
#endif /* #ifdef FM_RECORD */

            case ACTION_FM_EXIT:
#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
                if(audio_status() == AUDIO_STATUS_RECORD)
                    audio_stop();
#endif
                keep_playing = true;
                done = true;
                if(presets_have_changed())
                {
                    if(yesno_pop(ID2P(LANG_SAVE_CHANGES)))
                    {
                        presets_save();
                    }
                }

                break;

            case ACTION_STD_PREV:
            case ACTION_STD_NEXT:
                next_station(button == ACTION_STD_PREV ? -1 : 1);
                end_search();
                update_type = SKIN_REFRESH_ALL;
                talk = true;
                break;

            case ACTION_STD_PREVREPEAT:
            case ACTION_STD_NEXTREPEAT:
            {
                int dir = search_dir;
                search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1;
                if (radio_mode != RADIO_SCAN_MODE)
                {
                    preset_next(search_dir);
                    end_search();
                    talk = true;
                }
                else if (dir == 0)
                {
                    /* Starting auto scan */
                    tuner_set(RADIO_MUTE, 1);
                }
                update_type = SKIN_REFRESH_ALL;
                break;
            }

            case ACTION_SETTINGS_INC:
            case ACTION_SETTINGS_INCREPEAT:
                global_settings.volume++;
                setvol();
                update_type = SKIN_REFRESH_NON_STATIC;
                break;

            case ACTION_SETTINGS_DEC:
            case ACTION_SETTINGS_DECREPEAT:
                global_settings.volume--;
                setvol();
                update_type = SKIN_REFRESH_NON_STATIC;
                break;

            case ACTION_FM_PLAY:
                if (radio_status == FMRADIO_PLAYING)
                    radio_pause();
                else
                    radio_start();

                update_type = SKIN_REFRESH_NON_STATIC;
                talk = false;
                talk_shutup();
                break;

            case ACTION_FM_MENU:
                fms_fix_displays(FMS_EXIT);
                do_menu(&radio_settings_menu, NULL, NULL, false);
                preset_set_current(preset_find(curr_freq));
                fms_fix_displays(FMS_ENTER);
                update_type = SKIN_REFRESH_ALL;
                break;

#ifdef FM_PRESET
            case ACTION_FM_PRESET:
                if(radio_preset_count() < 1)
                {
                    splash(HZ, ID2P(LANG_FM_NO_PRESETS));
                    update_type = SKIN_REFRESH_ALL;
                    break;
                }
                fms_fix_displays(FMS_EXIT);
                handle_radio_presets();
                fms_fix_displays(FMS_ENTER);
                update_type = SKIN_REFRESH_ALL;
                break;
#endif /* FM_PRESET */

#ifdef FM_FREEZE
            case ACTION_FM_FREEZE:
                if(!screen_freeze)
                {
                    splash(HZ, str(LANG_FM_FREEZE));
                    screen_freeze = true;
                }
                else
                {
                    update_type = SKIN_REFRESH_ALL;
                    screen_freeze = false;
                }
                break;
#endif /* FM_FREEZE */

            case SYS_USB_CONNECTED:
#if CONFIG_CODEC != SWCODEC
                /* Only accept USB connection when not recording */
                if(audio_status() != AUDIO_STATUS_RECORD)
#endif
                {
                    default_event_handler(SYS_USB_CONNECTED);
                    screen_freeze = true; /* Cosmetic: makes sure the
                                             radio screen doesn't redraw */
                    done = true;
                }
                break;

#ifdef FM_MODE
           case ACTION_FM_MODE:
                if(radio_mode == RADIO_SCAN_MODE)
                {
                    /* Force scan mode if there are no presets. */
                    if(radio_preset_count() > 0)
                        radio_mode = RADIO_PRESET_MODE;
                }
                else
                    radio_mode = RADIO_SCAN_MODE;
                update_type = SKIN_REFRESH_ALL;
                cond_talk_ids_fq(radio_mode ?
                                 LANG_PRESET : LANG_RADIO_SCAN_MODE);
                talk = true;
                break;
#endif /* FM_MODE */

#ifdef FM_NEXT_PRESET
            case ACTION_FM_NEXT_PRESET:
                preset_next(1);
                end_search();
                update_type = SKIN_REFRESH_ALL;
                talk = true;
                break;
#endif

#ifdef FM_PREV_PRESET
            case ACTION_FM_PREV_PRESET:
                preset_next(-1);
                end_search();
                update_type = SKIN_REFRESH_ALL;
                talk = true;
                break;
#endif
            case ACTION_NONE:
                update_type = SKIN_REFRESH_NON_STATIC;
                break;
             /* this case is used by the softlock feature
              * it requests a full update here */
            case ACTION_REDRAW:
                skin_request_full_update(FM_SCREEN);
                break;

            default:
                default_event_handler(button);
#ifdef HAVE_RDS_CAP
                if (tuner_get(RADIO_EVENT))
                    update_type = SKIN_REFRESH_ALL;
#endif
                if (!tuner_get(RADIO_PRESENT))
                {
#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
                    if(audio_status() == AUDIO_STATUS_RECORD)
                        audio_stop();
#endif
                    keep_playing = false;
                    done = true;
                    if(presets_have_changed())
                    {
                        if(yesno_pop(ID2P(LANG_SAVE_CHANGES)))
                        {
                            radio_save_presets();
                        }
                    }

                    /* Clear the preset list on exit. */
                    preset_list_clear();
                }
                break;
        } /*switch(button)*/

#ifdef FM_RECORD_DBLPRE
        if (button != ACTION_NONE)
            lastbutton = button;
#endif

#if CONFIG_CODEC != SWCODEC
        peak_meter_peek();
#endif

        if(!screen_freeze)
        {
            /* Only display the peak meter when not recording */
#if CONFIG_CODEC != SWCODEC
            if(TIME_AFTER(current_tick, timeout))
            {
                timeout = current_tick + HZ;
#else  /* SWCODEC */
            {
#endif /* CONFIG_CODEC == SWCODEC */

                /* keep "mono" from always being displayed when paused */
                if (radio_status != FMRADIO_PAUSED)
                {
                    stereo = tuner_get(RADIO_STEREO) &&
                        !global_settings.fm_force_mono;

                    if(stereo != last_stereo)
                    {
                        update_type = SKIN_REFRESH_ALL;
                        last_stereo = stereo;
                    }
                }
            }

#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
            seconds = audio_recorded_time() / HZ;
            if (update_type || seconds > last_seconds)
            {
                last_seconds = seconds;
#else
            if (update_type)
            {
#endif
                FOR_NB_SCREENS(i)
                    skin_update(FM_SCREEN, i, update_type);
                if (update_type == (int)SKIN_REFRESH_ALL)
                    skin_request_full_update(CUSTOM_STATUSBAR);
            }
        }
        update_type = 0;

        if (global_settings.talk_file && talk
            && radio_status == FMRADIO_PAUSED)
        {
            talk = false;
            bool enqueue = false;
            if (radio_mode == RADIO_SCAN_MODE)
            {
                talk_value_decimal(curr_freq, UNIT_INT, 6, enqueue);
                enqueue = true;
            }
            if (radio_current_preset() >= 0)
                preset_talk(radio_current_preset(), radio_mode == RADIO_PRESET_MODE,
                            enqueue);
        }

#if CONFIG_CODEC != SWCODEC
        if(audio_status() & AUDIO_STATUS_ERROR)
        {
            done = true;
        }
#endif

#ifndef HAVE_NOISY_IDLE_MODE
        if (TIME_AFTER(current_tick, button_timeout))
        {
            cpu_idle_mode(true);
        }
#endif
    } /*while(!done)*/

#ifndef SIMULATOR
#if CONFIG_CODEC != SWCODEC
    if(audio_status() & AUDIO_STATUS_ERROR)
    {
        splash(0, str(LANG_DISK_FULL));
        audio_error_clear();

        while(1)
        {
            button = get_action(CONTEXT_FM|ALLOW_SOFTLOCK, TIMEOUT_BLOCK);
            if(button == ACTION_FM_STOP)
                break;
        }
    }

    audio_init_playback();
#endif /* CONFIG_CODEC != SWCODEC */

    sound_settings_apply();
#endif /* SIMULATOR */

    if(keep_playing)
    {
/* Catch FMRADIO_PLAYING status for the sim. */
#ifndef SIMULATOR
#if CONFIG_CODEC != SWCODEC
        /* Enable the Left and right A/D Converter */
        audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
                                 sound_default(SOUND_RIGHT_GAIN),
                                 AUDIO_GAIN_LINEIN);
        mas_codec_writereg(6, 0x4000);
#endif
        end_search();
#endif /* SIMULATOR */
    }
    else
    {
#if CONFIG_CODEC == SWCODEC
        audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
#else
        radio_stop();
#endif
    }

#ifndef HAVE_NOISY_IDLE_MODE
    cpu_idle_mode(false);
#endif
    fms_fix_displays(FMS_EXIT);
    pop_current_activity();
    in_screen = false;
} /* radio_screen */

void toggle_mono_mode(bool mono)
{
    tuner_set(RADIO_FORCE_MONO, mono);
}

void set_radio_region(int region)
{
#ifdef HAVE_RADIO_REGION
    tuner_set(RADIO_REGION, region);
#endif
    next_station(0);
    remember_frequency();
    (void)region;
}
예제 #26
0
static bool clean_shutdown(void (*callback)(void *), void *parameter)
{
#ifdef SIMULATOR
    (void)callback;
    (void)parameter;
    bookmark_autobookmark();
    call_storage_idle_notifys(true);
    exit(0);
#else
    long msg_id = -1;
    int i;

    scrobbler_poweroff();

#if CONFIG_CHARGING && !defined(HAVE_POWEROFF_WHILE_CHARGING)
    if(!charger_inserted())
#endif
    {
        bool batt_safe = battery_level_safe();
        int audio_stat = audio_status();

        FOR_NB_SCREENS(i)
        {
            screens[i].clear_display();
            screens[i].update();
        }

        if (batt_safe)
        {
#ifdef HAVE_TAGCACHE
            if (!tagcache_prepare_shutdown())
            {
                cancel_shutdown();
                splash(HZ, ID2P(LANG_TAGCACHE_BUSY));
                return false;
            }
#endif
            if (battery_level() > 10)
                splash(0, str(LANG_SHUTTINGDOWN));
            else
            {
                msg_id = LANG_WARNING_BATTERY_LOW;
                splashf(0, "%s %s", str(LANG_WARNING_BATTERY_LOW),
                                    str(LANG_SHUTTINGDOWN));
            }
        }
        else
        {
            msg_id = LANG_WARNING_BATTERY_EMPTY;
            splashf(0, "%s %s", str(LANG_WARNING_BATTERY_EMPTY),
                                str(LANG_SHUTTINGDOWN));
        }

        if (global_settings.fade_on_stop
            && (audio_stat & AUDIO_STATUS_PLAY))
        {
            fade(false, false);
        }

        if (batt_safe) /* do not save on critical battery */
        {
#if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
            if (audio_stat & AUDIO_STATUS_RECORD)
            {
                rec_command(RECORDING_CMD_STOP);
                /* wait for stop to complete */
                while (audio_status() & AUDIO_STATUS_RECORD)
                    sleep(1);
            }
#endif
            bookmark_autobookmark();

            /* audio_stop_recording == audio_stop for HWCODEC */
            audio_stop();

            if (callback != NULL)
                callback(parameter);

#if CONFIG_CODEC != SWCODEC
            /* wait for audio_stop or audio_stop_recording to complete */
            while (audio_status())
                sleep(1);
#endif

#if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
            audio_close_recording();
#endif

            if(global_settings.talk_menu)
            {
                bool enqueue = false;
                if(msg_id != -1)
                {
                    talk_id(msg_id, enqueue);
                    enqueue = true;
                }
                talk_id(LANG_SHUTTINGDOWN, enqueue);
#if CONFIG_CODEC == SWCODEC
                voice_wait();
#endif
            }

            system_flush();
#ifdef HAVE_EEPROM_SETTINGS
            if (firmware_settings.initialized)
            {
                firmware_settings.disk_clean = true;
                firmware_settings.bl_version = 0;
                eeprom_settings_store();
            }
#endif
        }
#ifdef HAVE_DIRCACHE
        else
            dircache_disable();
#endif

        shutdown_hw();
    }
예제 #27
0
/*
 * Callback for 'strm' command.
 */
static int strm_callback(slimproto_t *proto, const unsigned char *buf, int buf_len, void *user_data) {
    slimproto_msg_t msg;
    float replay_gain;
    slimaudio_t *audio = (slimaudio_t *) user_data;
    slimproto_parse_command(buf, buf_len, &msg);

    DEBUGF("strm cmd %c strm.replay_gain:%u ", msg.strm.command, msg.strm.replay_gain);

    switch (msg.strm.command) {
    case 's': /* start */
        replay_gain = (float) (msg.strm.replay_gain) / 65536.0;
        audio->start_replay_gain = replay_gain == 0.0 ? 1.0 : replay_gain;

        if (audio->replay_gain == -1.0)
            audio->replay_gain = audio->start_replay_gain;

        DEBUGF("start_replay_gain:%f\n", audio->start_replay_gain);

        slimaudio_stat(audio, "STMc", (u32_t) 0); /* connect, acknowledge strm-s */

        slimaudio_http_connect(audio, &msg);
        slimaudio_decoder_connect(audio, &msg);
        slimaudio_output_connect(audio, &msg);
        break;

    case 'p': /* pause */
        DEBUGF("\n");
        slimaudio_output_pause(audio);

        /* Only send STMp if interval is zero */
        if (! msg.strm.replay_gain)
            slimaudio_stat(audio, "STMp", (u32_t) 0); /* pause */
        break;

    case 'u': /* unpause */
        DEBUGF("\n");
        slimaudio_output_unpause(audio);
        slimaudio_stat(audio, "STMr", (u32_t) 0); /* resume */
        break;

    case 'q': /* stop */
        DEBUGF("\n");
        audio_stop(audio);
        slimaudio_stat(audio, "STMf", (u32_t) 0); /* acknowledge stop cmd */
        break;

    case 'f': /* flush */
        DEBUGF("\n");
        slimaudio_buffer_flush(audio->decoder_buffer);
        slimaudio_buffer_flush(audio->output_buffer);
        slimaudio_stat(audio, "STMf", (u32_t) 0); /* acknowledge flush cmd */
        break;

    case 'a': /* skip ahead */
        DEBUGF("\n");
        break;

    case 't': /* status */
        DEBUGF("\n");
        slimaudio_stat(audio, "STMt", msg.strm.replay_gain);
        break;
    }

    DEBUGF("DONE strm cmd %c\n", msg.strm.command);
    return 0;
}
예제 #28
0
//播放某个WAV文件
//fname:wav文件路径.
//返回值:
//KEY0_PRES:下一曲
//KEY1_PRES:上一曲
//其他:错误
u8 wav_play_song(u8* fname)
{
	u8 key;
	u8 t=0; 
	u8 res;  
	u32 fillnum; 
	audiodev.file=(FIL*)mymalloc(SRAMIN,sizeof(FIL));
	audiodev.i2sbuf1=mymalloc(SRAMIN,WAV_I2S_TX_DMA_BUFSIZE);
	audiodev.i2sbuf2=mymalloc(SRAMIN,WAV_I2S_TX_DMA_BUFSIZE);
	audiodev.tbuf=mymalloc(SRAMIN,WAV_I2S_TX_DMA_BUFSIZE);
	if(audiodev.file&&audiodev.i2sbuf1&&audiodev.i2sbuf2&&audiodev.tbuf)
	{ 
		res=wav_decode_init(fname,&wavctrl);//得到文件的信息
		if(res==0)//解析文件成功
		{
			if(wavctrl.bps==16)
			{
				WM8978_I2S_Cfg(2,0);	//飞利浦标准,16位数据长度
				I2S2_Init(0,2,0,0);		//飞利浦标准,主机发送,时钟低电平有效,16位帧长度
			}else if(wavctrl.bps==24)
			{
				WM8978_I2S_Cfg(2,2);	//飞利浦标准,24位数据长度
				I2S2_Init(0,2,0,2);		//飞利浦标准,主机发送,时钟低电平有效,24位扩展帧长度
			}
			I2S2_SampleRate_Set(wavctrl.samplerate);//设置采样率
			I2S2_TX_DMA_Init(audiodev.i2sbuf1,audiodev.i2sbuf2,WAV_I2S_TX_DMA_BUFSIZE/2); //配置TX DMA
			i2s_tx_callback=wav_i2s_dma_tx_callback;			//回调函数指wav_i2s_dma_callback
			audio_stop();
			res=f_open(audiodev.file,(TCHAR*)fname,FA_READ);	//打开文件
			if(res==0)
			{
				f_lseek(audiodev.file, wavctrl.datastart);		//跳过文件头
				fillnum=wav_buffill(audiodev.i2sbuf1,WAV_I2S_TX_DMA_BUFSIZE,wavctrl.bps);
				fillnum=wav_buffill(audiodev.i2sbuf2,WAV_I2S_TX_DMA_BUFSIZE,wavctrl.bps);
				audio_start();  
				while(res==0)
				{ 
					while(wavtransferend==0);//等待wav传输完成; 
					wavtransferend=0;
					if(fillnum!=WAV_I2S_TX_DMA_BUFSIZE)//播放结束?
					{
						res=KEY0_PRES;
						break;
					} 
 					if(wavwitchbuf)fillnum=wav_buffill(audiodev.i2sbuf2,WAV_I2S_TX_DMA_BUFSIZE,wavctrl.bps);//填充buf2
					else fillnum=wav_buffill(audiodev.i2sbuf1,WAV_I2S_TX_DMA_BUFSIZE,wavctrl.bps);//填充buf1
					while(1)
					{
						key=KEY_Scan(0); 
						if(key==WKUP_PRES)//暂停
						{
							if(audiodev.status&0X01)audiodev.status&=~(1<<0);
							else audiodev.status|=0X01;  
						}
						if(key==KEY2_PRES||key==KEY0_PRES)//下一曲/上一曲
						{
							res=key;
							break; 
						}
						wav_get_curtime(audiodev.file,&wavctrl);//得到总时间和当前播放的时间 
						audio_msg_show(wavctrl.totsec,wavctrl.cursec,wavctrl.bitrate);
						t++;
						if(t==20)
						{
							t=0;
 							LED0=!LED0;
						}
						if((audiodev.status&0X01)==0)delay_ms(10);
						else break;
					}
				}
				audio_stop(); 
			}else res=0XFF; 
		}else res=0XFF;
	}else res=0XFF; 
	myfree(SRAMIN,audiodev.tbuf);	//释放内存
	myfree(SRAMIN,audiodev.i2sbuf1);//释放内存
	myfree(SRAMIN,audiodev.i2sbuf2);//释放内存 
	myfree(SRAMIN,audiodev.file);	//释放内存 
	return res;
} 
예제 #29
0
static void quit ()
{
    audio_stop();
    paddle_close();
    exit (0);
}
예제 #30
0
/* Get the touched action.
 * egde_offset is a percentage value for the position of the touch
 * inside the bar for regions which arnt WPS_TOUCHREGION_ACTION type.
 */
int skin_get_touchaction(struct wps_data *data, int* edge_offset,
                         struct touchregion **retregion)
{
    int returncode = ACTION_NONE;
    short x,y;
    short vx, vy;
    int type = action_get_touchscreen_press(&x, &y);
    struct skin_viewport *wvp;
    struct touchregion *r, *temp = NULL;
    char* skin_buffer = get_skin_buffer(data);
    bool repeated = (type == BUTTON_REPEAT);
    bool released = (type == BUTTON_REL);
    bool pressed = (type == BUTTON_TOUCHSCREEN);
    struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
    bool needs_repeat;

    while (regions)
    {
        struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
        r = SKINOFFSETTOPTR(skin_buffer, token->value.data);
        wvp = SKINOFFSETTOPTR(skin_buffer, r->wvp);
        /* make sure this region's viewport is visible */
        if (wvp->hidden_flags&VP_DRAW_HIDDEN)
        {
            regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
            continue;
        }
        if (data->touchscreen_locked && 
            (r->action != ACTION_TOUCH_SOFTLOCK && !r->allow_while_locked))
        {
            regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
            continue;
        }
        needs_repeat = r->press_length != PRESS;
        /* check if it's inside this viewport */
        if (viewport_point_within_vp(&(wvp->vp), x, y))
        {   /* reposition the touch inside the viewport since touchregions
             * are relative to a preceding viewport */
            vx = x - wvp->vp.x;
            vy = y - wvp->vp.y;
            /* now see if the point is inside this region */
            if (vx >= r->x && vx < r->x+r->width &&
                vy >= r->y && vy < r->y+r->height)
            {
                /* reposition the touch within the area */
                vx -= r->x;
                vy -= r->y;

                switch(r->action)
                {
                    case ACTION_TOUCH_SCROLLBAR:
                    case ACTION_TOUCH_VOLUME:
                    case ACTION_TOUCH_SETTING:
                        if (edge_offset)
                        {
                            struct progressbar *bar =
                                    SKINOFFSETTOPTR(skin_buffer, r->bar);
                            if(r->width > r->height)
                                *edge_offset = vx*100/r->width;
                            else
                                *edge_offset = vy*100/r->height;
                            if (r->reverse_bar || (bar && bar->invert_fill_direction))
                                *edge_offset = 100 - *edge_offset;
                        }
                        temp = r;
                        returncode = r->action;
                        r->last_press = current_tick;
                        break;
                    default:
                        if (r->armed && ((repeated && needs_repeat) || 
                            (released && !needs_repeat)))
                        {
                            returncode = r->action;
                            temp = r;
                        }
                        if (pressed)
                        {
                            r->armed = true;
                            r->last_press = current_tick;
                        }
                        break;
                }
            }
        }
        regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
    }

    /* On release, all regions are disarmed. */
    if (released)
        skin_disarm_touchregions(data);
    if (retregion && temp)
        *retregion = temp;
    if (temp && temp->press_length == LONG_PRESS)
        temp->armed = false;
    
    if (returncode != ACTION_NONE)
    {
        if (global_settings.party_mode)
        {
            switch (returncode)
            {
                case ACTION_WPS_PLAY:
                case ACTION_WPS_SKIPPREV:
                case ACTION_WPS_SKIPNEXT:
                case ACTION_WPS_STOP:
                    returncode = ACTION_NONE;
                    break;
                default:
                    break;
            }
        }
        switch (returncode)
        {
            case ACTION_TOUCH_SOFTLOCK:
                data->touchscreen_locked = !data->touchscreen_locked;
                returncode = ACTION_NONE;
                break;
            case ACTION_WPS_PLAY:
                if (!audio_status())
                {
                    if ( global_status.resume_index != -1 )
                    {
                        if (playlist_resume() != -1)
                        {
                            playlist_start(global_status.resume_index,
                                global_status.resume_offset);
                        }
                    }
                    else
                    {
                        splash(HZ*2, ID2P(LANG_NOTHING_TO_RESUME));
                    }
                }
                else
                {
                    wps_do_playpause(false);
                }
                returncode = ACTION_REDRAW;
                break;
            case ACTION_WPS_SKIPPREV:
                audio_prev();
                returncode = ACTION_REDRAW;
                break;
            case ACTION_WPS_SKIPNEXT:
                audio_next();
                returncode = ACTION_REDRAW;
                break;
            case ACTION_WPS_STOP:
                audio_stop();
                returncode = ACTION_REDRAW;
                break;
            case ACTION_SETTINGS_INC:
            case ACTION_SETTINGS_DEC:
            {
                const struct settings_list *setting = 
                                            temp->setting_data.setting;
                option_select_next_val(setting, 
                                       returncode == ACTION_SETTINGS_DEC,
                                       true);
                returncode = ACTION_REDRAW;
            }
            break;
            case ACTION_SETTINGS_SET:
            {
                struct touchsetting *data = &temp->setting_data;
                const struct settings_list *s = data->setting;
                void (*f)(int) = NULL;
                switch (s->flags&F_T_MASK)
                {
                    case F_T_CUSTOM:
                        s->custom_setting
                            ->load_from_cfg(s->setting, SKINOFFSETTOPTR(skin_buffer, data->value.text));
                        break;                          
                    case F_T_INT:
                    case F_T_UINT:
                        *(int*)s->setting = data->value.number;
                        if ((s->flags & F_T_SOUND) == F_T_SOUND)
                            sound_set(s->sound_setting->setting, data->value.number);
                        else if (s->flags&F_CHOICE_SETTING)
                            f = s->choice_setting->option_callback;
                        else if (s->flags&F_TABLE_SETTING)
                            f = s->table_setting->option_callback;
                        else
                            f = s->int_setting->option_callback;

                        if (f)
                            f(data->value.number);
                        break;
                    case F_T_BOOL:
                        *(bool*)s->setting = data->value.number ? true : false;
                        if (s->bool_setting->option_callback)
                            s->bool_setting
                                ->option_callback(data->value.number ? true : false);
                        break;
                }
                returncode = ACTION_REDRAW;
            }
            break;
            case ACTION_TOUCH_MUTE:
            {
                const int min_vol = sound_min(SOUND_VOLUME);
                if (global_settings.volume == min_vol)
                    global_settings.volume = temp->value;
                else
                {
                    temp->value = global_settings.volume;
                    global_settings.volume = min_vol;
                }
                setvol();
                returncode = ACTION_REDRAW;
            }
            break;
            case ACTION_TOUCH_SHUFFLE: /* toggle shuffle mode */
            {
                global_settings.playlist_shuffle = 
                                            !global_settings.playlist_shuffle;
                replaygain_update();
                if (global_settings.playlist_shuffle)
                    playlist_randomise(NULL, current_tick, true);
                else
                    playlist_sort(NULL, true);
                returncode = ACTION_REDRAW;
            }
            break;
            case ACTION_TOUCH_REPMODE: /* cycle the repeat mode setting */
            {
                const struct settings_list *rep_setting = 
                                find_setting(&global_settings.repeat_mode, NULL);
                option_select_next_val(rep_setting, false, true);
                audio_flush_and_reload_tracks();
                returncode = ACTION_REDRAW;
            }
            break;
            case ACTION_TOUCH_SETTING:
            {                
                struct progressbar *bar =
                        SKINOFFSETTOPTR(skin_buffer, temp->bar);
                if (bar && edge_offset)
                {                    
                    int val, count;
                    get_setting_info_for_bar(bar->setting_id, &count, &val);
                    val = *edge_offset * count / 100;
                    update_setting_value_from_touch(bar->setting_id, val);
                }
            }
            break;
        }
        return returncode;
    }

    return ACTION_TOUCHSCREEN;
}