基于Linux的internet收音机的
实现
王辉
www.farsight.com.cn
www.farsight.com.cn2
版权版权
} 华清远见嵌入式
中心版权所有;
} 未经华清远见明确许可,不能为任何目的以任何形式复制
或传播此文档的任何部分;
} 本文档包含的信息如有更改,恕不另行通知;
} 保留所有权利。
今日内容大纲
} Internet Radio功能简介
} Linux应用层Mplayer简介
} Mplayer的输入-Keypad driver
} Mplayer的声音输出-sound driver
www.farsight.com.cn
Internet Radio功能简介
} 也叫IP Radio,可以实时收听网络电
台
} rtsp://211.167.134.41/broadcast/live3
} mms://211.89.225.101/live3
} http://www.stv.sh.cn/1422.asx
www.farsight.com.cn
Internet Radio功能要点
} 网络功能
} Ethernet、WiFi网络层
} TCP/IP
} rtsp、mms、http
} upnp
} DHCP client
} 多媒体功能
} 立体声声音输出
} Line Out、Line In
} MP3、WMA、RA(Real
Audio)解码功能
} 时钟功能
} 实时时钟RTC
} 网络时钟同步NTP
} 存储功能
} SD卡播放
} U盘播放
} SD卡升级
} 用户交互界面
} 按键
} 红外遥控器
} GUI界面
www.farsight.com.cn
Internet Radio硬件框图
www.farsight.com.cn
Internent Radio软件结构
www.farsight.com.cn
Mplayer概述
} 网站http://www.mplayerhq.hu/
} 其遵守GPLv2许可证
} 支持本地播放、网络数据流获取
} HTTP/FTP
} RTP/RTSP
} MMS/MMST
} 支持常见视频、音频格式的编解码
} MPEG layer 1, 2, and 3 (MP3) audio
} WMA (DivX Audio) v1, v2
} WMA 9 (WMAv3)(using x86 DLLs)
} RealAudio: COOK, SIPRO, ATRAC3 (using Real libraries)
} RealAudio: DNET and older codecs
} 支持多种音频设备、输入设备
} OSS (Open Sound System) - factory standard under UNIX
} ALSA (Advanced Linux Sound Architecture) 0.5/0.9/1.0 for Linux
} Keyboard、mouse、joystick
www.farsight.com.cn
Mplayer输入及控制
} Mplayer中输入机制读键值-》解析绑定命令-》调
用命令
code = ((mp_key_func_t)key_fds[i].read_func)(key_fds[i].fd);
if (code >= 0) {
mp_cmd_t *ret = interpret_key(code, paused);
if (ret)
return ret;
}
} 向Mplayer注册输入设别:
int fd = mp_input_keypad_init(keypadname);
mp_input_add_key_fd(fd,1,mp_input_keypad_read,(mp_close
_func_t)close);
} 键值与命令的绑定:
{ { KEY_RIGHT, 0 }, "seek 10" },
{ { KEY_LEFT, 0 }, "seek -10" },
{ { KEY_UP, 0 }, "seek 60" },
{ { KEY_DOWN, 0 }, "seek -60" }, Linux kernel keypad driver
设备节点/dev/input/event0
Mplayer input layer($(src)/input)
Open/select/
read/close
Interpret
key and call
cmd proc
Mplayer cmd process
Bind key to
cmd
www.farsight.com.cn
Linux内核input子系统
www.farsight.com.cn
Linux内核keypad驱动
} 键盘注册:
struct input_dev *input_allocate_device(void);
int __must_check input_register_device(struct input_dev *);
struct input_dev {
const char *name;
unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
unsigned int keycodemax;
unsigned int keycodesize;
void *keycode;
};
} 获取按键信息:
打开 press down 中断;
按键,进入中断,判断某键按下 stat=firstpress;
防止毛刺,关闭中断打开kernel timer;
在timer中根据按键状态及上一次stat 状态,如 stat 为firstpress
并且新状态为按下,则确认某键按下, 向input core传递键值
void input_report_key(struct input_dev *dev, unsigned int code, int value);
或 input_event(dev, EV_KEY, code, !!value);
www.farsight.com.cn
Mplayer音频输出
} Mplayer中音频输出机制获取音频输出设备-》调用设备接口-
》控制音频设备、写出声音数据
mpctx->audio_out=init_best_audio_out(audio_driver_list, 0, // plugin
flag ao_data.samplerate, ao_data.channels,
ao_data.format,0)
} 调用音频设备接口:
mpctx->audio_out->play(sh_audio->a_out_buffer, playsize, playflags);
} 实现mplayer音频设备
typedef struct ao_functions_s{
ao_info_t *info;
int (*control)(int cmd,void *arg);
int (*init)(int rate,int channels,int format,int flags);
void (*uninit)(int immed);
void (*reset)(void);
int (*get_space)(void);
int (*play)(void* data,int len,int flags);
float (*get_delay)(void);
void (*pause)(void);
void (*resume)(void);
} ao_functions_t;
Linux kernel sound driver
ALSA节点
/dev/snd/pcmc0d0
/dev/snd/controlc0d0
Mplayer ao layer($(src)/libao2)
Open/select/
read/close
Mplayer audio process
OSS节点
/dev/dsp
/dev/mixer
ALSA-lib
ALSA API
typedef struct ao_functions_s
{
ao_info_t *info;
int (*control)(int cmd,void *arg);
int (*init)(int rate,int channels,int
format,int flags);
void (*uninit)(int immed);
void (*reset)(void);
int (*get_space)(void);
int (*play)(void* data,int len,int
flags);
float (*get_delay)(void);
void (*pause)(void);
void (*resume)(void);
} ao_functions_t;
CALL
ao_functions
www.farsight.com.cn
Linux内核sound驱动(ALSA)
} CARD:
struct snd_card *snd_card_new(int idx, const char *id,
struct module *module, int extra_size);
int snd_card_register(struct snd_card *card);
} PCM device:
int snd_pcm_new(struct snd_card *card, const char *id, int
device, int playback_count, int capture_count, struct
snd_pcm **rpcm);
void snd_pcm_set_ops(struct snd_pcm * pcm, int
direction, struct snd_pcm_ops *ops);
} Control:
struct snd_kcontrol *snd_ctl_new1(const struct
snd_kcontrol_new * kcontrolnew, void * private_data);
int snd_ctl_add(struct snd_card * card, struct snd_kcontrol *
kcontrol);
Sound card 0
Device0 Device1
pcm0
control
...
...
...
plb0 cap0 ...
www.farsight.com.cn
www.farsight.com.cn14
Q&A
www.farsight.com.cn15