forked from enlightenment/efl
ecore_audio: Add rudimentary ALSA support
By rudimentary I mean I barely got it to work. For my particular test case. It will not work for you and needs lots of love until it can be used. Signed-off-by: Daniel Willmann <d.willmann@samsung.com> SVN revision: 80999
This commit is contained in:
parent
d49fe90b18
commit
eb15fa9e9c
|
@ -76,6 +76,11 @@ ecore_audio_init(void)
|
||||||
ECORE_AUDIO_OUTPUT_INPUT_ADDED = ecore_event_type_new();
|
ECORE_AUDIO_OUTPUT_INPUT_ADDED = ecore_event_type_new();
|
||||||
ECORE_AUDIO_OUTPUT_INPUT_REMOVED = ecore_event_type_new();
|
ECORE_AUDIO_OUTPUT_INPUT_REMOVED = ecore_event_type_new();
|
||||||
|
|
||||||
|
#ifdef HAVE_ALSA
|
||||||
|
mod = ecore_audio_alsa_init();
|
||||||
|
if (mod)
|
||||||
|
ecore_audio_modules = eina_list_append(ecore_audio_modules, mod);
|
||||||
|
#endif
|
||||||
#ifdef HAVE_PULSE
|
#ifdef HAVE_PULSE
|
||||||
mod = ecore_audio_pulse_init();
|
mod = ecore_audio_pulse_init();
|
||||||
if (mod)
|
if (mod)
|
||||||
|
@ -107,6 +112,9 @@ ecore_audio_shutdown(void)
|
||||||
|
|
||||||
/* FIXME: Shutdown all the inputs and outputs first */
|
/* FIXME: Shutdown all the inputs and outputs first */
|
||||||
|
|
||||||
|
#ifdef HAVE_ALSA
|
||||||
|
ecore_audio_alsa_shutdown();
|
||||||
|
#endif
|
||||||
#ifdef HAVE_PULSE
|
#ifdef HAVE_PULSE
|
||||||
ecore_audio_pulse_shutdown();
|
ecore_audio_pulse_shutdown();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ALSA
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_FEATURES_H
|
||||||
|
#include <features.h>
|
||||||
|
#endif
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
|
#include "ecore_audio_private.h"
|
||||||
|
|
||||||
|
static Ecore_Audio_Module *alsa_module = NULL;
|
||||||
|
|
||||||
|
static Ecore_Audio_Object *
|
||||||
|
_alsa_output_new(Ecore_Audio_Object *output)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
Ecore_Audio_Output *out = (Ecore_Audio_Output *)output;
|
||||||
|
struct _Ecore_Audio_Alsa *alsa;
|
||||||
|
|
||||||
|
alsa = calloc(1, sizeof(struct _Ecore_Audio_Alsa));
|
||||||
|
if (!alsa)
|
||||||
|
{
|
||||||
|
ERR("Could not allocate memory for private structure.");
|
||||||
|
free(out);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->module_data = alsa;
|
||||||
|
|
||||||
|
ret = snd_pcm_open(&alsa->handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
ERR("Could not open playback: %s", snd_strerror(ret));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: Make configurable */
|
||||||
|
ret = snd_pcm_set_params(alsa->handle, SND_PCM_FORMAT_FLOAT, SND_PCM_ACCESS_RW_INTERLEAVED, 2, 44100, 1, 500000);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
ERR("Could not set parameters: %s", snd_strerror(ret));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
|
||||||
|
err:
|
||||||
|
free(out->module_data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_alsa_output_del(Ecore_Audio_Object *output)
|
||||||
|
{
|
||||||
|
free(output->module_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_alsa_output_async_cb(Ecore_Audio_Object *output)
|
||||||
|
{
|
||||||
|
unsigned char *data;
|
||||||
|
int size, ret;
|
||||||
|
snd_pcm_sframes_t avail;
|
||||||
|
Ecore_Audio_Output *out = output;
|
||||||
|
Ecore_Audio_Input *in = eina_list_data_get(out->inputs);
|
||||||
|
struct _Ecore_Audio_Alsa *alsa = (struct _Ecore_Audio_Alsa *)output->module_data;
|
||||||
|
|
||||||
|
/* XXX: Error handling! */
|
||||||
|
avail = snd_pcm_avail_update(alsa->handle);
|
||||||
|
ERR("Aval: %i", avail);
|
||||||
|
if (!avail)
|
||||||
|
return EINA_TRUE;
|
||||||
|
if (avail < 0)
|
||||||
|
goto recover;
|
||||||
|
|
||||||
|
data = calloc(1, sizeof(float) * avail * 8);
|
||||||
|
|
||||||
|
size = in->module->in_ops->input_read((Ecore_Audio_Object *)in, data, avail*8);
|
||||||
|
ERR("Read: %i", size);
|
||||||
|
|
||||||
|
ret = snd_pcm_writei(alsa->handle, data, size/8);
|
||||||
|
ERR("Written: %i", ret);
|
||||||
|
if (ret < 0) {
|
||||||
|
recover:
|
||||||
|
ERR(snd_strerror(ret));
|
||||||
|
snd_pcm_recover(alsa->handle, ret, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_alsa_output_add_input(Ecore_Audio_Object *output, Ecore_Audio_Object *input)
|
||||||
|
{
|
||||||
|
Ecore_Audio_Module *outmod = output->module;
|
||||||
|
Ecore_Audio_Module *inmod = input->module;
|
||||||
|
struct _Ecore_Audio_Alsa *alsa = (struct _Ecore_Audio_Alsa *)output->module_data;
|
||||||
|
|
||||||
|
ecore_timer_add(0.3, _alsa_output_async_cb, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct input_api inops = {
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct output_api outops = {
|
||||||
|
.output_new = _alsa_output_new,
|
||||||
|
.output_del = _alsa_output_del,
|
||||||
|
// .output_volume_set = _alsa_output_volume_set,
|
||||||
|
.output_add_input = _alsa_output_add_input,
|
||||||
|
// .output_del_input = _alsa_output_del_input,
|
||||||
|
// .output_update_input_format = _alsa_output_update_input_format,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* externally accessible functions */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup Ecore_Audio_Group Ecore_Audio_alsa - Ecore internal ALSA audio functions
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the Ecore_Audio ALSA module.
|
||||||
|
*
|
||||||
|
* @return the initialized module success, NULL on error.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Ecore_Audio_Module *
|
||||||
|
ecore_audio_alsa_init(void)
|
||||||
|
{
|
||||||
|
alsa_module = calloc(1, sizeof(Ecore_Audio_Module));
|
||||||
|
if (!alsa_module)
|
||||||
|
{
|
||||||
|
ERR("Could not allocate memory for the module.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ECORE_MAGIC_SET(alsa_module, ECORE_MAGIC_AUDIO_MODULE);
|
||||||
|
alsa_module->type = ECORE_AUDIO_TYPE_ALSA;
|
||||||
|
alsa_module->name = "alsa";
|
||||||
|
alsa_module->inputs = NULL;
|
||||||
|
alsa_module->outputs = NULL;
|
||||||
|
alsa_module->in_ops = &inops;
|
||||||
|
alsa_module->out_ops = &outops;
|
||||||
|
|
||||||
|
return alsa_module;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shut down the Ecore_Audio ALSA module
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ecore_audio_alsa_shutdown(void)
|
||||||
|
{
|
||||||
|
free(alsa_module);
|
||||||
|
alsa_module = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* HAVE_ALSA */
|
|
@ -9,6 +9,10 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ALSA
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_PULSE
|
#ifdef HAVE_PULSE
|
||||||
#include <pulse/pulseaudio.h>
|
#include <pulse/pulseaudio.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -297,6 +301,20 @@ struct _Ecore_Audio_Callback {
|
||||||
|
|
||||||
extern Eina_List *ecore_audio_modules;
|
extern Eina_List *ecore_audio_modules;
|
||||||
|
|
||||||
|
#ifdef HAVE_ALSA
|
||||||
|
/* ecore_audio_alsa */
|
||||||
|
struct _Ecore_Audio_Alsa
|
||||||
|
{
|
||||||
|
ECORE_MAGIC;
|
||||||
|
snd_pcm_t *handle;
|
||||||
|
unsigned int channels;
|
||||||
|
unsigned int samplerate;
|
||||||
|
};
|
||||||
|
|
||||||
|
Ecore_Audio_Module *ecore_audio_alsa_init(void);
|
||||||
|
void ecore_audio_alsa_shutdown(void);
|
||||||
|
#endif /* HAVE_ALSA */
|
||||||
|
|
||||||
#ifdef HAVE_PULSE
|
#ifdef HAVE_PULSE
|
||||||
/* PA mainloop integration */
|
/* PA mainloop integration */
|
||||||
struct _Ecore_Audio_Pa_Private
|
struct _Ecore_Audio_Pa_Private
|
||||||
|
|
Loading…
Reference in New Issue