Beispiel #1
0
// play a module using portaudio.
void play(DUH *duh) {
	// init portaudio, redirecting stderr output temporarily; a lot of junk
	// gets printed otherwise. this won't work on windows, but who cares?
	int old_stderr = dup(2);
	int new_stderr = open("/dev/null", O_WRONLY);
	dup2(new_stderr, 2);
	PaError err = Pa_Initialize();
	close(new_stderr);
	dup2(old_stderr, 2);
	close(old_stderr);
	if (err != paNoError)
		die("could not init PortAudio: %s\n", Pa_GetErrorText(err));
	atexit(&pa_terminate);

	// get default device info
	PaDeviceIndex index = Pa_GetDefaultOutputDevice();
	if (index == paNoDevice)
		die("could not get default output device\n");
	callback_data cd;
	const PaDeviceInfo *dev = Pa_GetDeviceInfo(index);
	cd.sample_rate = dev->defaultSampleRate;
	cd.delta = 65536.0f / cd.sample_rate;

	// open and start output stream
	PaStream *stream;
	cd.sr = duh_start_sigrenderer(duh, 0, channels, 0);
	err = Pa_OpenDefaultStream(&stream, 0, channels, paInt16,
			dev->defaultSampleRate, paFramesPerBufferUnspecified,
			callback, &cd);
	if (err != paNoError) {
		duh_end_sigrenderer(cd.sr);
		unload_duh(duh);
		die("could not open default stream: %s\n",
				Pa_GetErrorText(err));
	}
	if ((err = Pa_StartStream(stream)) != paNoError) {
		duh_end_sigrenderer(cd.sr);
		unload_duh(duh);
		die("could not start stream: %s\n", Pa_GetErrorText(err));
	}

	init_sigrenderer(cd.sr);

	// play
	while (Pa_IsStreamActive(stream) == 1)
		Pa_Sleep(100);

	// clean up
	Pa_CloseStream(stream);
	duh_end_sigrenderer(cd.sr);
}
Beispiel #2
0
void dumb_source_close(audio_source *src) {
    dumb_source *local = source_get_userdata(src);
    duh_end_sigrenderer(local->renderer);
    unload_duh(local->data);
    free(local);
    DEBUG("Libdumb Source: Closed.");
}
bool DeInit(void* context)
{
  DumbContext* dumb = (DumbContext*)context;
  duh_end_sigrenderer(dumb->sr);
  unload_duh(dumb->module);
  delete dumb;

  return true;
}
Beispiel #4
0
void al_stop_duh(AL_DUH_PLAYER *dp)
{
	if (dp) {
		if (dp->sigrenderer) {
			duh_end_sigrenderer(dp->sigrenderer);
			stop_audio_stream(dp->stream);
		}
		free(dp);
	}
}
Beispiel #5
0
void Tracker_Stop(void)
{
	if(bTracker_Initialized == false || playing == false)
		return;
	if(!trackmod || !sr)
		return;

	playing = false;			// Not playing the song anymore to prevent Tracker_Update
	Con_Printf("Stopping %s\n", name);	// Just print that we are stopping whatever track
	duh_end_sigrenderer(sr);		// Stop the renderer safely
	unload_duh(trackmod);			// Unload the song!
}
Beispiel #6
0
// -----------------------------------------------------------------------------
// Closes and unloads any currently open mod
// -----------------------------------------------------------------------------
void ModMusic::close()
{
	if (dumb_player_ != nullptr)
	{
		duh_end_sigrenderer(dumb_player_);
		dumb_player_ = nullptr;
	}
	if (dumb_module_ != nullptr)
	{
		unload_duh(dumb_module_);
		dumb_module_ = nullptr;
	}
}
Beispiel #7
0
 void seek(int patnum)
 {
   if ((!done) && (duhPlayer)) {
     al_stop_duh(duhPlayer);
     done = 0;
     DUH_SIGRENDERER *sr = dumb_it_start_at_order(tune, 2, patnum);
     duhPlayer = al_duh_encapsulate_sigrenderer(sr, VOLUME_TO_DUMB_VOL(vol), 8192, 22050);
     if (!duhPlayer)
       duh_end_sigrenderer(sr);
     else
       al_duh_set_loop(duhPlayer, repeat);
   }
 }
Beispiel #8
0
/* ModMusic::close
 * Closes and unloads any currently open mod
 *******************************************************************/
void ModMusic::close()
{
    if (dumb_player != NULL)
    {
        duh_end_sigrenderer(dumb_player);
        dumb_player = NULL;
    }
    if (dumb_module != NULL)
    {
        unload_duh(dumb_module);
        dumb_module = NULL;
    }
}
/* Destroy the specified player. */
void dumba5_destroy_player(DUMBA5_PLAYER * pp)
{
	if(pp)
	{
		al_destroy_thread(pp->thread);
		al_destroy_mutex(pp->mutex);
		if(pp->sigrenderer)
		{
			duh_end_sigrenderer(pp->sigrenderer);
//			al_drain_stream(dp->stream);
			al_destroy_audio_stream(pp->stream);
		}
		free(pp);
	}
}
Beispiel #10
0
static void
cdumb_free (DB_fileinfo_t *_info) {
    trace ("cdumb_free %p\n", _info);
    dumb_info_t *info = (dumb_info_t *)_info;
    if (info) {
        if (info->renderer) {
            duh_end_sigrenderer (info->renderer);
            info->renderer = NULL;
        }
        if (info->duh) {
            unload_duh (info->duh);
            info->duh = NULL;
        }
        free (info);
    }
}
bool MODDecoder::Close(CFErrorRef */*error*/)
{
	if(!IsOpen()) {
		log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger("org.sbooth.AudioEngine.AudioDecoder.MOD");
		LOG4CXX_WARN(logger, "Close() called on an AudioDecoder that hasn't been opened");
		return true;
	}

	if(dsr)
		duh_end_sigrenderer(dsr), dsr = NULL;
	if(duh)
		unload_duh(duh), duh = NULL;
	if(df)
		dumbfile_close(df), df = NULL;

	mIsOpen = false;
	return true;
}
Beispiel #12
0
static int
cdumb_startrenderer (DB_fileinfo_t *_info) {
    dumb_info_t *info = (dumb_info_t *)_info;
    // reopen
    if (info->renderer) {
        duh_end_sigrenderer (info->renderer);
        info->renderer = NULL;
    }
    info->renderer = duh_start_sigrenderer (info->duh, 0, 2, 0);
    if (!info->renderer) {
        return -1;
    }

    DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer (info->renderer);
    dumb_it_set_loop_callback (itsr, &dumb_it_callback_terminate, NULL);

    int q = conf_resampling_quality;
    if (q < 0) {
        q = 0;
    }
    else if (q >= DUMB_RQ_N_LEVELS) {
        q = DUMB_RQ_N_LEVELS - 1;
    }

    dumb_it_set_resampling_quality (itsr, q);
    dumb_it_set_xm_speed_zero_callback (itsr, &dumb_it_callback_terminate, NULL);
    dumb_it_set_global_volume_zero_callback (itsr, &dumb_it_callback_terminate, NULL);

    int rq = conf_ramping_style;
    if (rq < 0) {
        rq = 0;
    }
    else if (rq > 2) {
        rq = 2;
    }
    dumb_it_set_ramp_style(itsr, rq);

    dumb_it_sr_set_global_volume (itsr, conf_global_volume);
    return 0;
}
Beispiel #13
0
int al_poll_duh(AL_DUH_PLAYER *dp)
{
	unsigned short *sptr;
	long n;
	long size;
	int n_channels;

	if (!dp || !dp->sigrenderer)
		return 1;

	if (!(dp->flags & ADP_PLAYING))
		return 0;

	sptr = get_audio_stream_buffer(dp->stream);

	if (!sptr)
		return 0;

	n = duh_render(dp->sigrenderer, 16, 1, dp->volume, 65536.0 / dp->freq, dp->bufsize, sptr);

	if (n == 0) {
		if (++dp->silentcount >= 2) {
			duh_end_sigrenderer(dp->sigrenderer);
			free_audio_stream_buffer(dp->stream);
			stop_audio_stream(dp->stream);
			dp->sigrenderer = NULL;
			return 1;
		}
	}

	n_channels = duh_sigrenderer_get_n_channels(dp->sigrenderer);
	n *= n_channels;
	size = dp->bufsize * n_channels;
	for (; n < size; n++)
		sptr[n] = 0x8000;

	free_audio_stream_buffer(dp->stream);

	return 0;
}
void dumba5_stop_duh(DUMBA5_PLAYER * dp)
{
	if(dp)
	{
		al_destroy_thread(dp->thread);
		if(dp->sigrenderer)
		{
			duh_end_sigrenderer(dp->sigrenderer);
//			al_drain_stream(dp->stream);
			al_destroy_audio_stream(dp->stream);
		}
		free(dp);
		
		/* if we are using the internal DUH, free it automatically,
		   you are responsible for freeing your own DUHs */
		if(dumba5_duh)
		{
			unload_duh(dumba5_duh);
			dumba5_duh = NULL;
		}
	}
}
Beispiel #15
0
/* DEPRECATED */
void duh_end_renderer(DUH_SIGRENDERER *dr)
{
	duh_end_sigrenderer(dr);
}
void * dumba5_update_thread(ALLEGRO_THREAD * thread, void * arg)
{
	DUMBA5_PLAYER * dp = (DUMBA5_PLAYER *)arg;
	ALLEGRO_EVENT_QUEUE * queue;
	unsigned short *fragment;
	long n;
	long size;
	int n_channels;
	
	queue = al_create_event_queue();
	al_register_event_source(queue, al_get_audio_stream_event_source(dp->stream));
	
	while(1)
	{
		ALLEGRO_EVENT event;

		al_wait_for_event(queue, &event);

		if(event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT)
		{
			fragment = (unsigned short *)al_get_audio_stream_fragment(dp->stream);
			if(!fragment)
			{
				return NULL;
			}
			n = duh_render(dp->sigrenderer, 16, 0, dp->volume, 65536.0 / dp->freq, dp->bufsize, fragment);

			if (n == 0)
			{
				if (++dp->silentcount >= 2)
				{
					duh_end_sigrenderer(dp->sigrenderer);
					if(!al_set_audio_stream_fragment(dp->stream, fragment))
					{
					}
					al_destroy_audio_stream(dp->stream);
					dp->sigrenderer = NULL;
					return NULL;
				}
			}

			n_channels = duh_sigrenderer_get_n_channels(dp->sigrenderer);
			n *= n_channels;
			size = dp->bufsize * n_channels;
			for (; n < size; n++)
			{
				fragment[n] = 0x8000;
			}
			if(!al_set_audio_stream_fragment(dp->stream, fragment))
			{
			}
		}
		if(al_get_thread_should_stop(thread))
		{
			break;
		}
	}
	
	al_destroy_event_queue(queue);

	return NULL;
}
Beispiel #17
0
int main(int argc, char *argv[]) {
    int retcode = 1;
    int nerrors = 0;
    streamer_t streamer;
    memset(&streamer, 0, sizeof(streamer_t));

    // Signal handlers
    signal(SIGINT, sig_fn);
    signal(SIGTERM, sig_fn);

    // Initialize SDL2
    if (SDL_Init(SDL_INIT_AUDIO) != 0) {
        fprintf(stderr, "%s\n", SDL_GetError());
        return 1;
    }

    // Defaults
    streamer.freq = 44100;
    streamer.n_channels = 2;
    streamer.bits = 16;
    streamer.volume = 1.0f;
    streamer.quality = DUMB_RQ_CUBIC;

    // commandline argument parser options
    struct arg_lit *arg_help =
        arg_lit0("h", "help", "print this help and exits");
    struct arg_dbl *arg_volume =
        arg_dbl0("v", "volume", "<volume",
                 "sets the output volume (-8.0 to +8.0, default 1.0)");
    struct arg_int *arg_samplerate = arg_int0(
        "s", "samplerate", "<freq>", "sets the sampling rate (default 44100)");
    struct arg_int *arg_quality = arg_int0(
        "r", "quality", "<quality>", "specify the resampling quality to use");
    struct arg_lit *arg_mono =
        arg_lit0("m", "mono", "generate mono output instead of stereo");
    struct arg_lit *arg_eight =
        arg_lit0("8", "eight", "generate 8-bit instead of 16-bit");
    struct arg_lit *arg_noprogress =
        arg_lit0("n", "noprogress", "hide progress bar");
    struct arg_file *arg_output =
        arg_file0("o", "output", "<file>", "output file");
    struct arg_file *arg_input =
        arg_file1(NULL, NULL, "<file>", "input module file");
    struct arg_end *arg_fend = arg_end(20);
    void *argtable[] = {arg_help,       arg_input,      arg_volume,
                        arg_samplerate, arg_quality,    arg_mono,
                        arg_eight,      arg_noprogress, arg_fend};
    const char *progname = "dumbplay";

    // Make sure everything got allocated
    if (arg_nullcheck(argtable) != 0) {
        fprintf(stderr, "%s: insufficient memory\n", progname);
        goto exit_0;
    }

    // Parse inputs
    nerrors = arg_parse(argc, argv, argtable);

    // Handle help
    if (arg_help->count > 0) {
        fprintf(stderr, "Usage: %s", progname);
        arg_print_syntax(stderr, argtable, "\n");
        fprintf(stderr, "\nArguments:\n");
        arg_print_glossary(stderr, argtable, "%-25s %s\n");
        goto exit_0;
    }

    // Handle libargtable errors
    if (nerrors > 0) {
        arg_print_errors(stderr, arg_fend, progname);
        fprintf(stderr, "Try '%s --help' for more information.\n", progname);
        goto exit_0;
    }

    // Handle the switch options
    streamer.input = arg_input->filename[0];
    if (arg_eight->count > 0) {
        streamer.bits = 8;
    }
    if (arg_mono->count > 0) {
        streamer.n_channels = 1;
    }
    if (arg_noprogress->count > 0) {
        streamer.no_progress = true;
    }

    if (arg_volume->count > 0) {
        streamer.volume = arg_volume->dval[0];
        if (streamer.volume < -8.0f || streamer.volume > 8.0f) {
            fprintf(stderr, "Volume must be between -8.0f and 8.0f.\n");
            goto exit_0;
        }
    }

    if (arg_samplerate->count > 0) {
        streamer.freq = arg_samplerate->ival[0];
        if (streamer.freq < 1 || streamer.freq > 96000) {
            fprintf(stderr, "Sampling rate must be between 1 and 96000.\n");
            goto exit_0;
        }
    }

    if (arg_quality->count > 0) {
        streamer.quality = arg_quality->ival[0];
        if (streamer.quality < 0 || streamer.quality >= DUMB_RQ_N_LEVELS) {
            fprintf(stderr, "Quality must be between %d and %d.\n", 0,
                    DUMB_RQ_N_LEVELS - 1);
            goto exit_0;
        }
    }

    // Load source file.
    dumb_register_stdfiles();
    streamer.src = dumb_load_any(streamer.input, 0, 0);
    if (!streamer.src) {
        fprintf(stderr, "Unable to load file %s for playback!\n",
                streamer.input);
        goto exit_0;
    }

    // Set up playback
    streamer.renderer =
        duh_start_sigrenderer(streamer.src, 0, streamer.n_channels, 0);
    streamer.delta = 65536.0f / streamer.freq;
    streamer.sbytes = (streamer.bits / 8) * streamer.n_channels;
    streamer.ssize = duh_get_length(streamer.src);

    // Stop producing samples on module end
    DUMB_IT_SIGRENDERER *itsr = duh_get_it_sigrenderer(streamer.renderer);
    dumb_it_set_loop_callback(itsr, &dumb_it_callback_terminate, NULL);
    dumb_it_set_xm_speed_zero_callback(itsr, &dumb_it_callback_terminate, NULL);
    dumb_it_set_resampling_quality(itsr, streamer.quality);

    // Set up the SDL2 format we want for playback.
    SDL_AudioSpec want;
    SDL_zero(want);
    want.freq = streamer.freq;
    want.format = (streamer.bits == 16) ? AUDIO_S16 : AUDIO_S8;
    want.channels = streamer.n_channels;
    want.samples = SAMPLES;
    want.callback = stream_audio;
    want.userdata = &streamer;

    // Find SDL2 audio device, and request the format we just set up.
    // SDL2 will tell us what we got in the "have" struct.
    SDL_AudioSpec have;
    streamer.dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
    if (streamer.dev == 0) {
        fprintf(stderr, "%s\n", SDL_GetError());
        goto exit_1;
    }

    // Make sure we got the format we wanted. If not, stop here.
    if (have.format != want.format) {
        fprintf(stderr, "Could not get correct playback format.\n");
        goto exit_2;
    }

    // Play file
    SDL_PauseAudioDevice(streamer.dev, 0);

    // Show initial state of the progress bar (if it is enabled)
    int time_start = SDL_GetTicks();
    float seek = 0.0f;
    int ms_played = 0;
    if (!streamer.no_progress) {
        show_progress(PROGRESSBAR_LENGTH, seek, ms_played);
    }

    // Loop while dumb is still giving data. Update progressbar if enabled.
    while (!stop_signal && !streamer.ended) {
        if (!streamer.no_progress) {
            seek = ((float)streamer.spos) / ((float)streamer.ssize);
            ms_played = SDL_GetTicks() - time_start;
            show_progress(PROGRESSBAR_LENGTH, seek, ms_played);
        }
        SDL_Delay(100);
    }

    // We made it this far without crashing, so let's just exit with no error :)
    retcode = 0;

    // Free up resources and exit.
    if (streamer.sig_samples) {
        destroy_sample_buffer(streamer.sig_samples);
    }

exit_2:
    SDL_CloseAudioDevice(streamer.dev);

exit_1:
    if (streamer.renderer) {
        duh_end_sigrenderer(streamer.renderer);
    }
    if (streamer.src) {
        unload_duh(streamer.src);
    }

exit_0:
    arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
    SDL_Quit();
    return retcode;
}