sim/sim_alsa: add audio offload capture support.
use host liblame as encoder. Signed-off-by: qiaohaijiao1 <qiaohaijiao1@xiaomi.com>
This commit is contained in:
parent
1faeba3f2d
commit
b6472b8b15
@ -204,6 +204,7 @@ ifeq ($(CONFIG_SIM_SOUND_ALSA),y)
|
|||||||
CSRCS += sim_offload.c
|
CSRCS += sim_offload.c
|
||||||
STDLIBS += -lasound
|
STDLIBS += -lasound
|
||||||
STDLIBS += -lmad
|
STDLIBS += -lmad
|
||||||
|
STDLIBS += -lmp3lame
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_SIM_VIDEO_V4L2),y)
|
ifeq ($(CONFIG_SIM_VIDEO_V4L2),y)
|
||||||
|
@ -675,13 +675,67 @@ static int sim_audio_process_playback(struct sim_audio_s *priv,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sim_audio_process_capture(struct sim_audio_s *priv,
|
||||||
|
struct ap_buffer_s *apb,
|
||||||
|
int expect, bool *dequeue)
|
||||||
|
{
|
||||||
|
struct ap_buffer_s *aux = priv->aux;
|
||||||
|
uint8_t *out = NULL;
|
||||||
|
uint32_t outsize;
|
||||||
|
int frames = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
frames = snd_pcm_readi(priv->pcm, apb->samp, expect);
|
||||||
|
if (frames < 0)
|
||||||
|
{
|
||||||
|
return frames;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = priv->ops->process(priv->codec, apb->samp,
|
||||||
|
frames * priv->frame_size, &out, &outsize);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pcm, process bypass */
|
||||||
|
|
||||||
|
if (out == apb->samp)
|
||||||
|
{
|
||||||
|
apb->nbytes = outsize;
|
||||||
|
*dequeue = true;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(aux->samp + aux->curbyte, out, outsize);
|
||||||
|
aux->curbyte += outsize;
|
||||||
|
|
||||||
|
if (aux->curbyte >= apb->nmaxbytes)
|
||||||
|
{
|
||||||
|
/* memcpy from aux to apb, and dequeue to apps */
|
||||||
|
|
||||||
|
memcpy(apb->samp, aux->samp, apb->nmaxbytes);
|
||||||
|
apb->nbytes = apb->nmaxbytes;
|
||||||
|
*dequeue = true;
|
||||||
|
|
||||||
|
/* memmove the remain data to beginning of aux */
|
||||||
|
|
||||||
|
memmove(aux->samp,
|
||||||
|
aux->samp + apb->nmaxbytes,
|
||||||
|
aux->curbyte - apb->nmaxbytes);
|
||||||
|
aux->curbyte -= apb->nmaxbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return frames * priv->frame_size;
|
||||||
|
}
|
||||||
|
|
||||||
static void sim_audio_process(struct sim_audio_s *priv)
|
static void sim_audio_process(struct sim_audio_s *priv)
|
||||||
{
|
{
|
||||||
snd_pcm_sframes_t expect;
|
snd_pcm_sframes_t expect;
|
||||||
struct ap_buffer_s *apb;
|
struct ap_buffer_s *apb;
|
||||||
snd_pcm_sframes_t avail;
|
snd_pcm_sframes_t avail;
|
||||||
bool dequeue = false;
|
bool dequeue = false;
|
||||||
uint32_t outsize;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!priv->pcm)
|
if (!priv->pcm)
|
||||||
@ -709,8 +763,7 @@ static void sim_audio_process(struct sim_audio_s *priv)
|
|||||||
avail = snd_pcm_avail(priv->pcm);
|
avail = snd_pcm_avail(priv->pcm);
|
||||||
if (avail < expect)
|
if (avail < expect)
|
||||||
{
|
{
|
||||||
ret = avail;
|
return;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->playback)
|
if (priv->playback)
|
||||||
@ -719,30 +772,20 @@ static void sim_audio_process(struct sim_audio_s *priv)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = snd_pcm_readi(priv->pcm, apb->samp, expect);
|
ret = sim_audio_process_capture(priv, apb, expect, &dequeue);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = priv->ops->process(priv->codec, apb->samp,
|
|
||||||
ret * priv->frame_size, &apb->samp, &outsize);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
apb->curbyte += ret;
|
|
||||||
dequeue = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dequeue)
|
if (dequeue)
|
||||||
{
|
{
|
||||||
bool final = false;
|
bool final = false;
|
||||||
|
|
||||||
dq_remfirst(&priv->pendq);
|
dq_remfirst(&priv->pendq);
|
||||||
|
|
||||||
apb->nbytes = apb->curbyte;
|
|
||||||
if (apb->flags & AUDIO_APB_FINAL)
|
if (apb->flags & AUDIO_APB_FINAL)
|
||||||
{
|
{
|
||||||
final = true;
|
final = true;
|
||||||
@ -761,6 +804,8 @@ static void sim_audio_process(struct sim_audio_s *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (ret == -EPIPE)
|
if (ret == -EPIPE)
|
||||||
{
|
{
|
||||||
@ -768,7 +813,7 @@ out:
|
|||||||
snd_pcm_prepare(priv->pcm);
|
snd_pcm_prepare(priv->pcm);
|
||||||
snd_pcm_start(priv->pcm);
|
snd_pcm_start(priv->pcm);
|
||||||
}
|
}
|
||||||
else if (ret < 0 && ret != -EAGAIN)
|
else if (ret != -EAGAIN)
|
||||||
{
|
{
|
||||||
aerr("pcm writei/readi failed %d, %s\n", ret, snd_strerror(ret));
|
aerr("pcm writei/readi failed %d, %s\n", ret, snd_strerror(ret));
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <lame/lame.h>
|
||||||
#include <mad.h>
|
#include <mad.h>
|
||||||
|
|
||||||
#include "sim_offload.h"
|
#include "sim_offload.h"
|
||||||
@ -33,19 +34,26 @@
|
|||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void *sim_audio_mp3_init(struct audio_info_s *info);
|
|
||||||
static int sim_audio_mp3_samples(void *handle);
|
|
||||||
static int sim_audio_mp3_decode(void *handle,
|
|
||||||
uint8_t *in, uint32_t insize,
|
|
||||||
uint8_t **out, uint32_t *outsize);
|
|
||||||
static void sim_audio_mp3_uninit(void *handle);
|
|
||||||
|
|
||||||
static void *sim_audio_pcm_init(struct audio_info_s *info);
|
static void *sim_audio_pcm_init(struct audio_info_s *info);
|
||||||
static int sim_audio_pcm_process(void *handle,
|
static int sim_audio_pcm_process(void *handle,
|
||||||
uint8_t *in, uint32_t insize,
|
uint8_t *in, uint32_t insize,
|
||||||
uint8_t **out, uint32_t *outsize);
|
uint8_t **out, uint32_t *outsize);
|
||||||
static void sim_audio_pcm_uninit(void *handle);
|
static void sim_audio_pcm_uninit(void *handle);
|
||||||
|
|
||||||
|
static void *sim_audio_mad_init(struct audio_info_s *info);
|
||||||
|
static int sim_audio_mad_samples(void *handle);
|
||||||
|
static int sim_audio_mad_decode(void *handle,
|
||||||
|
uint8_t *in, uint32_t insize,
|
||||||
|
uint8_t **out, uint32_t *outsize);
|
||||||
|
static void sim_audio_mad_uninit(void *handle);
|
||||||
|
|
||||||
|
static void *sim_audio_lame_init(struct audio_info_s *info);
|
||||||
|
static int sim_audio_lame_samples(void *handle);
|
||||||
|
static int sim_audio_lame_encode(void *handle,
|
||||||
|
uint8_t *in, uint32_t insize,
|
||||||
|
uint8_t **out, uint32_t *outsize);
|
||||||
|
static void sim_audio_lame_uninit(void *handle);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -63,10 +71,18 @@ const struct sim_codec_ops_s g_codec_ops[] =
|
|||||||
{
|
{
|
||||||
AUDIO_FMT_MP3,
|
AUDIO_FMT_MP3,
|
||||||
AUDCODEC_DEC,
|
AUDCODEC_DEC,
|
||||||
sim_audio_mp3_init,
|
sim_audio_mad_init,
|
||||||
sim_audio_mp3_samples,
|
sim_audio_mad_samples,
|
||||||
sim_audio_mp3_decode,
|
sim_audio_mad_decode,
|
||||||
sim_audio_mp3_uninit
|
sim_audio_mad_uninit
|
||||||
|
},
|
||||||
|
{
|
||||||
|
AUDIO_FMT_MP3,
|
||||||
|
AUDCODEC_ENC,
|
||||||
|
sim_audio_lame_init,
|
||||||
|
sim_audio_lame_samples,
|
||||||
|
sim_audio_lame_encode,
|
||||||
|
sim_audio_lame_uninit
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
AUDIO_FMT_UNDEF,
|
AUDIO_FMT_UNDEF,
|
||||||
@ -82,7 +98,12 @@ const struct sim_codec_ops_s g_codec_ops[] =
|
|||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
struct sim_decoder_mp3_s
|
struct sim_codec_pcm_s
|
||||||
|
{
|
||||||
|
uint32_t frame_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sim_mad_s
|
||||||
{
|
{
|
||||||
uint8_t *out;
|
uint8_t *out;
|
||||||
struct mad_stream stream;
|
struct mad_stream stream;
|
||||||
@ -90,21 +111,23 @@ struct sim_decoder_mp3_s
|
|||||||
struct mad_synth synth;
|
struct mad_synth synth;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sim_codec_pcm_s
|
struct sim_lame_s
|
||||||
{
|
{
|
||||||
uint32_t frame_size;
|
uint8_t *out;
|
||||||
|
uint32_t max;
|
||||||
|
lame_global_flags *gfp;
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static const uint16_t g_mpa_freq_tab[3] =
|
static const uint16_t g_mad_freq_tab[3] =
|
||||||
{
|
{
|
||||||
44100, 48000, 32000
|
44100, 48000, 32000
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t g_mpa_bitrate_tab[2][3][15] =
|
static const uint16_t g_mad_bitrate_tab[2][3][15] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@ -134,7 +157,27 @@ static const uint16_t g_mpa_bitrate_tab[2][3][15] =
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int sim_audio_mp3_scale(mad_fixed_t sample)
|
static void *sim_audio_pcm_init(struct audio_info_s *info)
|
||||||
|
{
|
||||||
|
return kmm_malloc(sizeof(struct sim_codec_pcm_s));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sim_audio_pcm_process(void *handle,
|
||||||
|
uint8_t *in, uint32_t insize,
|
||||||
|
uint8_t **out, uint32_t *outsize)
|
||||||
|
{
|
||||||
|
*out = in;
|
||||||
|
*outsize = insize;
|
||||||
|
|
||||||
|
return *outsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sim_audio_pcm_uninit(void *handle)
|
||||||
|
{
|
||||||
|
kmm_free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sim_mad_scale(mad_fixed_t sample)
|
||||||
{
|
{
|
||||||
sample += 1L << (MAD_F_FRACBITS - 16);
|
sample += 1L << (MAD_F_FRACBITS - 16);
|
||||||
|
|
||||||
@ -150,7 +193,7 @@ static int sim_audio_mp3_scale(mad_fixed_t sample)
|
|||||||
return sample >> (MAD_F_FRACBITS + 1 - 16);
|
return sample >> (MAD_F_FRACBITS + 1 - 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sim_audio_check_mpeg(uint32_t header)
|
static int sim_mad_check_mpeg(uint32_t header)
|
||||||
{
|
{
|
||||||
/* header */
|
/* header */
|
||||||
|
|
||||||
@ -190,7 +233,7 @@ static int sim_audio_check_mpeg(uint32_t header)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sim_audio_mp3_check(uint32_t header)
|
static int sim_mad_check(uint32_t header)
|
||||||
{
|
{
|
||||||
int sample_rate;
|
int sample_rate;
|
||||||
int frame_size;
|
int frame_size;
|
||||||
@ -202,7 +245,7 @@ static int sim_audio_mp3_check(uint32_t header)
|
|||||||
int lsf;
|
int lsf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = sim_audio_check_mpeg(header);
|
ret = sim_mad_check_mpeg(header);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
return ret;
|
return ret;
|
||||||
@ -224,17 +267,17 @@ static int sim_audio_mp3_check(uint32_t header)
|
|||||||
sr_idx = (header >> 10) & 3;
|
sr_idx = (header >> 10) & 3;
|
||||||
padding = (header >> 9) & 1;
|
padding = (header >> 9) & 1;
|
||||||
|
|
||||||
if (sr_idx >= sizeof(g_mpa_freq_tab) / sizeof(g_mpa_freq_tab[0]) ||
|
if (sr_idx >= sizeof(g_mad_freq_tab) / sizeof(g_mad_freq_tab[0]) ||
|
||||||
br_idx >= 0xf)
|
br_idx >= 0xf)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sample_rate = g_mpa_freq_tab[sr_idx] >> (lsf + mpeg25);
|
sample_rate = g_mad_freq_tab[sr_idx] >> (lsf + mpeg25);
|
||||||
|
|
||||||
if (br_idx != 0)
|
if (br_idx != 0)
|
||||||
{
|
{
|
||||||
frame_size = g_mpa_bitrate_tab[lsf][layer - 1][br_idx];
|
frame_size = g_mad_bitrate_tab[lsf][layer - 1][br_idx];
|
||||||
|
|
||||||
switch (layer)
|
switch (layer)
|
||||||
{
|
{
|
||||||
@ -265,12 +308,12 @@ static int sim_audio_mp3_check(uint32_t header)
|
|||||||
return frame_size;
|
return frame_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *sim_audio_mp3_init(struct audio_info_s *info)
|
static void *sim_audio_mad_init(struct audio_info_s *info)
|
||||||
{
|
{
|
||||||
struct sim_decoder_mp3_s *codec;
|
struct sim_mad_s *codec;
|
||||||
|
|
||||||
codec = kmm_malloc(sizeof(struct sim_decoder_mp3_s));
|
codec = kmm_malloc(sizeof(struct sim_mad_s));
|
||||||
if (codec == NULL)
|
if (!codec)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -280,7 +323,7 @@ static void *sim_audio_mp3_init(struct audio_info_s *info)
|
|||||||
mad_synth_init(&codec->synth);
|
mad_synth_init(&codec->synth);
|
||||||
|
|
||||||
codec->out = kmm_malloc(sizeof(codec->synth.pcm.samples));
|
codec->out = kmm_malloc(sizeof(codec->synth.pcm.samples));
|
||||||
if (codec->out == NULL)
|
if (!codec->out)
|
||||||
{
|
{
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -296,24 +339,24 @@ out:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sim_audio_mp3_samples(void *handle)
|
static int sim_audio_mad_samples(void *handle)
|
||||||
{
|
{
|
||||||
struct sim_decoder_mp3_s *codec = (struct sim_decoder_mp3_s *)handle;
|
struct sim_mad_s *codec = (struct sim_mad_s *)handle;
|
||||||
|
|
||||||
return sizeof(codec->synth.pcm.samples[0]) / sizeof(mad_fixed_t);
|
return sizeof(codec->synth.pcm.samples[0]) / sizeof(mad_fixed_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sim_audio_mp3_decode(void *handle,
|
static int sim_audio_mad_decode(void *handle,
|
||||||
uint8_t *in, uint32_t insize,
|
uint8_t *in, uint32_t insize,
|
||||||
uint8_t **out, uint32_t *outsize)
|
uint8_t **out, uint32_t *outsize)
|
||||||
{
|
{
|
||||||
struct sim_decoder_mp3_s *codec = (struct sim_decoder_mp3_s *)handle;
|
struct sim_mad_s *codec = (struct sim_mad_s *)handle;
|
||||||
const mad_fixed_t *right_ch;
|
const mad_fixed_t *right_ch;
|
||||||
const mad_fixed_t *left_ch;
|
const mad_fixed_t *left_ch;
|
||||||
int mpa_header;
|
|
||||||
int nchannels;
|
int nchannels;
|
||||||
int nsamples;
|
int nsamples;
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
|
int header;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int size;
|
int size;
|
||||||
int ret;
|
int ret;
|
||||||
@ -323,11 +366,11 @@ static int sim_audio_mp3_decode(void *handle,
|
|||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpa_header = in[0] << 24 | in[1] << 16 | in[2] << 8 | in[3];
|
header = in[0] << 24 | in[1] << 16 | in[2] << 8 | in[3];
|
||||||
size = sim_audio_mp3_check(mpa_header);
|
size = sim_mad_check(header);
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insize < size + 8)
|
if (insize < size + 8)
|
||||||
@ -357,13 +400,13 @@ static int sim_audio_mp3_decode(void *handle,
|
|||||||
|
|
||||||
/* output sample(s) in 16-bit signed little-endian PCM */
|
/* output sample(s) in 16-bit signed little-endian PCM */
|
||||||
|
|
||||||
sample = sim_audio_mp3_scale(*left_ch++);
|
sample = sim_mad_scale(*left_ch++);
|
||||||
ptr[i] = (sample >> 0) & 0xff;
|
ptr[i] = (sample >> 0) & 0xff;
|
||||||
ptr[i + 1] = (sample >> 8) & 0xff;
|
ptr[i + 1] = (sample >> 8) & 0xff;
|
||||||
|
|
||||||
if (nchannels == 2)
|
if (nchannels == 2)
|
||||||
{
|
{
|
||||||
sample = sim_audio_mp3_scale(*right_ch++);
|
sample = sim_mad_scale(*right_ch++);
|
||||||
ptr[i + 2] = (sample >> 0) & 0xff;
|
ptr[i + 2] = (sample >> 0) & 0xff;
|
||||||
ptr[i + 3] = (sample >> 8) & 0xff;
|
ptr[i + 3] = (sample >> 8) & 0xff;
|
||||||
}
|
}
|
||||||
@ -377,9 +420,9 @@ static int sim_audio_mp3_decode(void *handle,
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sim_audio_mp3_uninit(void *handle)
|
static void sim_audio_mad_uninit(void *handle)
|
||||||
{
|
{
|
||||||
struct sim_decoder_mp3_s *codec = (struct sim_decoder_mp3_s *)handle;
|
struct sim_mad_s *codec = (struct sim_mad_s *)handle;
|
||||||
|
|
||||||
mad_synth_finish(&(codec->synth));
|
mad_synth_finish(&(codec->synth));
|
||||||
mad_frame_finish(&(codec->frame));
|
mad_frame_finish(&(codec->frame));
|
||||||
@ -389,22 +432,101 @@ static void sim_audio_mp3_uninit(void *handle)
|
|||||||
kmm_free(codec);
|
kmm_free(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *sim_audio_pcm_init(struct audio_info_s *info)
|
void *sim_audio_lame_init(struct audio_info_s *info)
|
||||||
{
|
{
|
||||||
return kmm_malloc(sizeof(struct sim_codec_pcm_s));
|
struct sim_lame_s *codec;
|
||||||
|
int samples;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
codec = kmm_zalloc(sizeof(struct sim_lame_s));
|
||||||
|
if (codec == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
codec->gfp = lame_init();
|
||||||
|
if (codec->gfp == NULL)
|
||||||
|
{
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
lame_set_num_channels(codec->gfp, info->channels);
|
||||||
|
lame_set_mode(codec->gfp, info->channels > 1 ? STEREO : MONO);
|
||||||
|
|
||||||
|
lame_set_in_samplerate (codec->gfp, info->samplerate);
|
||||||
|
lame_set_out_samplerate(codec->gfp, info->samplerate);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = lame_init_params(codec->gfp);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
samples = lame_get_framesize(codec->gfp);
|
||||||
|
codec->max = samples + samples / 4 + 7200;
|
||||||
|
|
||||||
|
codec->out = kmm_malloc(codec->max);
|
||||||
|
if (codec->out == NULL)
|
||||||
|
{
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return codec;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (codec->gfp)
|
||||||
|
{
|
||||||
|
lame_close(codec->gfp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codec->out)
|
||||||
|
{
|
||||||
|
kmm_free(codec->out);
|
||||||
|
}
|
||||||
|
|
||||||
|
kmm_free(codec);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sim_audio_pcm_process(void *handle,
|
static int sim_audio_lame_samples(void *handle)
|
||||||
|
{
|
||||||
|
struct sim_lame_s *codec = (struct sim_lame_s *)handle;
|
||||||
|
|
||||||
|
return lame_get_framesize(codec->gfp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sim_audio_lame_encode(void *handle,
|
||||||
uint8_t *in, uint32_t insize,
|
uint8_t *in, uint32_t insize,
|
||||||
uint8_t **out, uint32_t *outsize)
|
uint8_t **out, uint32_t *outsize)
|
||||||
{
|
{
|
||||||
*out = in;
|
struct sim_lame_s *codec = (struct sim_lame_s *)handle;
|
||||||
*outsize = insize;
|
int samples;
|
||||||
|
int ret;
|
||||||
|
int chs;
|
||||||
|
|
||||||
return *outsize;
|
chs = lame_get_num_channels(codec->gfp);
|
||||||
|
samples = insize / (sizeof(short int) * chs);
|
||||||
|
|
||||||
|
ret = lame_encode_buffer_interleaved(codec->gfp, (short int *)in, samples,
|
||||||
|
codec->out, codec->max);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = codec->out;
|
||||||
|
*outsize = ret;
|
||||||
|
return insize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sim_audio_pcm_uninit(void *handle)
|
static void sim_audio_lame_uninit(void *handle)
|
||||||
{
|
{
|
||||||
kmm_free(handle);
|
struct sim_lame_s *codec = (struct sim_lame_s *)handle;
|
||||||
|
|
||||||
|
kmm_free(codec->out);
|
||||||
|
lame_close(codec->gfp);
|
||||||
|
kmm_free(codec);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user