コード例 #1
0
ファイル: rdpsnd_pulse.c プロジェクト: roman-b/FreeRDP-1.0
static boolean rdpsnd_pulse_connect(rdpsndDevicePlugin* device)
{
	rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
	pa_context_state_t state;

	if (!pulse->context)
		return False;

	if (pa_context_connect(pulse->context, NULL, 0, NULL))
	{
		DEBUG_WARN("pa_context_connect failed (%d)", pa_context_errno(pulse->context));
		return False;
	}
	pa_threaded_mainloop_lock(pulse->mainloop);
	if (pa_threaded_mainloop_start(pulse->mainloop) < 0)
	{
		pa_threaded_mainloop_unlock(pulse->mainloop);
		DEBUG_WARN("pa_threaded_mainloop_start failed (%d)", pa_context_errno(pulse->context));
		return False;
	}
	for (;;)
	{
		state = pa_context_get_state(pulse->context);
		if (state == PA_CONTEXT_READY)
			break;
		if (!PA_CONTEXT_IS_GOOD(state))
		{
			DEBUG_WARN("bad context state (%d)", pa_context_errno(pulse->context));
			break;
		}
		pa_threaded_mainloop_wait(pulse->mainloop);
	}
	pa_threaded_mainloop_unlock(pulse->mainloop);
	if (state == PA_CONTEXT_READY)
	{
		DEBUG_SVC("connected");
		return True;
	}
	else
	{
		pa_context_disconnect(pulse->context);
		return False;
	}
}
コード例 #2
0
ファイル: tsmf_pulse.c プロジェクト: JozLes77/FreeRDP
static BOOL tsmf_pulse_connect(TSMFPulseAudioDevice *pulse)
{
	pa_context_state_t state;
	if(!pulse->context)
		return FALSE;
	if(pa_context_connect(pulse->context, NULL, 0, NULL))
	{
		CLOG_ERR("pa_context_connect failed (%d)",
				   pa_context_errno(pulse->context));
		return FALSE;
	}
	pa_threaded_mainloop_lock(pulse->mainloop);
	if(pa_threaded_mainloop_start(pulse->mainloop) < 0)
	{
		pa_threaded_mainloop_unlock(pulse->mainloop);
		CLOG_ERR("pa_threaded_mainloop_start failed (%d)",
				   pa_context_errno(pulse->context));
		return FALSE;
	}
	for(;;)
	{
		state = pa_context_get_state(pulse->context);
		if(state == PA_CONTEXT_READY)
			break;
		if(!PA_CONTEXT_IS_GOOD(state))
		{
			DEBUG_TSMF("bad context state (%d)",
					   pa_context_errno(pulse->context));
			break;
		}
		pa_threaded_mainloop_wait(pulse->mainloop);
	}
	pa_threaded_mainloop_unlock(pulse->mainloop);
	if(state == PA_CONTEXT_READY)
	{
		DEBUG_TSMF("connected");
		return TRUE;
	}
	else
	{
		pa_context_disconnect(pulse->context);
		return FALSE;
	}
}
コード例 #3
0
ファイル: pulse-input.c プロジェクト: Jhonthe7th/obs-studio
/*
 * Create a new pulse audio main loop and connect to the server
 *
 * Returns a negative value on error
 */
static int pulse_connect(struct pulse_data *data)
{
	data->mainloop = pa_mainloop_new();
	if (!data->mainloop) {
		blog(LOG_ERROR, "pulse-input: Unable to create main loop");
		return -1;
	}

	data->context = pa_context_new_with_proplist(
		pa_mainloop_get_api(data->mainloop), "OBS Studio", data->props);
	if (!data->context) {
		blog(LOG_ERROR, "pulse-input: Unable to create context");
		return -1;
	}

	int status = pa_context_connect(
		data->context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL);
	if (status < 0) {
		blog(LOG_ERROR, "pulse-input: Unable to connect! Status: %d",
		     status);
		return -1;
	}

	// wait until connected
	for (;;) {
		pulse_iterate(data);
		pa_context_state_t state = pa_context_get_state(data->context);
		if (state == PA_CONTEXT_READY) {
			blog(LOG_DEBUG, "pulse-input: Context ready");
			break;
		}
		if (!PA_CONTEXT_IS_GOOD(state)) {
			blog(LOG_ERROR, "pulse-input: Context connect failed");
			return -1;
		}
	}

	return 0;
}
コード例 #4
0
ファイル: context.cpp プロジェクト: KDE/plasma-pa
void Context::contextStateCallback(pa_context *c)
{
    qCDebug(PLASMAPA) << "state callback";
    pa_context_state_t state = pa_context_get_state(c);
    if (state == PA_CONTEXT_READY) {
        qCDebug(PLASMAPA) << "ready";

        // 1. Register for the stream changes (except during probe)
        if (m_context == c) {
            pa_context_set_subscribe_callback(c, subscribe_cb, this);

            if (!PAOperation(pa_context_subscribe(c, (pa_subscription_mask_t)
                                           (PA_SUBSCRIPTION_MASK_SINK|
                                            PA_SUBSCRIPTION_MASK_SOURCE|
                                            PA_SUBSCRIPTION_MASK_CLIENT|
                                            PA_SUBSCRIPTION_MASK_SINK_INPUT|
                                            PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT|
                                            PA_SUBSCRIPTION_MASK_CARD|
                                            PA_SUBSCRIPTION_MASK_SERVER), nullptr, nullptr))) {
                qCWarning(PLASMAPA) << "pa_context_subscribe() failed";
                return;
            }
        }

        if (!PAOperation(pa_context_get_sink_info_list(c, sink_cb, this))) {
            qCWarning(PLASMAPA) << "pa_context_get_sink_info_list() failed";
            return;
        }

        if (!PAOperation(pa_context_get_source_info_list(c, source_cb, this))) {
            qCWarning(PLASMAPA) << "pa_context_get_source_info_list() failed";
            return;
        }

        if (!PAOperation(pa_context_get_client_info_list(c, client_cb, this))) {
            qCWarning(PLASMAPA) << "pa_context_client_info_list() failed";
            return;
        }

        if (!PAOperation(pa_context_get_card_info_list(c, card_cb, this))) {
            qCWarning(PLASMAPA) << "pa_context_get_card_info_list() failed";
            return;
        }

        if (!PAOperation(pa_context_get_sink_input_info_list(c, sink_input_callback, this))) {
            qCWarning(PLASMAPA) << "pa_context_get_sink_input_info_list() failed";
            return;
        }

        if (!PAOperation(pa_context_get_source_output_info_list(c, source_output_cb, this))) {
            qCWarning(PLASMAPA) << "pa_context_get_source_output_info_list() failed";
            return;
        }

        if (!PAOperation(pa_context_get_server_info(c, server_cb, this))) {
            qCWarning(PLASMAPA) << "pa_context_get_server_info() failed";
            return;
        }

        if (PAOperation(pa_ext_stream_restore_read(c, ext_stream_restore_read_cb, this))) {
            pa_ext_stream_restore_set_subscribe_cb(c, ext_stream_restore_subscribe_cb, this);
            PAOperation(pa_ext_stream_restore_subscribe(c, 1, nullptr, this));
        } else {
            qCWarning(PLASMAPA) << "Failed to initialize stream_restore extension";
        }
    } else if (!PA_CONTEXT_IS_GOOD(state)) {
        qCWarning(PLASMAPA) << "context kaput";
        if (m_context) {
            pa_context_unref(m_context);
            m_context = nullptr;
        }
        reset();
        QTimer::singleShot(1000, this, &Context::connectToDaemon);
    }
}
コード例 #5
0
static int
PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
{
    struct SDL_PrivateAudioData *h = NULL;
    Uint16 test_format = 0;
    pa_sample_spec paspec;
    pa_buffer_attr paattr;
    pa_channel_map pacmap;
    pa_stream_flags_t flags = 0;
    int state = 0;

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    h = this->hidden;

    paspec.format = PA_SAMPLE_INVALID;

    /* Try for a closest match on audio format */
    for (test_format = SDL_FirstAudioFormat(this->spec.format);
         (paspec.format == PA_SAMPLE_INVALID) && test_format;) {
#ifdef DEBUG_AUDIO
        fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
#endif
        switch (test_format) {
        case AUDIO_U8:
            paspec.format = PA_SAMPLE_U8;
            break;
        case AUDIO_S16LSB:
            paspec.format = PA_SAMPLE_S16LE;
            break;
        case AUDIO_S16MSB:
            paspec.format = PA_SAMPLE_S16BE;
            break;
        case AUDIO_S32LSB:
            paspec.format = PA_SAMPLE_S32LE;
            break;
        case AUDIO_S32MSB:
            paspec.format = PA_SAMPLE_S32BE;
            break;
        case AUDIO_F32LSB:
            paspec.format = PA_SAMPLE_FLOAT32LE;
            break;
        case AUDIO_F32MSB:
            paspec.format = PA_SAMPLE_FLOAT32BE;
            break;
        default:
            paspec.format = PA_SAMPLE_INVALID;
            break;
        }
        if (paspec.format == PA_SAMPLE_INVALID) {
            test_format = SDL_NextAudioFormat();
        }
    }
    if (paspec.format == PA_SAMPLE_INVALID) {
        PULSEAUDIO_CloseDevice(this);
        return SDL_SetError("Couldn't find any hardware audio formats");
    }
    this->spec.format = test_format;

    /* Calculate the final parameters for this audio specification */
#ifdef PA_STREAM_ADJUST_LATENCY
    this->spec.samples /= 2; /* Mix in smaller chunck to avoid underruns */
#endif
    SDL_CalculateAudioSpec(&this->spec);

    /* Allocate mixing buffer */
    h->mixlen = this->spec.size;
    h->mixbuf = (Uint8 *) SDL_AllocAudioMem(h->mixlen);
    if (h->mixbuf == NULL) {
        PULSEAUDIO_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    SDL_memset(h->mixbuf, this->spec.silence, this->spec.size);

    paspec.channels = this->spec.channels;
    paspec.rate = this->spec.freq;

    /* Reduced prebuffering compared to the defaults. */
#ifdef PA_STREAM_ADJUST_LATENCY
    /* 2x original requested bufsize */
    paattr.tlength = h->mixlen * 4;
    paattr.prebuf = -1;
    paattr.maxlength = -1;
    /* -1 can lead to pa_stream_writable_size() >= mixlen never being true */
    paattr.minreq = h->mixlen;
    flags = PA_STREAM_ADJUST_LATENCY;
#else
    paattr.tlength = h->mixlen*2;
    paattr.prebuf = h->mixlen*2;
    paattr.maxlength = h->mixlen*2;
    paattr.minreq = h->mixlen;
#endif

    /* The SDL ALSA output hints us that we use Windows' channel mapping */
    /* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */
    PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels,
                                        PA_CHANNEL_MAP_WAVEEX);

    /* Set up a new main loop */
    if (!(h->mainloop = PULSEAUDIO_pa_mainloop_new())) {
        PULSEAUDIO_CloseDevice(this);
        return SDL_SetError("pa_mainloop_new() failed");
    }

    h->mainloop_api = PULSEAUDIO_pa_mainloop_get_api(h->mainloop);
    h->context = PULSEAUDIO_pa_context_new(h->mainloop_api, getAppName());
    if (!h->context) {
        PULSEAUDIO_CloseDevice(this);
        return SDL_SetError("pa_context_new() failed");
    }

    /* Connect to the PulseAudio server */
    if (PULSEAUDIO_pa_context_connect(h->context, NULL, 0, NULL) < 0) {
        PULSEAUDIO_CloseDevice(this);
        return SDL_SetError("Could not setup connection to PulseAudio");
    }

    do {
        if (PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
            PULSEAUDIO_CloseDevice(this);
            return SDL_SetError("pa_mainloop_iterate() failed");
        }
        state = PULSEAUDIO_pa_context_get_state(h->context);
        if (!PA_CONTEXT_IS_GOOD(state)) {
            PULSEAUDIO_CloseDevice(this);
            return SDL_SetError("Could not connect to PulseAudio");
        }
    } while (state != PA_CONTEXT_READY);

    h->stream = PULSEAUDIO_pa_stream_new(
        h->context,
        "Simple DirectMedia Layer", /* stream description */
        &paspec,    /* sample format spec */
        &pacmap     /* channel map */
        );

    if (h->stream == NULL) {
        PULSEAUDIO_CloseDevice(this);
        return SDL_SetError("Could not set up PulseAudio stream");
    }

    if (PULSEAUDIO_pa_stream_connect_playback(h->stream, NULL, &paattr, flags,
            NULL, NULL) < 0) {
        PULSEAUDIO_CloseDevice(this);
        return SDL_SetError("Could not connect PulseAudio stream");
    }

    do {
        if (PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
            PULSEAUDIO_CloseDevice(this);
            return SDL_SetError("pa_mainloop_iterate() failed");
        }
        state = PULSEAUDIO_pa_stream_get_state(h->stream);
        if (!PA_STREAM_IS_GOOD(state)) {
            PULSEAUDIO_CloseDevice(this);
            return SDL_SetError("Could not create to PulseAudio stream");
        }
    } while (state != PA_STREAM_READY);

    /* We're ready to rock and roll. :-) */
    return 0;
}
コード例 #6
0
ファイル: hostaudio.cpp プロジェクト: plasma-apps/emumaster
/*! Starts up audio streaming to the host. */
void HostAudio::open()
{
	m_mainloop = pa_threaded_mainloop_new();
	if (!m_mainloop) {
		qDebug("Could not acquire PulseAudio main loop");
		return;
	}
	m_api = pa_threaded_mainloop_get_api(m_mainloop);
	m_context = pa_context_new(m_api, "emumaster");
	pa_context_set_state_callback(m_context, contextStreamCallback, this);

	if (!m_context) {
		qDebug("Could not acquire PulseAudio device context");
		return;
	}
#if defined(MEEGO_EDITION_HARMATTAN)
	if (pa_context_connect(m_context, 0, PA_CONTEXT_NOFLAGS, 0) < 0) {
#elif defined(Q_WS_MAEMO_5)
	if (pa_context_connect(m_context, 0, (pa_context_flags_t)0, 0) < 0) {
#endif
		int error = pa_context_errno(m_context);
		qDebug("Could not connect to PulseAudio server: %s", pa_strerror(error));
		return;
	}
	pa_threaded_mainloop_lock(m_mainloop);
	if (pa_threaded_mainloop_start(m_mainloop) < 0) {
		qDebug("Could not start mainloop");
		return;
	}

	waitForStreamReady();

	pa_sample_spec fmt;
	fmt.channels = 2;
	fmt.format = PA_SAMPLE_S16LE;
	fmt.rate = 44100;

	pa_buffer_attr buffer_attributes;
	buffer_attributes.tlength = pa_bytes_per_second(&fmt) / 5;
	buffer_attributes.maxlength = buffer_attributes.tlength * 3;
	buffer_attributes.minreq = buffer_attributes.tlength / 3;
	buffer_attributes.prebuf = buffer_attributes.tlength;

	m_stream = pa_stream_new(m_context, "emumaster", &fmt, 0);
	if (!m_stream) {
		int error = pa_context_errno(m_context);
		qDebug("Could not acquire new PulseAudio stream: %s", pa_strerror(error));
		return;
	}
	pa_stream_flags_t flags = (pa_stream_flags_t)(PA_STREAM_ADJUST_LATENCY | PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE);
//	pa_stream_flags_t flags = (pa_stream_flags_t) (PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_EARLY_REQUESTS);
	if (pa_stream_connect_playback(m_stream, 0, &buffer_attributes, flags, 0, 0) < 0) {
		m_stream = 0;
		int error = pa_context_errno(m_context);
		qDebug("Could not connect for playback: %s", pa_strerror(error));
		return;
	}

	waitForStreamReady();

	pa_threaded_mainloop_unlock(m_mainloop);
}

/*! Stops audio streaming. */
void HostAudio::close()
{
	if (m_mainloop)
		pa_threaded_mainloop_stop(m_mainloop);
	if (m_stream) {
		pa_stream_unref(m_stream);
		m_stream = 0;
	}
	if (m_context) {
		pa_context_disconnect(m_context);
		pa_context_unref(m_context);
		m_context = 0;
	}
	if (m_mainloop) {
		pa_threaded_mainloop_free(m_mainloop);
		m_mainloop = 0;
	}
}

/*! Streams a frame of audio from emulated system to the host. */
void HostAudio::sendFrame()
{
	if (!m_stream)
		return;
	pa_threaded_mainloop_lock(m_mainloop);
	void *data;
#if defined(MEEGO_EDITION_HARMATTAN)
	size_t size = -1;
	pa_stream_begin_write(m_stream, &data, &size);
#elif defined(Q_WS_MAEMO_5)
	size_t size = 4096;
	static char buf[4096];
	data = buf;
#endif
	size = qMin(size, pa_stream_writable_size(m_stream));
	if (size)
		size = m_emu->fillAudioBuffer(reinterpret_cast<char *>(data), size);
	if (size)
		pa_stream_write(m_stream, data, size, 0, 0, PA_SEEK_RELATIVE);
#if defined(MEEGO_EDITION_HARMATTAN)
	else
		pa_stream_cancel_write(m_stream);
#endif
	pa_threaded_mainloop_unlock(m_mainloop);
}

/*! \internal */
void HostAudio::waitForStreamReady()
{
	pa_context_state_t context_state = pa_context_get_state(m_context);
	while (context_state != PA_CONTEXT_READY) {
		context_state = pa_context_get_state(m_context);
		if (!PA_CONTEXT_IS_GOOD(context_state)) {
			int error = pa_context_errno(m_context);
			qDebug("Context state is not good: %s", pa_strerror(error));
			return;
		} else if (context_state == PA_CONTEXT_READY) {
			break;
		} else {
			//qDebug("PulseAudio context state is %d", context_state);
		}
		pa_threaded_mainloop_wait(m_mainloop);
	}
}
コード例 #7
0
static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
	int             state;
	Uint16          test_format;
	pa_sample_spec  paspec;
	pa_buffer_attr  paattr;
	pa_channel_map  pacmap;
	pa_stream_flags_t flags = 0;

	paspec.format = PA_SAMPLE_INVALID;
	for ( test_format = SDL_FirstAudioFormat(spec->format); test_format; ) {
		switch ( test_format ) {
			case AUDIO_U8:
				paspec.format = PA_SAMPLE_U8;
				break;
			case AUDIO_S16LSB:
				paspec.format = PA_SAMPLE_S16LE;
				break;
			case AUDIO_S16MSB:
				paspec.format = PA_SAMPLE_S16BE;
				break;
		}
		if ( paspec.format != PA_SAMPLE_INVALID )
			break;
		test_format = SDL_NextAudioFormat();
	}
	if (paspec.format == PA_SAMPLE_INVALID ) {
		SDL_SetError("Couldn't find any suitable audio formats");
		return(-1);
	}
	spec->format = test_format;

	paspec.channels = spec->channels;
	paspec.rate = spec->freq;

	
#ifdef PA_STREAM_ADJUST_LATENCY
	spec->samples /= 2; 
#endif
	SDL_CalculateAudioSpec(spec);

	
	mixlen = spec->size;
	mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen);
	if ( mixbuf == NULL ) {
		return(-1);
	}
	SDL_memset(mixbuf, spec->silence, spec->size);

	
#ifdef PA_STREAM_ADJUST_LATENCY
	paattr.tlength = mixlen * 4; 
	paattr.prebuf = -1;
	paattr.maxlength = -1;
	paattr.minreq = mixlen; 
	flags = PA_STREAM_ADJUST_LATENCY;
#else
	paattr.tlength = mixlen*2;
	paattr.prebuf = mixlen*2;
	paattr.maxlength = mixlen*2;
	paattr.minreq = mixlen;
#endif

	
	
	SDL_NAME(pa_channel_map_init_auto)(
		&pacmap, spec->channels, PA_CHANNEL_MAP_WAVEEX);

	
	if (!(mainloop = SDL_NAME(pa_mainloop_new)())) {
		PULSE_CloseAudio(this);
		SDL_SetError("pa_mainloop_new() failed");
		return(-1);
	}

	if (this->hidden->caption == NULL) {
		char *title = NULL;
		SDL_WM_GetCaption(&title, NULL);
		PULSE_SetCaption(this, title);
	}

	mainloop_api = SDL_NAME(pa_mainloop_get_api)(mainloop);
	if (!(context = SDL_NAME(pa_context_new)(mainloop_api,
	                                         this->hidden->caption))) {
		PULSE_CloseAudio(this);
		SDL_SetError("pa_context_new() failed");
		return(-1);
	}

	
	if (SDL_NAME(pa_context_connect)(context, NULL, 0, NULL) < 0) {
		PULSE_CloseAudio(this);
		SDL_SetError("Could not setup connection to PulseAudio");
		return(-1);
	}

	do {
		if (SDL_NAME(pa_mainloop_iterate)(mainloop, 1, NULL) < 0) {
			PULSE_CloseAudio(this);
			SDL_SetError("pa_mainloop_iterate() failed");
			return(-1);
		}
		state = SDL_NAME(pa_context_get_state)(context);
		if (!PA_CONTEXT_IS_GOOD(state)) {
			PULSE_CloseAudio(this);
			SDL_SetError("Could not connect to PulseAudio");
			return(-1);
		}
	} while (state != PA_CONTEXT_READY);

	stream = SDL_NAME(pa_stream_new)(
		context,
		"Simple DirectMedia Layer",  
		&paspec,                     
		&pacmap                      
	);
	if ( stream == NULL ) {
		PULSE_CloseAudio(this);
		SDL_SetError("Could not setup PulseAudio stream");
		return(-1);
	}

	if (SDL_NAME(pa_stream_connect_playback)(stream, NULL, &paattr, flags,
			NULL, NULL) < 0) {
		PULSE_CloseAudio(this);
		SDL_SetError("Could not connect PulseAudio stream");
		return(-1);
	}

	do {
		if (SDL_NAME(pa_mainloop_iterate)(mainloop, 1, NULL) < 0) {
			PULSE_CloseAudio(this);
			SDL_SetError("pa_mainloop_iterate() failed");
			return(-1);
		}
		state = SDL_NAME(pa_stream_get_state)(stream);
		if (!PA_STREAM_IS_GOOD(state)) {
			PULSE_CloseAudio(this);
			SDL_SetError("Could not create to PulseAudio stream");
			return(-1);
		}
	} while (state != PA_STREAM_READY);

	return(0);
}
コード例 #8
0
ファイル: paaudio.c プロジェクト: juanquintela/qemu
/* common */
static void *qpa_audio_init(Audiodev *dev)
{
    paaudio *g;
    AudiodevPaOptions *popts = &dev->u.pa;
    const char *server;

    if (!popts->has_server) {
        char pidfile[64];
        char *runtime;
        struct stat st;

        runtime = getenv("XDG_RUNTIME_DIR");
        if (!runtime) {
            return NULL;
        }
        snprintf(pidfile, sizeof(pidfile), "%s/pulse/pid", runtime);
        if (stat(pidfile, &st) != 0) {
            return NULL;
        }
    }

    assert(dev->driver == AUDIODEV_DRIVER_PA);

    g = g_malloc(sizeof(paaudio));
    server = popts->has_server ? popts->server : NULL;

    g->dev = dev;
    g->mainloop = NULL;
    g->context = NULL;

    g->mainloop = pa_threaded_mainloop_new ();
    if (!g->mainloop) {
        goto fail;
    }

    g->context = pa_context_new (pa_threaded_mainloop_get_api (g->mainloop),
                                 server);
    if (!g->context) {
        goto fail;
    }

    pa_context_set_state_callback (g->context, context_state_cb, g);

    if (pa_context_connect(g->context, server, 0, NULL) < 0) {
        qpa_logerr (pa_context_errno (g->context),
                    "pa_context_connect() failed\n");
        goto fail;
    }

    pa_threaded_mainloop_lock (g->mainloop);

    if (pa_threaded_mainloop_start (g->mainloop) < 0) {
        goto unlock_and_fail;
    }

    for (;;) {
        pa_context_state_t state;

        state = pa_context_get_state (g->context);

        if (state == PA_CONTEXT_READY) {
            break;
        }

        if (!PA_CONTEXT_IS_GOOD (state)) {
            qpa_logerr (pa_context_errno (g->context),
                        "Wrong context state\n");
            goto unlock_and_fail;
        }

        /* Wait until the context is ready */
        pa_threaded_mainloop_wait (g->mainloop);
    }

    pa_threaded_mainloop_unlock (g->mainloop);

    return g;

unlock_and_fail:
    pa_threaded_mainloop_unlock (g->mainloop);
fail:
    AUD_log (AUDIO_CAP, "Failed to initialize PA context");
    qpa_audio_fini(g);
    return NULL;
}
コード例 #9
0
ファイル: pulseaudio.c プロジェクト: mayamonkeys/projectmaya
static ALCboolean pulse_open(ALCdevice *device, const ALCchar *device_name) //{{{
{
    pulse_data *data = ppa_xmalloc0(sizeof(pulse_data));
    pa_context_state_t state;

    if(ppa_get_binary_name(data->path_name, sizeof(data->path_name)))
        data->context_name = ppa_path_get_filename(data->path_name);
    else
        data->context_name = "OpenAL Soft";

    if(!(data->loop = ppa_threaded_mainloop_new()))
    {
        AL_PRINT("pa_threaded_mainloop_new() failed!\n");
        goto out;
    }

    if(ppa_threaded_mainloop_start(data->loop) < 0)
    {
        AL_PRINT("pa_threaded_mainloop_start() failed\n");
        goto out;
    }

    ppa_threaded_mainloop_lock(data->loop);

    data->context = ppa_context_new(ppa_threaded_mainloop_get_api(data->loop), data->context_name);
    if(!data->context)
    {
        AL_PRINT("pa_context_new() failed: %s\n",
                 ppa_strerror(ppa_context_errno(data->context)));

        ppa_threaded_mainloop_unlock(data->loop);
        goto out;
    }

    if(ppa_context_connect(data->context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL) < 0)
    {
        AL_PRINT("Context did not connect: %s\n",
                 ppa_strerror(ppa_context_errno(data->context)));

        ppa_context_unref(data->context);
        data->context = NULL;

        ppa_threaded_mainloop_unlock(data->loop);
        goto out;
    }

    while((state=ppa_context_get_state(data->context)) != PA_CONTEXT_READY)
    {
        if(!PA_CONTEXT_IS_GOOD(state))
        {
            AL_PRINT("Context did not get ready: %s\n",
                     ppa_strerror(ppa_context_errno(data->context)));

            ppa_context_unref(data->context);
            data->context = NULL;

            ppa_threaded_mainloop_unlock(data->loop);
            goto out;
        }

        ppa_threaded_mainloop_unlock(data->loop);
        Sleep(1);
        ppa_threaded_mainloop_lock(data->loop);
    }

    device->szDeviceName = strdup(device_name);
    device->ExtraData = data;

    ppa_threaded_mainloop_unlock(data->loop);
    return ALC_TRUE;

out:
    if(data->loop)
    {
        ppa_threaded_mainloop_stop(data->loop);
        ppa_threaded_mainloop_free(data->loop);
    }

    ppa_xfree(data);
    return ALC_FALSE;
} //}}}
コード例 #10
0
ファイル: pulseaudio.c プロジェクト: DAOWAce/pcsxr
void SetupSound (void)
{
     int error_number;

     // Acquire mainloop ///////////////////////////////////////////////////////
     device.mainloop = pa_threaded_mainloop_new ();
     if (device.mainloop == NULL)
     {
	  fprintf (stderr, "Could not acquire PulseAudio main loop\n");
	  return;
     }

     // Acquire context ////////////////////////////////////////////////////////
     device.api = pa_threaded_mainloop_get_api (device.mainloop);
     device.context = pa_context_new (device.api, "PCSXR");
     pa_context_set_state_callback (device.context, context_state_cb, &device);

     if (device.context == NULL)
     {
	  fprintf (stderr, "Could not acquire PulseAudio device context\n");
	  return;
     }

     // Connect to PulseAudio server ///////////////////////////////////////////
     if (pa_context_connect (device.context, NULL, 0, NULL) < 0)
     {
	  error_number = pa_context_errno (device.context);
	  fprintf (stderr, "Could not connect to PulseAudio server: %s\n", pa_strerror(error_number));
	  return;
     }

     // Run mainloop until sever context is ready //////////////////////////////
     pa_threaded_mainloop_lock (device.mainloop);
     if (pa_threaded_mainloop_start (device.mainloop) < 0)
     {
	  fprintf (stderr, "Could not start mainloop\n");
	  return;
     }

     pa_context_state_t context_state;
     context_state = pa_context_get_state (device.context);
     while (context_state != PA_CONTEXT_READY)
     {
	  context_state = pa_context_get_state (device.context);
	  if (! PA_CONTEXT_IS_GOOD (context_state))
	  {
	       error_number = pa_context_errno (device.context);
	       fprintf (stderr, "Context state is not good: %s\n", pa_strerror (error_number));
	       return;
	  }
	  else if (context_state == PA_CONTEXT_READY)
	       break;
	  else
	       fprintf (stderr, "PulseAudio context state is %d\n", context_state);
	  pa_threaded_mainloop_wait (device.mainloop);
     }

     // Set sample spec ////////////////////////////////////////////////////////
     device.spec.format = PA_SAMPLE_S16NE;
     if (iDisStereo)
	  device.spec.channels = 1;
     else
	  device.spec.channels = 2;
     device.spec.rate = settings.frequency;

     pa_buffer_attr buffer_attributes;
     buffer_attributes.tlength = pa_bytes_per_second (& device.spec) / 5;
     buffer_attributes.maxlength = buffer_attributes.tlength * 3;
     buffer_attributes.minreq = buffer_attributes.tlength / 3;
     buffer_attributes.prebuf = buffer_attributes.tlength;

     //maxlength = buffer_attributes.maxlength;
     //fprintf (stderr, "Total space: %u\n", buffer_attributes.maxlength);
     //fprintf (stderr, "Minimum request size: %u\n", buffer_attributes.minreq);
     //fprintf (stderr, "Bytes needed before playback: %u\n", buffer_attributes.prebuf);
     //fprintf (stderr, "Target buffer size: %lu\n", buffer_attributes.tlength);

     // Acquire new stream using spec //////////////////////////////////////////
     device.stream = pa_stream_new (device.context, "PCSXR", &device.spec, NULL);
     if (device.stream == NULL)
     {
	  error_number = pa_context_errno (device.context);
	  fprintf (stderr, "Could not acquire new PulseAudio stream: %s\n", pa_strerror (error_number));
	  return;
     }

     // Set callbacks for server events ////////////////////////////////////////
     pa_stream_set_state_callback (device.stream, stream_state_cb, &device);
     pa_stream_set_write_callback (device.stream, stream_request_cb, &device);
     pa_stream_set_latency_update_callback (device.stream, stream_latency_update_cb, &device);

     // Ready stream for playback //////////////////////////////////////////////
     pa_stream_flags_t flags = (pa_stream_flags_t) (PA_STREAM_ADJUST_LATENCY | PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE);
     //pa_stream_flags_t flags = (pa_stream_flags_t) (PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_EARLY_REQUESTS);
     if (pa_stream_connect_playback (device.stream, NULL, &buffer_attributes, flags, NULL, NULL) < 0)
     {
	  pa_context_errno (device.context);
	  fprintf (stderr, "Could not connect for playback: %s\n", pa_strerror (error_number));
	  return;
     }

     // Run mainloop until stream is ready /////////////////////////////////////
     pa_stream_state_t stream_state;
     stream_state = pa_stream_get_state (device.stream);
     while (stream_state != PA_STREAM_READY)
     {
	  stream_state = pa_stream_get_state (device.stream);

	  if (stream_state == PA_STREAM_READY)
	       break;

	  else if (! PA_STREAM_IS_GOOD (stream_state))
	  {
	       error_number = pa_context_errno (device.context);
	       fprintf (stderr, "Stream state is not good: %s\n", pa_strerror (error_number));
	       return;
	  }
	  else
	       fprintf (stderr, "PulseAudio stream state is %d\n", stream_state);
	  pa_threaded_mainloop_wait (device.mainloop);
     }

     pa_threaded_mainloop_unlock (device.mainloop);

     fprintf  (stderr, "PulseAudio should be connected\n");
     return;
}
コード例 #11
0
ファイル: pulsesrc.c プロジェクト: spunktsch/svtplayer
static gboolean
gst_pulsesrc_open (GstAudioSrc * asrc)
{
  GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc);
  gchar *name = gst_pulse_client_name ();

  pa_threaded_mainloop_lock (pulsesrc->mainloop);

  g_assert (!pulsesrc->context);
  g_assert (!pulsesrc->stream);

  GST_DEBUG_OBJECT (pulsesrc, "opening device");

  if (!(pulsesrc->context =
          pa_context_new (pa_threaded_mainloop_get_api (pulsesrc->mainloop),
              name))) {
    GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Failed to create context"),
        (NULL));
    goto unlock_and_fail;
  }

  pa_context_set_state_callback (pulsesrc->context,
      gst_pulsesrc_context_state_cb, pulsesrc);

  GST_DEBUG_OBJECT (pulsesrc, "connect to server %s",
      GST_STR_NULL (pulsesrc->server));

  if (pa_context_connect (pulsesrc->context, pulsesrc->server, 0, NULL) < 0) {
    GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Failed to connect: %s",
            pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
    goto unlock_and_fail;
  }

  for (;;) {
    pa_context_state_t state;

    state = pa_context_get_state (pulsesrc->context);

    if (!PA_CONTEXT_IS_GOOD (state)) {
      GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Failed to connect: %s",
              pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
      goto unlock_and_fail;
    }

    if (state == PA_CONTEXT_READY)
      break;

    /* Wait until the context is ready */
    pa_threaded_mainloop_wait (pulsesrc->mainloop);
  }
  GST_DEBUG_OBJECT (pulsesrc, "connected");

  pa_threaded_mainloop_unlock (pulsesrc->mainloop);

  g_free (name);
  return TRUE;

  /* ERRORS */
unlock_and_fail:
  {
    gst_pulsesrc_destroy_context (pulsesrc);

    pa_threaded_mainloop_unlock (pulsesrc->mainloop);

    g_free (name);
    return FALSE;
  }
}
コード例 #12
0
ファイル: simple.c プロジェクト: KOLIA112/pulseaudio
pa_simple* pa_simple_new(
        const char *server,
        const char *name,
        pa_stream_direction_t dir,
        const char *dev,
        const char *stream_name,
        const pa_sample_spec *ss,
        const pa_channel_map *map,
        const pa_buffer_attr *attr,
        int *rerror) {

    pa_simple *p;
    int error = PA_ERR_INTERNAL, r;

    CHECK_VALIDITY_RETURN_ANY(rerror, !server || *server, PA_ERR_INVALID, NULL);
    CHECK_VALIDITY_RETURN_ANY(rerror, dir == PA_STREAM_PLAYBACK || dir == PA_STREAM_RECORD, PA_ERR_INVALID, NULL);
    CHECK_VALIDITY_RETURN_ANY(rerror, !dev || *dev, PA_ERR_INVALID, NULL);
    CHECK_VALIDITY_RETURN_ANY(rerror, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID, NULL);
    CHECK_VALIDITY_RETURN_ANY(rerror, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID, NULL)

    p = pa_xnew0(pa_simple, 1);
    p->direction = dir;

    if (!(p->mainloop = pa_threaded_mainloop_new()))
        goto fail;

    if (!(p->context = pa_context_new(pa_threaded_mainloop_get_api(p->mainloop), name)))
        goto fail;

    pa_context_set_state_callback(p->context, context_state_cb, p);

    if (pa_context_connect(p->context, server, 0, NULL) < 0) {
        error = pa_context_errno(p->context);
        goto fail;
    }

    pa_threaded_mainloop_lock(p->mainloop);

    if (pa_threaded_mainloop_start(p->mainloop) < 0)
        goto unlock_and_fail;

    for (;;) {
        pa_context_state_t state;

        state = pa_context_get_state(p->context);

        if (state == PA_CONTEXT_READY)
            break;

        if (!PA_CONTEXT_IS_GOOD(state)) {
            error = pa_context_errno(p->context);
            goto unlock_and_fail;
        }

        /* Wait until the context is ready */
        pa_threaded_mainloop_wait(p->mainloop);
    }

    if (!(p->stream = pa_stream_new(p->context, stream_name, ss, map))) {
        error = pa_context_errno(p->context);
        goto unlock_and_fail;
    }

    pa_stream_set_state_callback(p->stream, stream_state_cb, p);
    pa_stream_set_read_callback(p->stream, stream_request_cb, p);
    pa_stream_set_write_callback(p->stream, stream_request_cb, p);
    pa_stream_set_latency_update_callback(p->stream, stream_latency_update_cb, p);

    if (dir == PA_STREAM_PLAYBACK)
        r = pa_stream_connect_playback(p->stream, dev, attr,
                                       PA_STREAM_INTERPOLATE_TIMING
                                       |PA_STREAM_ADJUST_LATENCY
                                       |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
    else
        r = pa_stream_connect_record(p->stream, dev, attr,
                                     PA_STREAM_INTERPOLATE_TIMING
                                     |PA_STREAM_ADJUST_LATENCY
                                     |PA_STREAM_AUTO_TIMING_UPDATE);

    if (r < 0) {
        error = pa_context_errno(p->context);
        goto unlock_and_fail;
    }

    for (;;) {
        pa_stream_state_t state;

        state = pa_stream_get_state(p->stream);

        if (state == PA_STREAM_READY)
            break;

        if (!PA_STREAM_IS_GOOD(state)) {
            error = pa_context_errno(p->context);
            goto unlock_and_fail;
        }

        /* Wait until the stream is ready */
        pa_threaded_mainloop_wait(p->mainloop);
    }

    pa_threaded_mainloop_unlock(p->mainloop);

    return p;

unlock_and_fail:
    pa_threaded_mainloop_unlock(p->mainloop);

fail:
    if (rerror)
        *rerror = error;
    pa_simple_free(p);
    return NULL;
}
コード例 #13
0
ファイル: strudel.c プロジェクト: michaelmacinnis/strudel
int main(int argc, char **argv)
{
    M6502 *mpu;
    Strudel *mb;

    pa_mainloop_api *api;
    pa_context *context;
    pa_stream *stream;

    pa_context_state_t state;
    pa_sample_spec spec;

    int r;

    gtk_init(&argc, &argv);

    if (argc != 2) {
        fprintf(stderr, "You must specify a disk image.\n");
        return EXIT_FAILURE;
    }

    mb = calloc(1, sizeof(*mb));

    mb->main = calloc(65536, sizeof(*mb->main));
    mb->aux = calloc(65536, sizeof(*mb->aux));
    mb->firmware = calloc(65536, sizeof(*mb->firmware));

    mb->key = calloc(256, 1);
    mb->keyr = 0;
    mb->keyw = 0;

    mpu = M6502_new(mb, call_cb, read_cb, write_cb);

    loop = pa_threaded_mainloop_new();
    api = pa_threaded_mainloop_get_api(loop);
    context = pa_context_new(api, "strudel");
    pa_context_connect(context, NULL, 0, NULL);

    pa_threaded_mainloop_start(loop);

    for (;;) {
        state = pa_context_get_state(context);
        if (state == PA_CONTEXT_READY)
            break;
        else if (!PA_CONTEXT_IS_GOOD(state)) {
            fprintf(stderr, "bad context state (%d)\n",
                    pa_context_errno(context));
            return EXIT_FAILURE;
        }
    }

    spec.rate = 44100;
    spec.channels = 1;
    spec.format = PA_SAMPLE_S16LE;

    stream = pa_stream_new(context, "output", &spec, NULL);
    if (!stream) {
        fprintf(stderr, "pa_stream_new failed\n");
		return EXIT_FAILURE;
    }

    pa_stream_set_write_callback(stream, stream_request_cb, mpu);

    r = pa_stream_connect_playback(stream, NULL, NULL, 0, NULL, NULL);
    if (r < 0) {
        fprintf(stderr, "pa_stream_connect_playback failed\n");
		return EXIT_FAILURE;
    }

	mb->s6d1 = fopen(argv[1], "r+");
    if (mb->s6d1 == NULL) {
        fprintf(stderr, "Can't open '%s'.\n", argv[1]);
        return EXIT_FAILURE;
    }

    load(mpu, "./firmware.rom");

    /* Create buffers for raw and scaled screen */
    screen = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 560, 384);

    /* Create main window. */
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    gtk_window_set_title(GTK_WINDOW(window), "Strudel");
    
    g_signal_connect(window, "delete-event", G_CALLBACK(delete_event), NULL);
    g_signal_connect(window, "destroy", G_CALLBACK(destroy), NULL);
    g_signal_connect(window, "key-press-event",
                     G_CALLBACK(key), mpu);

    /* Create screen widget. */
    drawing_area = gtk_drawing_area_new();
    gtk_container_add(GTK_CONTAINER(window), drawing_area);

    gtk_widget_set_events(drawing_area, GDK_EXPOSURE_MASK);

    gtk_widget_set_size_request(drawing_area, 560, 384);

    M6502_do(mpu, M6502_RST);

    g_idle_add(idle, mpu);

    /* Go. */
    gtk_widget_show_all(window);
    gtk_main();
    
    M6502_delete(mpu);

    return 0;
}
コード例 #14
0
static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
	int             state;
	Uint16          test_format;
	pa_sample_spec  paspec;
	pa_buffer_attr  paattr;
	pa_channel_map  pacmap;
	pa_stream_flags_t flags = 0;

	paspec.format = PA_SAMPLE_INVALID;
	for ( test_format = SDL_FirstAudioFormat(spec->format); test_format; ) {
		switch ( test_format ) {
			case AUDIO_U8:
				paspec.format = PA_SAMPLE_U8;
				break;
			case AUDIO_S16LSB:
				paspec.format = PA_SAMPLE_S16LE;
				break;
			case AUDIO_S16MSB:
				paspec.format = PA_SAMPLE_S16BE;
				break;
		}
		if ( paspec.format != PA_SAMPLE_INVALID )
			break;
	}
	if (paspec.format == PA_SAMPLE_INVALID ) {
		SDL_SetError("Couldn't find any suitable audio formats");
		return(-1);
	}
	spec->format = test_format;

	paspec.channels = spec->channels;
	paspec.rate = spec->freq;

	/* Calculate the final parameters for this audio specification */
#ifdef PA_STREAM_ADJUST_LATENCY
	spec->samples /= 2; /* Mix in smaller chunck to avoid underruns */
#endif
	SDL_CalculateAudioSpec(spec);

	/* Allocate mixing buffer */
	mixlen = spec->size;
	mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen);
	if ( mixbuf == NULL ) {
		return(-1);
	}
	SDL_memset(mixbuf, spec->silence, spec->size);

	/* Reduced prebuffering compared to the defaults. */
#ifdef PA_STREAM_ADJUST_LATENCY
	paattr.tlength = mixlen * 4; /* 2x original requested bufsize */
	paattr.prebuf = -1;
	paattr.maxlength = -1;
	paattr.minreq = mixlen; /* -1 can lead to pa_stream_writable_size()
				   >= mixlen never becoming true */
	flags = PA_STREAM_ADJUST_LATENCY;
#else
	paattr.tlength = mixlen*2;
	paattr.prebuf = mixlen*2;
	paattr.maxlength = mixlen*2;
	paattr.minreq = mixlen;
#endif

	/* The SDL ALSA output hints us that we use Windows' channel mapping */
	/* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */
	SDL_NAME(pa_channel_map_init_auto)(
		&pacmap, spec->channels, PA_CHANNEL_MAP_WAVEEX);

	/* Set up a new main loop */
	if (!(mainloop = SDL_NAME(pa_mainloop_new)())) {
		PULSE_CloseAudio(this);
		SDL_SetError("pa_mainloop_new() failed");
		return(-1);
	}

	mainloop_api = SDL_NAME(pa_mainloop_get_api)(mainloop);
	if (!(context = SDL_NAME(pa_context_new)(mainloop_api, get_progname()))) {
		PULSE_CloseAudio(this);
		SDL_SetError("pa_context_new() failed");
		return(-1);
	}

	/* Connect to the PulseAudio server */
	if (SDL_NAME(pa_context_connect)(context, NULL, 0, NULL) < 0) {
		PULSE_CloseAudio(this);
	        SDL_SetError("Could not setup connection to PulseAudio");
		return(-1);
	}

	do {
		if (SDL_NAME(pa_mainloop_iterate)(mainloop, 1, NULL) < 0) {
			PULSE_CloseAudio(this);
			SDL_SetError("pa_mainloop_iterate() failed");
			return(-1);
		}
		state = SDL_NAME(pa_context_get_state)(context);
		if (!PA_CONTEXT_IS_GOOD(state)) {
			PULSE_CloseAudio(this);
			SDL_SetError("Could not connect to PulseAudio");
			return(-1);
		}
	} while (state != PA_CONTEXT_READY);

	stream = SDL_NAME(pa_stream_new)(
		context,
		"Simple DirectMedia Layer",  /* stream description */
		&paspec,                     /* sample format spec */
		&pacmap                      /* channel map */
	);
	if ( stream == NULL ) {
		PULSE_CloseAudio(this);
		SDL_SetError("Could not setup PulseAudio stream");
		return(-1);
	}

	if (SDL_NAME(pa_stream_connect_playback)(stream, NULL, &paattr, flags,
			NULL, NULL) < 0) {
		PULSE_CloseAudio(this);
		SDL_SetError("Could not connect PulseAudio stream");
		return(-1);
	}

	do {
		if (SDL_NAME(pa_mainloop_iterate)(mainloop, 1, NULL) < 0) {
			PULSE_CloseAudio(this);
			SDL_SetError("pa_mainloop_iterate() failed");
			return(-1);
		}
		state = SDL_NAME(pa_stream_get_state)(stream);
		if (!PA_STREAM_IS_GOOD(state)) {
			PULSE_CloseAudio(this);
			SDL_SetError("Could not create to PulseAudio stream");
			return(-1);
		}
	} while (state != PA_STREAM_READY);

	return(0);
}
コード例 #15
0
ファイル: ao_pulse.c プロジェクト: jmglogow/mpv
static int pa_init_boilerplate(struct ao *ao)
{
    struct priv *priv = ao->priv;
    char *host = priv->cfg_host && priv->cfg_host[0] ? priv->cfg_host : NULL;
    bool locked = false;

    pthread_mutex_init(&priv->wakeup_lock, NULL);
    pthread_cond_init(&priv->wakeup, NULL);

    if (!(priv->mainloop = pa_threaded_mainloop_new())) {
        MP_ERR(ao, "Failed to allocate main loop\n");
        goto fail;
    }

    if (pa_threaded_mainloop_start(priv->mainloop) < 0)
        goto fail;

    pa_threaded_mainloop_lock(priv->mainloop);
    locked = true;

    if (!(priv->context = pa_context_new(pa_threaded_mainloop_get_api(
                                         priv->mainloop), ao->client_name)))
    {
        MP_ERR(ao, "Failed to allocate context\n");
        goto fail;
    }

    MP_VERBOSE(ao, "Library version: %s\n", pa_get_library_version());
    MP_VERBOSE(ao, "Proto: %lu\n",
        (long)pa_context_get_protocol_version(priv->context));
    MP_VERBOSE(ao, "Server proto: %lu\n",
        (long)pa_context_get_server_protocol_version(priv->context));

    pa_context_set_state_callback(priv->context, context_state_cb, ao);
    pa_context_set_subscribe_callback(priv->context, subscribe_cb, ao);

    if (pa_context_connect(priv->context, host, 0, NULL) < 0)
        goto fail;

    /* Wait until the context is ready */
    while (1) {
        int state = pa_context_get_state(priv->context);
        if (state == PA_CONTEXT_READY)
            break;
        if (!PA_CONTEXT_IS_GOOD(state))
            goto fail;
        pa_threaded_mainloop_wait(priv->mainloop);
    }

    pa_threaded_mainloop_unlock(priv->mainloop);
    return 0;

fail:
    if (locked)
        pa_threaded_mainloop_unlock(priv->mainloop);

    if (priv->context) {
        pa_threaded_mainloop_lock(priv->mainloop);
        if (!(pa_context_errno(priv->context) == PA_ERR_CONNECTIONREFUSED
              && ao->probing))
            GENERIC_ERR_MSG("Init failed");
        pa_threaded_mainloop_unlock(priv->mainloop);
    }
    uninit(ao);
    return -1;
}
コード例 #16
0
ファイル: oss.cpp プロジェクト: dreiss/M1-Android
INT16 m1sdr_Init(int sample_rate)
{	
	int format, stereo, rate, fsize, err, state;
	unsigned int nfreq, periodtime;
	snd_pcm_hw_params_t *hwparams;
	#ifdef USE_SDL
	SDL_AudioSpec aspec;
	#endif
	pa_channel_map chanmap;
	pa_buffer_attr my_pa_attr;

	hw_present = 0;

	m1sdr_Callback = NULL;

	nDSoundSegLen = sample_rate / 60;

	switch (lnxdrv_apimode)
	{
	case 0: // SDL
		#ifdef USE_SDL
		SDL_InitSubSystem(SDL_INIT_AUDIO);

	 	m1sdr_SetSamplesPerTick(sample_rate/60);

		playbuf = 0;
		writebuf = 1;

		aspec.freq = sample_rate;
		aspec.format = AUDIO_S16SYS;	// keep endian independant 
		aspec.channels = 2;
		aspec.samples = 512;		// has to be a power of 2, and we want it smaller than our buffer size
		aspec.callback = sdl_callback;
		aspec.userdata = 0;

		if (SDL_OpenAudio(&aspec, NULL) < 0)
		{
			printf("ERROR: can't open SDL audio\n");
			return 0;
		}

		// make sure we don't start yet
		SDL_PauseAudio(1);
		#endif
		break;
				
	case 1:	// ALSA
		// Try to open audio device
		if ((err = snd_pcm_open(&pHandle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
			fprintf(stderr, "ALSA: Could not open soundcard (%s)\n", snd_strerror(err));
			hw_present = 0;
			return 0;
		}

		if ((err = snd_pcm_hw_params_malloc(&hwparams)) < 0) {
			fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
				 snd_strerror(err));
			return 0;
		}

		// Init hwparams with full configuration space
		if ((err = snd_pcm_hw_params_any(pHandle, hwparams)) < 0) {
			fprintf(stderr, "ALSA: couldn't set hw params (%s)\n", snd_strerror(err));
			hw_present = 0;
			return 0;
		}

		// Set access type
		if ((err = snd_pcm_hw_params_set_access(pHandle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
			fprintf(stderr, "ALSA: can't set access (%s)\n", snd_strerror(err));
			return 0;
		}

		// Set sample format
		if ((err = snd_pcm_hw_params_set_format(pHandle, hwparams, SND_PCM_FORMAT_S16)) < 0) {
			fprintf(stderr, "ALSA: can't set format (%s)\n", snd_strerror(err));
			return 0;
		}

		// Set sample rate (nearest possible)
		nfreq = sample_rate;
		if ((err = snd_pcm_hw_params_set_rate_near(pHandle, hwparams, &nfreq, 0)) < 0) {
			fprintf(stderr, "ALSA: can't set sample rate (%s)\n", snd_strerror(err));
			return 0;
		}

		// Set number of channels
		if ((err = snd_pcm_hw_params_set_channels(pHandle, hwparams, 2)) < 0) {
			fprintf(stderr, "ALSA: can't set stereo (%s)\n", snd_strerror(err));
			return 0;
		}

		// Set period time (nearest possible)
		periodtime = 16;
		if ((err = snd_pcm_hw_params_set_period_time_near(pHandle, hwparams, &periodtime, 0)) < 0) {
			fprintf(stderr, "ALSA: can't set period time (%s)\n", snd_strerror(err));
			return 0;
		}

		// Apply HW parameter settings to PCM device and prepare device
		if ((err = snd_pcm_hw_params(pHandle, hwparams)) < 0) {
			fprintf(stderr, "ALSA: unable to install hw_params (%s)\n", snd_strerror(err));
			snd_pcm_hw_params_free(hwparams);
			return 0;
		}

		snd_pcm_hw_params_free(hwparams);

		if ((err = snd_pcm_prepare(pHandle)) < 0) {
			fprintf (stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror(err));
			return 0;
		}
		break;	

	case 2:	// OSS
		audiofd = open("/dev/dsp", O_WRONLY, 0);
		if (audiofd == -1)
		{
			audiofd = open("/dev/dsp1", O_WRONLY, 0);

			if (audiofd == -1)
			{
				perror("/dev/dsp1");
				return(0);
			}
		}

		// reset things
		ioctl(audiofd, SNDCTL_DSP_RESET, 0);

		is_broken_driver = 0;
		num_frags = NUM_FRAGS_NORMAL;

		// set the buffer size we want
		fsize = OSS_FRAGMENT;
		if (ioctl(audiofd, SNDCTL_DSP_SETFRAGMENT, &fsize) == - 1)
		{
			perror("SNDCTL_DSP_SETFRAGMENT");
			return(0);
		}

		// set 16-bit output
		format = AFMT_S16_NE;	// 16 bit signed "native"-endian
		if (ioctl(audiofd, SNDCTL_DSP_SETFMT, &format) == - 1)
		{
			perror("SNDCTL_DSP_SETFMT");
			return(0);
		}

		// now set stereo
		stereo = 1;
		if (ioctl(audiofd, SNDCTL_DSP_STEREO, &stereo) == - 1)
		{
			perror("SNDCTL_DSP_STEREO");
			return(0);
		}

		// and the sample rate
		rate = sample_rate;
		if (ioctl(audiofd, SNDCTL_DSP_SPEED, &rate) == - 1)
		{
			perror("SNDCTL_DSP_SPEED");
			return(0);
		}

		// and make sure that did what we wanted
		ioctl(audiofd, SNDCTL_DSP_GETBLKSIZE, &fsize);
		break;

	case 3: // PulseAudio
		sample_spec.format = PA_SAMPLE_S16NE;
		sample_spec.rate = sample_rate;
		sample_spec.channels = 2;

		my_pa_context = NULL;
		my_pa_stream = NULL;
		my_pa_mainloop = NULL;
		my_pa_mainloop_api = NULL;

		#if !PULSE_USE_SIMPLE
		// get default channel mapping
		pa_channel_map_init_auto(&chanmap, sample_spec.channels, PA_CHANNEL_MAP_WAVEEX);


		if (!(my_pa_mainloop = pa_mainloop_new()))
		{
			fprintf(stderr, "pa_mainloop_new() failed\n");
			return 0;
		}

		my_pa_mainloop_api = pa_mainloop_get_api(my_pa_mainloop);

/*		if (pa_signal_init(my_pa_mainloop_api) != 0)
		{
			fprintf(stderr, "pa_signal_init() failed\n");
			return 0;
		}*/

		/* Create a new connection context */
		if (!(my_pa_context = pa_context_new(my_pa_mainloop_api, "Audio Overload"))) 
		{
			fprintf(stderr, "pa_context_new() failed\n");
			return 0;
		}

		/* set the context state CB */
//		pa_context_set_state_callback(my_pa_context, context_state_callback, NULL);

		/* Connect the context */
		if (pa_context_connect(my_pa_context, NULL, (pa_context_flags_t)0, NULL) < 0)
		{
			fprintf(stderr, "pa_context_connect() failed: %s", pa_strerror(pa_context_errno(my_pa_context)));
			return 0;
		}
		
		do
		{
			pa_mainloop_iterate(my_pa_mainloop, 1, NULL);
			state = pa_context_get_state(my_pa_context);
			if (!PA_CONTEXT_IS_GOOD((pa_context_state_t)state))
			{
				printf("PA CONTEXT NOT GOOD\n");
				hw_present = 0;
				return 0;
			}
		} while (state != PA_CONTEXT_READY);

		if (!(my_pa_stream = pa_stream_new(my_pa_context, "Audio Overload", &sample_spec, &chanmap))) 
		{
			fprintf(stderr, "pa_stream_new() failed: %s\n", pa_strerror(pa_context_errno(my_pa_context)));
			return 0;
		}

		memset(&my_pa_attr, 0, sizeof(my_pa_attr));
		my_pa_attr.tlength = nDSoundSegLen * 4 * 4;
		my_pa_attr.prebuf = -1;
		my_pa_attr.maxlength = -1;
		my_pa_attr.minreq = nDSoundSegLen * 4 * 2;

		if ((err = pa_stream_connect_playback(my_pa_stream, NULL, &my_pa_attr, PA_STREAM_ADJUST_LATENCY, NULL, NULL)) < 0)
		{
			fprintf(stderr, "pa_stream_connect_playback() failed: %s\n", pa_strerror(pa_context_errno(my_pa_context)));
			return 0;
		}

		do
		{
			pa_mainloop_iterate(my_pa_mainloop, 1, NULL);
			state = pa_stream_get_state(my_pa_stream);
			if (!PA_STREAM_IS_GOOD((pa_stream_state_t)state))
			{
				printf("PA STREAM NOT GOOD\n");
				hw_present = 0;
				return 0;
			}
		} while (state != PA_STREAM_READY);

//		printf("PulseAudio setup OK so far, len %d\n", nDSoundSegLen*4);
		#else
		my_simple = NULL;
		#endif
		break;
	}

	hw_present = 1;

	return (1);
}