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:
Daniel Willmann 2012-12-14 23:38:21 +00:00 committed by Daniel Willmann
parent d49fe90b18
commit eb15fa9e9c
3 changed files with 200 additions and 0 deletions

View File

@ -76,6 +76,11 @@ ecore_audio_init(void)
ECORE_AUDIO_OUTPUT_INPUT_ADDED = 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
mod = ecore_audio_pulse_init();
if (mod)
@ -107,6 +112,9 @@ ecore_audio_shutdown(void)
/* FIXME: Shutdown all the inputs and outputs first */
#ifdef HAVE_ALSA
ecore_audio_alsa_shutdown();
#endif
#ifdef HAVE_PULSE
ecore_audio_pulse_shutdown();
#endif

View File

@ -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 */

View File

@ -9,6 +9,10 @@
#include <config.h>
#endif
#ifdef HAVE_ALSA
#include <alsa/asoundlib.h>
#endif
#ifdef HAVE_PULSE
#include <pulse/pulseaudio.h>
#endif
@ -297,6 +301,20 @@ struct _Ecore_Audio_Callback {
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
/* PA mainloop integration */
struct _Ecore_Audio_Pa_Private