当前位置:文档之家› 基于 libmad 的简单 MP3 流媒体播放器的实现

基于 libmad 的简单 MP3 流媒体播放器的实现

基于 libmad 的简单 MP3 流媒体播放器的实现
基于 libmad 的简单 MP3 流媒体播放器的实现

本文在 Fedora 5 Linux 下实现了一个基于 libmad 的 MP3 流媒体播放器。此流媒体播放器可以播放基于 HTTP 1.1 协议传输的 MP3 流媒体数据。

基本原理是:从 HTTP 服务器获得 MP3 媒体信息,然后通过网络传输把 MP3 数据以数据流的形式接收到 MP3 流媒体播放器客户端,由客户端通过 libmad 解码 MP3 数据流,得到 PCM 音频数据,写入音频设备,播放音乐。本文的流媒体播放器只是实现了必要的简单功能,没有考虑太多情况。比如,没有考虑实时播放控制,这样的话就不能随意选取播放点进行播放。

本文的 MP3 流媒体播放器创建两个线程,使用两个缓冲区保存 MP3 数据,可以一边下载数据,一边播放音乐。编译运行此 MP3 流媒体播放器需要安装 libmad (https://www.doczj.com/doc/db8874371.html,/products/mad/) 以及 ALSA(Advanced Linux Sound Architecture) (https://www.doczj.com/doc/db8874371.html,)相关的软件。ALSA包括4部分,分别是 sound driver, sound library , sound utilities 以及 tools。至少应该安装 sound driver, sound library 。编译程序时连接库的选项是:-lmad -lasound -lpthread。

本文的 MP3 流媒体播放器使用双缓冲区,一个是数据接收缓冲区,另一个是数据解码缓冲区。主程序结构如下图所示,图中的蓝色线表示数据流向。

图 1:MP3 流媒体播放器主程序结构图

2.libmad简介

MAD(libmad)是一个开源的高精度 MPEG 音频解码库,支持 MPEG-1(Layer I, Layer II 和 LayerIII(也就是 MP3)。LIBMAD 提供 24-bit 的 PCM 输出,完全是定点计算,非常适合没有浮点支持的平台上使用。使用 libmad 提供的一系列 API,就可以非常简单地实现 MP3 数据解码工作。在 libmad 的源代码文件目录下的 mad.h 文件中,可以看到绝大部分该库的数据结构和 API 等。

本文用到的 libmad 中的主要数据结构有:struct mad_stream, struct

mad_synth, struct mad_frame。它们的定义如下:

清单 1:libmad 中的主要数据结构

struct mad_stream {

unsigned char const *buffer; /* input bitstream buffer */

unsigned char const *bufend; /* end of buffer */

unsigned long skiplen; /* bytes to skip before next frame */

int sync; /* stream sync found */

unsigned long freerate; /* free bitrate (fixed) */

unsigned char const *this_frame; /* start of current frame */

unsigned char const *next_frame; /* start of next frame */

struct mad_bitptr ptr; /* current processing bit pointer */

struct mad_bitptr anc_ptr; /* ancillary bits pointer */

unsigned int anc_bitlen; /* number of ancillary bits */

unsigned char (*main_data)[MAD_BUFFER_MDLEN];

/* Layer III main_data() */

unsigned int md_len; /* bytes in main_data */

int options; /* decoding options (see below) */

enum mad_error error; /* error code (see above) */

};

如果缓冲区最后一个 MPEG 数据帧只有部分数据包括在缓冲区中,那么 struct mad_stream 中的 next_frame 域指到不完整数据的开始地址。由于缓冲区的MPEG 数据帧不一定完整,所以不完整的 MPEG 帧的数据必须拷贝到下一次解码操作的缓冲区中,进行再次解码。这里我们还看到 bufend 指向缓冲区数据的最后地址,也就是最后一字节的地址加 1 的位置。mad_stream.bufend –

mad_stream.next_frame 就是剩余的未被解码的 MPEG 帧的数据的字节数量(假设此帧在缓冲区中不完整)。mad_stream 的 error 域用来记录操作 mad_stream 得到的错误代码。错误代码在 mad.h 中有很详细的定义。

清单 2:错误代码在 mad.h 中的详细定义

struct mad_synth {

mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ /* [ch][eo][peo][s][v] */

unsigned int phase; /* current processing phase */

struct mad_pcm pcm; /* PCM output */

};

mad_synth 中的关键域 pcm 保存解码和合成后得到的 PCM 数据。

清单 3:mad_synth 中的关键域

struct mad_pcm {

unsigned int samplerate; /* sampling frequency (Hz) */

unsigned short channels; /* number of channels */

unsigned short length; /* number of samples per channel */ mad_fixed_t samples[2][1152]; /* PCM output samples [ch][sample] */ };

struct mad_pcm 定义了音频的采样率、每个声道个数以及最后的 PCM 采样数据。这些参数可用来初始化音频设备。

清单 4:struct mad_pcm

struct mad_frame {

struct mad_header header; /* MPEG audio header */

int options; /* decoding options (from stream) */

mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */

mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */

};

mad_frame 是记录 MPEG 帧解码后的数据的数据结构,其中的 mad_header 尤其重要,其用来记录 MPEG 帧的一些基本信息,比如 MPEG 层数、声道模式、流比特率、采样比特率等等。声道模式包括单声道、双声道、联合立体混音声以及一般立体声。

清单 5:mad_frame

enum mad_mode {

MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */

MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */

MAD_MODE_JOINT_STEREO = 2, /* joint

(MS/intensity) stereo */

MAD_MODE_STEREO = 3 /* normal LR stereo */ };

struct mad_header {

enum mad_layer layer; /* audio layer (1, 2, or 3) */

enum mad_mode mode; /* channel mode */

int mode_extension; /* additional mode info */

enum mad_emphasis emphasis; /* de-emphasis to use */

unsigned long bitrate; /* stream bitrate (bps) */

unsigned int samplerate; /* sampling frequency (Hz) */

unsigned short crc_check; /* frame CRC accumulator */

unsigned short crc_target; /* final target CRC checksum */

int flags; /* flags */

int private_bits; /* private bits */

mad_timer_t duration; /* audio playing time of frame */ };

下面就本文使用的 API 的功能做简单介绍。

在本文中用到的 API 包括:

void mad_stream_init(struct mad_stream *)

void mad_synth_init(struct mad_synth *);

void mad_frame_init(struct mad_frame *);

以上3个 API 初始化解码需要的数据结构。

void mad_stream_buffer(struct mad_stream *, unsigned char const *, unsigned long);

此函数把原始的未解码的 MPEG 数据和 mad_stream 数据结构关联,以便使用mad_frame_decode( ) 来解码 MPEG 帧数据。

int mad_frame_decode(struct mad_frame *, struct mad_stream *);

把 mad_stream 中的 MPEG 帧数据解码。

void mad_synth_frame(struct mad_synth *, struct mad_frame const *); 把解码后的音频数据合成 PCM 采样。

void mad_stream_finish(struct mad_stream *);

void mad_frame_finish(struct mad_frame *);

mad_synth_finish(struct mad_synth);

以上 3 个 API 在解码完毕后使用,释放 libmad 占用的资源等。

回页首

3.PCM 音频设备的操作

对音频设备的操作主要是初始化音频设备以及往音频设备发送 PCM(Pulse Code Modulation)数据。为了方便,本文使用 ALSA(Advanced Linux Sound Architecture)提供的库和驱动。在编译和运行本文中的 MP3 流媒体播放器的时候,必须先安装 ALSA 相关的文件。

本文用到的主要对 PCM 设备操作的函数分为 PCM 设备初始化的函数以及 PCM 接口的一些操作函数。

PCM 硬件设备参数设置和初始化的函数有:

int snd_pcm_hw_params_malloc (snd_pcm_hw_params_t **ptr)

int snd_pcm_hw_params_any (snd_pcm_t *pcm, snd_pcm_hw_params_t

*params)

void snd_pcm_hw_params_free (snd_pcm_hw_params_t *obj)

int snd_pcm_hw_params_set_access ( snd_pcm_t *pcm,

snd_pcm_hw_params_t *params,

snd_pcm_access_t _access)

int snd_pcm_hw_params_set_format ( snd_pcm_t *pcm,

snd_pcm_hw_params_t *params,

snd_pcm_format_t val)

int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm,

snd_pcm_hw_params_t *params,

unsigned int val)

int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm,

snd_pcm_hw_params_t *params,

unsigned int *val, int *dir)

PCM 接口的操作函数:

int snd_pcm_hw_params (snd_pcm_t *pcm, snd_pcm_hw_params_t *params) int snd_pcm_prepare (snd_pcm_t *pcm)

int snd_pcm_open (snd_pcm_t **pcm, const char *name,

snd_pcm_stream_t stream, int mode)

int snd_pcm_close (snd_pcm_t *pcm)

snd_pcm_sframes_t snd_pcm_writei (snd_pcm_t *pcm,

const void *buffer, snd_pcm_uframes_t size)

这些函数用到了 snd_pcm_hw_params_t 结构,此结构包含用来播放 PCM 数据流的硬件信息配置。在往音频设备(声卡)写入音频数据之前,必须设置访问类型、采样格式、采样率、声道数等。

首先使用 snd_pcm_open () 打开 PCM 设备,在 ALSA 中,PCM 设备都有名字与之对应。比如我们可以定义 PCM 设备名字为 char *pcm_name = "plughw:0,0"。最重要的 PCM 设备接口是“plughw”以及“hw”接口。使用“plughw”接口,程序员不必过多关心硬件,而且如果设置的配置参数和实际硬件支持的参数不一致,ALSA 会自动转换数据。如果使用“hw”接口,我们就必须检测硬件是否支持设置的参数了。Plughw 后面的两个数字分别表示设备号和次设备(subdevice)号。

snd_pcm_hw_params_malloc( ) 在栈中分配 snd_pcm_hw_params_t 结构的空间,然后使用 snd_pcm_hw_params_any( ) 函数用声卡的全配置空间参数初始化已

经分配的 snd_pcm_hw_params_t 结构。snd_pcm_hw_params_set_access ( ) 设置访问类型,常用访问类型的宏定义有:

SND_PCM_ACCESS_RW_INTERLEAVED

交错访问。在缓冲区的每个 PCM 帧都包含所有设置的声道的连续的采样数据。比如声卡要播放采样长度是 16-bit 的 PCM 立体声数据,表示每个 PCM 帧中有16-bit 的左声道数据,然后是 16-bit 右声道数据。

SND_PCM_ACCESS_RW_NONINTERLEAVED

非交错访问。每个 PCM 帧只是一个声道需要的数据,如果使用多个声道,那么第一帧是第一个声道的数据,第二帧是第二个声道的数据,依此类推。

函数 snd_pcm_hw_params_set_format() 设置数据格式,主要控制输入的音频数据的类型、无符号还是有符号、是 little-endian 还是 bit-endian。比如对于16-bit 长度的采样数据可以设置为:

SND_PCM_FORMAT_S16_LE 有符号16 bit Little Endian

SND_PCM_FORMAT_S16_BE 有符号16 bit Big Endian

SND_PCM_FORMAT_U16_LE 无符号16 bit Little Endian

SND_PCM_FORMAT_U16_BE 无符号 16 bit Big Endian

比如对于 32-bit 长度的采样数据可以设置为:

SND_PCM_FORMAT_S32_LE 有符号32 bit Little Endian

SND_PCM_FORMAT_S32_BE 有符号32 bit Big Endian

SND_PCM_FORMAT_U32_LE 无符号32 bit Little Endian

SND_PCM_FORMAT_U32_BE 无符号 32 bit Big Endian

函数 snd_pcm_hw_params_set_channels() 设置音频设备的声道,常见的就是单声道和立体声,如果是立体声,设置最后一个参数为2。

snd_pcm_hw_params_set_rate_near () 函数设置音频数据的最接近目标的采样率。snd_pcm_hw_params( ) 从设备配置空间选择一个配置,让函数

snd_pcm_prepare() 准备好 PCM 设备,以便写入 PCM 数据。snd_pcm_writei() 用来把交错的音频数据写入到音频设备。

初始化 PCM 设备的例程如下:

清单 6:初始化 PCM 设备的例程

/* open a PCM device */

int open_device(struct mad_header const *header)

{

int err;

snd_pcm_hw_params_t *hw_params;

char *pcm_name = "plughw:0,0";

int rate = header->samplerate;

int channels = 2;

if (header->mode == 0) {

channels = 1;

} else {

channels = 2;

}

if ((err = snd_pcm_open (&playback_handle,

pcm_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {

printf("cannot open audio device %s (%s)\n",

pcm_name,

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {

printf("cannot allocate hardware parameter structure (%s)\n",

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {

printf("cannot initialize hardware parameter structure (%s)\n", snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {

printf("cannot set access type (%s)\n",

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params_set_format (playback_handle,

hw_params, SND_PCM_FORMAT_S32_LE)) < 0) {

printf("cannot set sample format (%s)\n",

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params_set_rate_near (playback_handle,

hw_params, &rate, 0)) < 0) {

printf("cannot set sample rate (%s)\n",

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params_set_channels (playback_handle,

hw_params, channels)) < 0) {

printf("cannot set channel count (%s)\n",

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params (playback_handle,

hw_params)) < 0) {

printf("cannot set parameters (%s)\n",

snd_strerror (err));

return -1;

}

snd_pcm_hw_params_free (hw_params);

if ((err = snd_pcm_prepare (playback_handle)) < 0) {

printf("cannot prepare audio interface for use (%s)\n",

snd_strerror (err));

return -1;

}

return 0;

}

这里配置的 PCM 格式是 SND_PCM_FORMAT_S32_LE,采样的格式是每个采样有

32-bit 的数据,数据按照 little-endian 存放。如果通过 mad_frame_decode() 函数得到 PCM 数据后,要求每个采样数据只占 16-bit,需要把数据进行MAD

的定点类型到 signed short 类型进行转换。那么,PCM 数据如何写入声卡中呢?函数实现例程如下所示:

清单 7:PCM 数据写入声卡函数实现例程

while (nsamples--) {

/* nsamples 是采样的数目 */

signed int sample;

sample = pcm->samples[0][j];

*(OutputPtr++) = sample & 0xff;

*(OutputPtr++) = (sample >> 8);

*(OutputPtr++) = (sample >> 16);

*(OutputPtr++) = (sample >> 24);

if (nchannels == 2) {

sample = pcm->samples[1][j];

*(OutputPtr++) = sample & 0xff;

*(OutputPtr++) = sample >> 8;

*(OutputPtr++) = (sample >> 16);

*(OutputPtr++) = (sample >> 24);

}

j++;

}

if ((err = snd_pcm_writei (playback_handle, buf, samples)) < 0) {

err = xrun_recovery(playback_handle, err);

if (err < 0) {

printf("Write error: %s\n", snd_strerror(err));

return -1;

}

}

这里用到了https://www.doczj.com/doc/db8874371.html,/关于 ALSA 文档中的例子函数

xrun_recovery( )。详细例子请参见

https://www.doczj.com/doc/db8874371.html,/alsa-doc/alsa-lib/_2test_2pcm_8c-example. html。使用此函数的目的是避免出现由于网络原因,声卡不能及时得到音频数据而使得 snd_pcm_writei() 不能正常连续工作。实际上在 xrun_recovery( ) 中,又调用 snd_pcm_prepare() 和 snd_pcm_resume() 以实现能“恢复错误”的功能。-EPIPE 错误表示应用程序没有及时把 PCM 采样数据送入ASLA 库。

xrun_recovery() 函数如下所示:

清单 8:xrun_recovery() 函数

int xrun_recovery(snd_pcm_t *handle, int err)

{

if (err == -EPIPE) { /* under-run */

err = snd_pcm_prepare(handle);

if (err < 0)

printf("Can't recovery from underrun, prepare failed: %s\n",

snd_strerror(err));

return 0;

} else if (err == -ESTRPIPE) {

while ((err = snd_pcm_resume(handle)) == -EAGAIN)

sleep(1); /* wait until the suspend flag is released */ if (err < 0) {

err = snd_pcm_prepare(handle);

if (err < 0)

printf("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err));

}

return 0;

}

return err;

}

知道了具体的音频设备操作方法,就该使用 MAD 提供的函数具体实现解码了。函数 mp3_decode_buf( ) 提供了使用 libmad 解码的方法。首先调用

mad_stream_buffer() 函数把 MP3 流数据和 decode_stream 关联,然后开始循环解码数据。如果在解码数据过程中,有不完整 PCM 数据帧,那么

decode_stream.error 的值就是 MAD_ERROR_BUFLEN,且

decode_stream.next_frame 不为 NULL。这时候,把剩余的未解码的数据再拷贝到数据解码缓冲区里。 mad_frame_decode( ) 函数从 decode_stream 中得到PCM 数据。

清单 9:mad_frame_decode( ) 函数从 decode_stream 中得到 PCM 数据

int mp3_decode_buf(char *input_buf, int size)

{

int decode_over_flag = 0;

int remain_bytes = 0;

int ret_val = 0;

mad_stream_buffer(&decode_stream, input_buf, size);

decode_stream.error = MAD_ERROR_NONE;

while (1)

{

if (decode_stream.error == MAD_ERROR_BUFLEN) {

if (decode_stream.next_frame != NULL) {

remain_bytes = decode_stream.bufend -

decode_stream.next_frame;

memcpy(input_buf, decode_stream.next_frame, remain_bytes); return remain_bytes;

}

}

ret_val = mad_frame_decode(&decode_frame, &decode_stream);

/* 省略部分代码 */

...

if (ret_val == 0) {

if (play_frame(&decode_frame) == -1) {

return -1;

}

}

/* 后面代码省略 */

...

}

return 0;

}

回页首

4.创建线程

本文使用 POSIX 线程库(pthreads)来创建线程。比如,本文需要两个线程,一个是数据接收线程,另一个是音乐播放线程。创建线程的程序如下所示:

清单 10:创建线程

ret_val = pthread_create(&thread[0],

NULL,

get_http_content,

&read_val);

if (ret_val != 0) {

printf("Cannot create get_http_content thread!\n");

return 1;

}

ret_val = pthread_create(&thread[1],

NULL,

play_http_content,

&read_val);

if (ret_val != 0) {

printf("Cannot create play_http_content thread!\n");

return 1;

}

pthread_join(thread[0], NULL);

pthread_join(thread[1], NULL);

可以看到,数据接收线程的线程主函数是 get_http_content,而播放音乐的线程主函数是 play_http_content。创建子线程后,主线程调用 pthread_join() 等待子结束,并释放线程相关资源。

回页首

5.接收 MP3 流媒体数据

由于 MP3 流媒体数据是在 HTTP 服务器的文件目录中,所以,必须由客户端发送 HTTP 请求,然后得到相关 URL 的 HTTP 响应。HTTP 的请求格式如下:

CRLF

*(( general-header

| request-header

| entity-header ) CRLF)

CRLF

[ message-body ]

这里 CR(13) 表示回车,LF 表示换行。

根据 HTTP 请求格式,可以构建发送到 HTTP 服务器请求。比如,想要往

192.168.0.123 HTTP 发送获得文件 http://192.168.0.123/45.MP3 那么构建的请求是:

GET /45.MP3 HTTP/1.1\r\n

HOST: 192.168.0.123\r\n\r\n

发送请求后,HTTP 服务器会就请求做出响应。如果请求合法,那么响应包括响应的媒体信息,包括 HTTP/1.1 200 OK,表示请求成功。最简单验证请求是否有效的方法是使用 telnet。例如:

[root@localhost netmad]# telnet 192.168.0.123 80

Trying 192.168.0.123...

Connected to 192.168.0.123(192.168.0.123).

Escape character is '^]'.

HEAD /45.MP3 HTTP/1.1

HOST:192.168.0.123

HTTP/1.1 200 OK

Date: Tue, 14 Nov 2006 10:11:43 GMT

Server: Apache/2.2.0 (Fedora)

Last-Modified: Tue, 17 Oct 2006 15:08:16 GMT

ETag: "3147c9-32e080-1fb83800"

Accept-Ranges: bytes

Content-Length: 3334272

Connection: close

Content-Type: audio/mpeg

X-Pad: avoid browser bug

这里可以看到在 HTTP 请求的响应中,有关于 45.MP3 的简单信息,包括文件类型 Content-Type: audio/mpeg,以及文件的长度 Content-Length: 3334272。通过解析 HTTP 响应,很容易从 Content-Length 项得到 MP3 数据总的长度。为了发送 HTTP 请求,首先从播放器程序传递的参数解析出请求的资源的 URI,比如程序传递参数为 http://192.168.0.123/45.MP3 那么解析此 URL,得到HTTP 请求的资源 URI 是 /45.MP3。get_address 函数简单地解析了 URL,用gethostbyname( ) 获得域名以及操作 socket 需要的地址信息。本文用于网络通信的一些 socket 相关的函数如下:

#include

#include

int socket (int family, int type, int protocol)

此函数创建 socket 。

int connect(int sockfd, const struct sockaddr *serv_addr,

socklen_t addrlen);

和目标地址服务程序连接,完成 3 次握手。

int recv(int s, void *buf, size_t len, int flags);

此函数从创建的 socket 接收数据。

回页首

6.数据接收线程和音乐播放线程

由于是两个线程并发运行,且音乐播放线程线程运行速度较慢。如果网络速度较快,数据接收线程的接收缓冲区满后,如果当前音乐播放线程正在播放音乐,那么数据接收线程必须停止接收数据。如果不让数据接收线程进入等待状态,它会一直轮训音乐播放线程观察其是否需要数据,简单的轮询会浪费 CPU 资源,所以在这种情况下,有必要让数据接收线程进入等待状态。本文使用信号量机制,来动态控制线程的运行。数据接收缓冲区必须留出一定的空间,存放解码缓冲区中没有被解码的数据。那么要留出多少数据空间呢?至少应该留出一帧数据的空间。这里 8192 字节空间存放剩余的一帧 MPEG 数据,一般情况下应该够用。因此定义:

#define DECODE_BUF_SIZE (8192*11)

#define GARD_SIZE (8192*10)

static char decode_buf[DECODE_BUF_SIZE];

static char recv_buf[DECODE_BUF_SIZE];

GARD_SIZE 是一次从 socket 读取数据字节数的最大值,而解码缓冲区的大小应该是比 GARD_SIZE 大 8192 字节,因此定义 DECODE_BUF_SIZE 为 (8192*11)。recv_buf 是数据接收缓冲区,decode_buf 是数据解码缓冲区。在拷贝数据到解码缓冲区的时候,上次未解码的数据,还被保存在解码缓冲区的开始部分,故拷贝数据的时候,必须拷贝到剩余数据的后面,程序例子如下:

memcpy(decode_buf + current_remain, recv_buf, current_read);

current_read += current_remain;

这里的 current_remain 表示上次解码线程中未解码的不完整 MP3 帧的数据字节数,current_read 表示当前接收线程接收到的实际数据字节数。两个缓冲区之间的数据拷贝操作如下图所示。

图 2:缓冲区之间的数据拷贝操作

数据接收线程和音乐播放线程之间的同步

由于使用了双缓冲区保存数据,所以,在音乐播放线程播放音乐的时候,数据接收线程不能把数据拷贝到数据解码缓冲区,而是需要等待。当数据接收缓冲区满的时候,接收线程自己也需要等待。本文用到了 POSIX 信号量处理函数,实现了线程之间的同步。它们分别是:

#include

int sem_init(sem_t *sem, int pshared, unsigned int value);

初始化信号量,第三个参数表示初始的信号量的计数。

int sem_wait(sem_t * sem);

sem_wait 阻塞当前线程的执行,直到信号量的计数非 0;然后,它会把信号量计数减 1,然后程序继续执行。相当于 P 操作。

int sem_post(sem_t * sem);

把 sem 指向的信号量计数加 1。相当于 V 操作。

int sem_destroy(sem_t * sem);

释放信号量对象。

在程序中,信号量定义及初始化为:

static sem_t empty_sem;

static sem_t decode_sem;

static sem_t copy_sem;

sem_init(&empty_sem, 0, 1);

sem_init(&decode_sem, 0, 0);

sem_init(©_sem, 0, 1);

empty_sem 信号量的计数表示接收缓冲是否为空,其中如果是 1,表示为空;如果为 0 表示不为空。decode_sem 信号量的计数表示音乐播放线程是否正在对数据解码缓冲区的数据进行解码,如果是 1 表示正在进行解码,如果是 0 表示没有解码;copy_sem 信号量的计数表示是否可以从数据接收缓冲区拷贝数据到数据解码缓冲区,如果是 1 表示可以,如果是 0 表示不能。

两个线程的同步操作或者说是 PV 操作流程如下图所示:

图 3:PV 操作流程示意图

回页首

7.程序运行实例

图 4:程序运行实例

回页首

8.小结

在实现基于 libmad 的 MP3 流媒体播放器中,我们用到了 libmad 的 API、网络 socket 编程技术、在音频设备上播放 PCM 数据技术、POSIX 信号量以及POSIX 线程。数据接收线程和音乐播放线程通过信号量和共享数据通信,相比单缓冲操作,通过双缓冲数据操作有效地提高了程序执行效率。同时,通过简单的信号量操作,线程不必使用轮询的方法来处理数据,也进一步减少了对 CPU 资源的浪费。

本文的意义在于给出了一个简单、明了的 MP3 流媒体播放器的实现。但是不足之处在于没有实现流媒体播放的控制协议,不能动态实现播放拖放操作。

参考资料

?https://www.doczj.com/doc/db8874371.html,/alsa-doc/alsa-lib/_2test_2pcm_8c-ex ample.html

?https://www.doczj.com/doc/db8874371.html,/alsa-doc/alsa-lib/pcm.html

?https://www.doczj.com/doc/db8874371.html,/documentation.php#dev-toots

?http://www.suse.de/~mana/alsa090_howto.html

?https://www.doczj.com/doc/db8874371.html,/products/mad/

?http://www.bsd-dk.dk/~elrond/audio/madlld/

关于作者

李素科,北京大学软件学院北大摩托罗拉嵌入式系统联合实验室讲师,主要研究方向是:网络与信息安全、嵌入式系统、分布式计算。现在主要从事 Linux 和MPC860 嵌入式系统的一些教学和开发工作。可以通过电子邮件地址

lisuke@https://www.doczj.com/doc/db8874371.html,与他联系。

音乐播放器前十排行

音乐播放器前十排行 1、QQ音乐 QQ音乐是腾讯公司推出的网络音乐平台,是中国互联网领域领先的正版数字音乐服务的领先平台,海量乐库在线试听、卡拉ok歌词模式、最流行新歌在线首发等,绿钻用户还可享受高品质音乐试听、正版音乐下载、MV观看等特权。 QQ音乐目前是国内音乐APP的绝对龙头,2016年底其曲库已经超过2000万首,旗下拥有的版权也是音乐APP中的第一,如索尼、华纳、杰尔威、英皇、韩国YG等,其市场份额也超过50%。虽然总有人吐槽QQ音乐,但是十大音乐APP排行榜第一位毫无悬念。在此前评选的全球音乐流服务排行榜,QQ音乐排名第四。 2、虾米音乐 虾米音乐版权建设虽然起步较晚,歌曲量在整体版权音乐中的比例低于20%,但在华语资源上仍具有一定优势。你想要听到华研唱片下的林宥嘉、S.H.E和田馥甄、相信音乐的五月天、梁静茹以及聚集了李宗盛、周华健等人的滚石,还是要投入虾米音乐的怀抱。而且虾米也在去年取得了韩国SM公司的音乐版权,这在国内来说,争取到了很大一部分的韩粉。虽然无法对QQ音乐造成威胁但依旧稳居十大音乐APP排行榜第二。 3、网易云音乐 网易云音乐不用再过多介绍了,近两年大火的音乐APP,口碑爆棚,市场份额目前也达到15%,局国内第二仅次于QQ音域。为何口碑份额双丰收的网易云音乐仅列十大音乐APP排行榜第三?网易云音乐的版权数量实在太少,并且官方也并不太重视版权的购买,虽然网易云音乐的版权音乐歌曲量占整体版权音乐的70%左右,但非常有意思的是大部分的版权都是通过转授权获得的。

4、酷狗音乐 酷狗音乐是一款集中播放、音乐效果、在线下载歌词等众多功能于一身,完全免费的手机音乐播放器。酷狗算是老牌音乐APP了, 但此前酷狗和酷我同QQ音乐一起加入新音乐集团,三大音乐APP曲 库资源基本互通,而且音乐伴奏资源众多也是酷狗的一大优势,喜 欢唱歌的人通常都是用酷狗搜索放伴奏唱歌、录歌。 不过酷狗的音质是劣势,对于耳朵挑剔的乐迷,对音质要求高的人来说很难满足。 5、咪咕音乐 咪咕音乐是一款面向所有用户的手机音乐APP,它包含了在线听歌、下载歌曲、订购彩铃以及开通会员等功能和业务,用户通过咪 咕音乐可以第一时间聆听中国移动无线首发的最新音乐,感觉最热 最流行歌曲,实时了解最新音乐咨讯及娱乐新闻,并可通过软件行 使无线音乐俱乐部会员权益。目前该软件已经覆盖市面上高中低端 主流机型,无论你是何种手机,均可轻松安装和使用。 6、酷我音乐 酷我音乐是中国数字音乐的交互服务品牌,是互联网领域的数字音乐服务平台,同时也是一款内容全、聆听快和界面炫的音乐聚合 播放器,是国内的多种音乐资源聚合的播放软件。自平台成立以来,酷我音乐作为前端潮流音乐的重要推手,率先与唱片公司、版权管 理机构合作探索发展,免费向广大用户提供方便流畅的在线音乐, 还有免费无损音乐方便用户的试听和下载,生成了丰富的音乐流媒 体生态系统。 7、天天动听 天天动听是一款功能强大、完全免费的手机音乐播放软件,支持歌词和歌曲图片下载,简洁人性化的操作,带来手机听歌的全新体验,是拇指一族必备的音乐播放工具。 8、百度音乐

音乐播放器的详细设计

音乐播放器详细设计 1.引言 随着社会的快速发展,现今社会生活紧张,而欣赏音乐是其中最好的舒缓压力的方式之一,音乐成了我们生活工作中的一个重要的部分。而3G时代的到来,手机移动应用越来越普遍。此文档就是为了能更好地设计出一个基于android系统的音乐播放器而编写的。 1.1 编写目的 为软件的开发者能更好的理解和明确软件开发的详细过程,安排项目与进度、组织软件开发与测试,撰写本文档。本文档供项目组成员,软件开发人员参考。1.2项目背景 本项目由李雪梅、杨挺等人提出,由本组成员联合开发,实现播放现今流行的音乐MP3等文本格式。 该软件是基于Android系统的音乐播放软件,并能够与其他音乐播放软件兼容。 1.3 参考资料 [1] 重庆大学出版社《软件工程》“软件计划与可行性分析” [2] 靳岩、姚尚明人民邮电出版社《Android开发入门与实践》 [3] 可行性分析 [4] 《音乐播放器需求分析书》 [5] 《音乐播放器总体设计说明书》 1.4项目开发计划 实施计划:

阶段名称负责人 需求分析杨挺、李雪梅 总体设计李雪梅、杨挺 详细设计李雪梅、杨挺 软件测试李雪梅、杨挺 在技术方面,编程知识比较缺乏,对有些与项目相关的软件 不熟悉,需进行人员的技术培训(自学为主),技术难点是数据库的构架和软件功能的设计。 2. 总体设计 2.1 项目目的 本项目的目的是开发一个可以播放主流的音乐文本格式的播放器。设计的主要实现功能是播放MP3等格式的音乐文件,并且能控制播放,暂停,停止,音量控制,选择上一曲,选择下一曲,更改皮肤,歌曲列表文件的管理操作,在线播放,读取 存储卡播放等多种播放控制,界面简明,操作简单。 软件系统检测到错误行为时,报告错误,并提示处理操作。 2.2 软件运行环境 硬件:Android操作系统手机 系统软件:Android 2.2 -- 4.0版本 支撑软件:Eclipse 7.5 、ADT 1.5 2.3 需求概述

音乐播放器程序源代码及注释

音乐播放器程序源代码及注释: #include #define uchar unsigned char #define uint unsigned int sbit duan=P2^6; sbit key1=P3^2;//按key1可切换花样 sbit key2=P3^3;//按key2可切换歌曲 sbit fm=P2^4;//蜂鸣器连续的IO口 sbit P30=P3^0;//矩阵键盘的一列 uchar code huayang1[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe, 0xfd,0xfb,0xf7,0xef,0xdf,0xbf};//花样1 uchar code huayang2[]={0x7f,0xfe,0xbf,0xfd,0xdf,0xfb,0xef,0xf7, 0xef,0xfb,0xdf,0xfd,0xbf,0xfe};//花样2 uchar code huayang3[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x0, 0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; char code huayang4[]={ 0x55,0xaa,0xcc,0x33,0x99,0x66,0x0f,0xf0}; uchar count1;//花样标志 uchar count2;//歌曲标志 uchar timeh,timel,i; //编程规则:字节高位是简谱,低位是持续时间, //代表多少个十六分音符 //1-7代表中央C调,8-E代表高八度,0代表停顿

课程设计简易单片机音乐播放器

课程设计 题目:基于单片机音乐演奏曲Title: instrumental music based on single chip 姓名: 学号: 系别: 专业: 年级: 指导教师: 2012年5 月25 日

摘要 单片机具有强大的控制功能和灵活的编程实现特性,它已经溶入现代人们的生活中,成为不可替代的一部分。本设计以At89c2051为核心,主要由电源电路、复位电路、音频放大电路、时钟电路和数码管电路和蜂鸣器电路构成单片机奏乐附加时钟的一个小系统。电路中I/O口采用分时复用的借口技术,使AT89c2051单片机的引脚资源得以充分利用,本系统的电路简单,实现的功能强大,所用芯片比较便宜,性价比较高。 关键词:At89c2051,数码管,单片机奏乐,分时复用

目录 摘要 ........................................................... - 1 - 1.引言 (3) 2.系统整体结构 (4) 2.1系统总设计 (4) 2.2实现的功能 (4) 2.3主要芯片介绍 (4) 2.3.1 AT89c2051芯片介绍 (4) 3.系统硬件设计 (5) 3.1键盘输入模块 (5) 3.2时钟模块 (5) 3.3显示模块 (6) 3.4复位电路 (6) 3.5蜂鸣器电路设计 (7) 4.系统软件设计 (7) 4.1系统主程序流程图系 (7) 4.2 部分子程序流程图 (8) 结束语 (10) 参考文献 (10) 致谢 (11) 附录 (11)

1.引言 随着社会的发展、科技的进步以及人们生活水平的逐步提高,各种方便于生活的自动控制系统开始进入了人们的生活,以单片机为核心的各种系统也越来越多。同时也标志了自动控制领域成为了数字化时代的一员。它实用性强,功能齐全,技术先进,使人们相信这是科技进步的成果。它更让人类懂得,数字时代的发展将改变人类的生活,将加快科学技术的发展。 本次设计为单片机奏乐器,硬件部分它以单片机AT89C2051为核心,由功放电路、数码管等组成。当接上电源按下开关时,就能听到优美的旋律。当然这些音乐都是通过软件编程实现的,把它存储在存储器里,根据存储容量大小决定存储音乐的数目。 [2]

嵌入式MP3播放器的设计

嵌入式MP3播放器的设计 1 系统概述 本文采用STM32系列微控制器,结合解码芯片VS1003、SD卡、LCD等外围设备设计并实现了MP3播放器。其主要功能有:播放VS1003支持的所有音频文件,如MP3、WMA、WAV文件,且音质非常好;通过触摸屏实现按键功能,控制播放上一首/下一首、音量增减等;通过LCD显示歌曲名字和播放状态;本系统还实现了读卡器功能,PC机可通过USB接口直接对开发板上的SD卡进行读写操作,以方便拷贝音频文件。 MP3播放过程是STM32通过SPI1接口将数据从SD卡中取出,然后通过SPI2接口送至解码芯VS1003解码播放。这里解码模块单独使用一个SPI接口,以减小干扰和噪声、提高音质。 2 系统硬件设计方案 本系统在硬件上分为6个模块: 微控制器STM32F103、解码模块VS1003、存储模块SD卡、触摸屏、USB接口和显示屏LCD。系统硬件框架如图5所示。 VS1003 STM32 图5 系统硬件框架图 2.1 存储模块设计 SD卡在现在的日常生活与工作中使用非常广泛,时下已经成为最为通用的数据存储卡。在诸如MP3、数码相机等设备上也都采用SD卡作为其存储设备。SD卡之所以得到如此广泛的使用,是因为它价格低廉、存储容量大、使用方便、通用性与安全性强等优点。SD卡支持两种总线方式: SD方式与SPI方式。其中SD 方式采用6线制,而SPI方式采用4线制,采用单片机对SD卡进行读写时一般都采用SPI模式。可用不同的初始化方式使SD卡工作于SD方式或SPI方式。 在本设计中,音频数据MP3文件是以SD卡为载体。所以在电路设计中必须含有读取SD卡模块。该系统使用STM32内部接口SPI1与SD卡进行通信,下面介绍其引脚连接情况。 PE3:低电平有效,连接到SD卡的片选引脚CD/DAT3。SPI在和SD卡进行通

Java音乐播放器源代码即结果显示

简单的音乐播放器一、程序代码: import java.io.File; import java.awt.BorderLayout; import java.awt.Button; import java.awt.Color; import java.awt.FileDialog; import java.awt.Frame; import java.awt.GridLayout; import https://www.doczj.com/doc/db8874371.html,bel; import java.awt.List; import java.awt.Menu; import java.awt.MenuBar; import java.awt.MenuItem; import java.awt.MenuShortcut; import java.awt.Panel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.SourceDataLine; public class Example extends Frame { private static final long serialVersionUID = 1L; boolean isStop = true;// 控制播放线程 boolean hasStop = true;// 播放线程状态

基于51单片机的音乐播放器设计

题目:音乐播放器 课程设计(论文)任务书

摘要 随着电子技术的发展和计算机越来越普遍的使用,单片机作为这两项技术的有机结合也得到了广泛的应用,在某些领域具有不可替代的作用。音乐播放功能随处都会用到,如,在开发儿童智力的玩具中,等等。目前,基于单片机实现音乐播放,其体积小、价格低、编程灵活等特点在这一领域独领风骚。 单片机的英文名称为single chip microcomputer,最早出现在20世纪70年代,国际上现在已逐渐被微控制器(Microcontroller Unit 或MCU)一词所取代。它体积小,集成度高,运算速度快,运行可靠,功耗低,价格廉,因此在数据采集、智能化仪表、通讯设备等方面得到了广泛应用。而8051单片机在小到中型应用场合很常见,已成为单片机领域的实际标准。随着硬件的发展,8051单片机系列的软件工具也有了C级编译器和实时多任务操作系统RTOS,为单片机编程使用C语言提供了便利的条件;并针对单片机常用的接口芯片编制通用的驱动函数,可针对常用的功能模块,算法等编制相应的函数;C语言模块化程序结构特点,可以使程序模块大家共享,不断丰富,这样就使得单片机的的程序设计更简单可靠,实时性强,效率高。作为测控技术与仪器的学生,掌握8051单片机硬件基础及其相关软件操作,将其应用于现代电子产品中是必要而且重要的,这次课程设计我们的题目是用单片机实验箱系统制作音乐播放器。 本次课程设计主要内容是通过单片机C51语言进行编程,以产生乐曲音符和节拍,把乐谱翻译成计算机语言(音符转换诚成相对应的方波频率即定时器装载初值,节拍转换成相对应的延长时间),并将其预先存储到单片机里,然后根据按键调用再由单片机进行信息处理,在经过信号放大,由喇叭放出乐曲声,实现音乐播放的功能。其主要表现在可以播放十首歌曲,可以用十个数字键控制播放的歌曲,并且能在LCD液晶屏显

数字系统设计音乐播放器

一、实验目的和要求(必填) 二、实验内容和原理(必填) 三、主要仪器设备(必填) 四、操作方法和实验步骤 五、实验数据记录和处理 六、实验结果与分析(必填) 七、 讨论、心得 一、实验目的和要求: 实验目的: (1)掌握音符产生的方法,了解DDS 技术的应用。 (2)了解AC97音频接口电路的应用。 (3)掌握系统“自顶而下”的设计方法。 实验任务: 设计一个音乐播放器。 (1)可以播放四首乐曲,设置play 、next 、reset 三个按键。按play 键播放当前乐曲,按next 键播放下一首乐曲。 (2)LED0指示播放情况(播放时点亮)、LED2和LED3指示当前乐曲序号。 二、实验内容和原理 (1)音乐播放器的设计原理 根据实验任务可将系统分为主控制器(mcu )、乐曲读取(song_reader )、音符

播放(note_player)、AC97音频接口(codec_conditioner)和ac97_if五个子模块,系统的总体框图如下: 各个模块的功能如下: 模块接收按键信息,通知song_reader模块是否要播放(play)及播放哪首乐曲(song),若一曲播放结束则进入播放结束END状态。 模块根据mcu模块的要求,逐个取出音符{note,duration}送给note_player模块播放,当一首乐曲播放完毕,回复mcu模块乐曲播放结束信号(song_done)。 模块接收到需播放的音符,在音符的持续时间内,以48kHz速率送出该音符的正弦波样品给AC97音频接口模块。当一个音符播放结束,向song_reader模块发送一个note_done脉冲索取新的音符。 、ac97_if模块负责与AC97音频系统接口工作,本实验已提供了这两个模块的代码。 另外,按键处理模块完成输入同步化、防颤动和脉宽变换等功能。 1、主控制模块mcu的设计 mcu模块是主控制模块,有响应按键信息、控制系统播放两大任务,工作流程如下面的流程图所示。要求系统复位后经RESET状态初始化后进入WAIT状态等待按键输入或乐曲播放结束应答,若有按键输入则转入相应的按键处理状态(NEXT或PLAY),若一曲播放结束则进入结束播放END状态。 mcu的控制器算法流程图如下图: 以下为mcu的端口含义

音乐播放器的设计与实现

德州学院信息管理学院 课程设计报告实习名称课程设计2 设计题目Android音乐播放器的设计与实现实习时间 专业班级12级计算机科学与技术 指导老师刘想 教学单位(盖章) 小组成员分工情况: 学号姓名分工 3018 周生明音乐播放的设计与实现1052曹法瑞 1040 张正奎 1055 李元华 2049 王山 二〇一五年六月三十日

目录 摘要 ................................................................................................................ 错误!未定义书签。 1 引言 ............................................................................................................ 错误!未定义书签。 2 可行性分析................................................................................................. 错误!未定义书签。 2.1 技术可行性...................................................................................... 错误!未定义书签。 2.2 经济可行性...................................................................................... 错误!未定义书签。 2.3 管理可行性...................................................................................... 错误!未定义书签。 2.4 可行性分析结论.............................................................................. 错误!未定义书签。 3 系统需求分析............................................................................................. 错误!未定义书签。 3.1 功能分析.......................................................................................... 错误!未定义书签。 3.2 数据流程分析.................................................................................. 错误!未定义书签。 4 系统功能设计............................................................................................. 错误!未定义书签。 4.1 播放器功能结构.............................................................................. 错误!未定义书签。 4.1.1 播放器主界面功能模块....................................................... 错误!未定义书签。 4.1.2 播放器菜单功能模块........................................................... 错误!未定义书签。 4.2 播放器功能流程.............................................................................. 错误!未定义书签。 5 系统实现..................................................................................................... 错误!未定义书签。 5.1 播放器主界面功能列表.................................................................. 错误!未定义书签。 5.2 播放器基本功能的实现.................................................................. 错误!未定义书签。 5.3 播放列表的实现.............................................................................. 错误!未定义书签。 6 软件测试与验证......................................................................................... 错误!未定义书签。 6.1 软件测试的目的.............................................................................. 错误!未定义书签。 6.2 软件测试的方法.............................................................................. 错误!未定义书签。 6.3 软件测试环境.................................................................................. 错误!未定义书签。 6.3.1 android模拟器 ...................................................................... 错误!未定义书签。 6.3.2 真机测试............................................................................... 错误!未定义书签。 6.4 软件测试流程与结果评估.............................................................. 错误!未定义书签。 6.4.1 测试流程............................................................................... 错误!未定义书签。 6.4.2 结果评估............................................................................... 错误!未定义书签。

音乐播放器代码大全

音乐播放器代码大全 autostart="true"中true或1表示自动播放,false或0表示手动播放 loop="true" 中的true或1表示重复播放,false或0表示只播放一次width= height= 中的数字分别表示播放器的宽度和高度=0表示隐藏播放器 EnableContextMenu="0" 禁右键 ShowStatusBar="1" (带显示文件播放信息) 1隐藏播放器(不循环) 代码: 2.隐藏播放器(循环播放) 代码: 3.黑色皮肤播放器 代码: 4.淡蓝色播放器 代码:

5.迷幻播放器 代码:

6.带菜单的播放器 代码: 7.深黄色带菜单播放器 代码: 8.灰色播放器 代码:

新型变频数码音乐播放器使用手册

新型变频数码音乐播放器使用手册 江苏华宇电气有限公司 (网址)https://www.doczj.com/doc/db8874371.html, (邮箱)cnhuayu@https://www.doczj.com/doc/db8874371.html, 第一章总述........................................................................................................- 3 - 1.1简介 .....................................................................................................- 3 - 1.1.1 华宇MP3型超级智能数码音乐播放仪特点........................- 3 - 1.1.2 手册约定 .................................................................................- 4 - 1.1.3 通讯软件计算机系统要求 .....................................................- 4 - 1.1.4 产品包装 .................................................................................- 4 - 1.2 安装说明 ..........................................................................................- 5 - 1.2.1 硬件安装 .................................................................................- 5 - 1.2.2 软件安装 .................................................................................- 6 - 1.2.3 运行程序 .................................................................................- 6 - 第二章编程说明................................................................................................- 6 - 2.1 编程准备 ............................................................................................- 6 - 2.1.1 整理时间表: .........................................................................- 6 - 2.1.2 编程状态说明: .....................................................................- 7 - 2.1.3编程顺序: ..............................................................................- 7 - 2.1.4编程位左右移动: ..................................................................- 7 - 2.1.5数值输入: ..............................................................................- 7 - 2.1.6 编程存贮: .............................................................................- 7 - 2.1.7编程退出: .................................................................................- 7 - 2.2 定时音乐播放程序编程 ....................................................................- 8 - 2.2.1 时间设置: ................................................................................- 8 - 2.2.2 曲目设置: ................................................................................- 8 - 2.2.3 星期设置: ................................................................................- 8 -

安卓音乐播放器开发,含源代码

基于an droid平台的音乐播放器开发 实验报告 学生姓名:_______ 温从林 _________________ 学号: ___________________________________ 班级:计自1201 _____________ 第一章引言 1.1项目背景 当今社会的生活节奏越来越快,人们对手机的要求也越来越高,由于手机市场发展迅速,使得手机操作系统也出现了不同各类,现在的市场上主要有三个手机操作系统,Win dowsmobile,symbia n,以及谷歌的An droid操作系统,其中占有开放源代码优势的An droid系统有最大的发展前景。那么能否在手机上拥有自己编写的个性音乐播放器呢?能的,谷歌An droid系统就能做到。本文的音乐播放器就是基于谷歌An droid手机平台的播放器。 An droid :是谷歌于2007年公布的开放式源代码手机系统,它的开放性就优于其它封闭式的手机系统,因此,任何人都可能根据自己的喜好将手机系统中的所有功能重新编写。这使得越来越多的人关注这个操作系统。本次作品音乐播放器就是基于An droid平台的。 1.2编写目的 现今社会生活紧张,而欣赏音乐是其中最好的舒缓压力的方式之一,本项目的目的是开发一个可以播放主流音乐文件格式的播放器,本设计实现的主要功能是播放Mp3 Wav多种格式的音乐文件,并且能够控制播放,暂停,停止,播放列等基本播放控制功能,界面简明,操作简单。

本项目是一款基于An droid手机平台的音乐播放器,使An droid手机拥有个性的 多媒体播放器,使手机显得更生动灵活化,与人们更为接近,让手机主人随时随地处于音乐视频的旋律之中。使人们的生活更加多样化。也使设计者更加熟练An droid的技术和其它在市场上的特点。 1.3开发环境 Eclipse、An droid SDK 320 第二章系统需求分析 2.1功能需求(用例图分析) 根据项目的目标,我们可获得项目系统的基本需求,以下从不同角度来描述系统的需求,并且使用用例图来描述,系统的功能需求,我们分成四部分来概括,即播放器的基本控制需要,播放列表管理需求,播放器友好性需求和播放器扩展卡需求。以下分别描述: 2.1.1播放器的用例图 假设安装了音乐播放器的用户是系统的主要设计对象,其拥有以下操作, 启动软件、播放音乐、暂停播放、停止播放、退出软件,其用例图如下 图2.1 播放器基本用例图 2.1.2用例分析

音乐播放器设计文档

生产实习报告 题目:音乐播放器 学生姓名:张凡 学号: 201220220123 班级: 1222201 专业:数字媒体技术 指导教师:张金 2015年08 月08日

目录 一、引言 (3) 1.1 项目背景 (3) 1.2 项目研究的目的 (4) 1.3 安卓简介 (4) 二.功能分析 (5) 2.1 功能需求分析 (5) 2.2 系统性能需求 (6) 2.3 运行环境需求 (6) 三.程序详细设计 (6) 3.1 主界面的设计 (6) 3.2 播放界面设计 (11) 3.3 其他功能 (14) 四.调试与运行 (18) 4.1 调试 (18) 4.2 运行结果 (19) 五.总结 (21)

一、引言 1.1 项目背景 当今社会的生活节奏越来越快,人们对手机的要求也越来越高,由于手机市场发展迅速,使得手机操作系统也出现了不同各类,现在的市场上主要有三个手机操作系统,symbian,Windows mobile,以及谷歌的Android操作系统,其中占有开放源代码优势的Android系统有最大的发展前景。那么能否在手机上拥有自己编写的个性音乐播放器呢?答案是:肯定的,谷歌Android系统就能做到。本文的音乐播放器就是基于谷歌Android手机平台的播放器。 随着计算机的广泛运用,手机市场的迅速发展,各种音频视频资源也在网上广为流传,这些资源看似平常,但已经渐渐成为人们生活中必不可少的一部分了。于是各种手机播放器也紧跟着发展起来,但是很多播放器一味追求外观花哨,功能庞大,对用户的手机造成了很多资源浪费,比如CPU,内存等的占用率过高,在用户需要多任务操作时,受到了不小的影响,带来了许多不便,而对于大多数普通用户,许多功能用不上,形同虚设。针对以上各种弊端,选择了开发多语种的音频视频播放器,将各种性能优化,继承播放器的常用功能,满足一般用户(如听歌,看电影)的需求,除了能播放常见格式的语音视频文件,高级功能:还能播放RMVB格式的视频文件。此外,还能支持中文、英文等语言界面。

【推荐下载】html5 简单音乐播放器

html5 简单音乐播放器 2016/04/09 0 html5 简单音乐播放器 !DOCTYPE html html xmlns=“w3/1999/xhtml”head meta http-equiv=“Content- Type”content=“text/html;charset=UTF-8”/title /title style type=“text/css”body{font-family:微软雅黑;} #container{width:500px;margin:10px auto;border:1px solid #ccc;background:#999999;border-radius:5px;padding:10px;} #mName{float:left;width:250px;} #mTime{float:left;width:250px;text-align:right;} #player{margin-top:20px;} #media{width:450px;} ul{list-style:none;padding-left:5px;} ul li{margin-top:5px;} #mList{height:200px;} #changeMusic{text-align:right;} a{text- decoration:none;color:black;} a:hover{color:red;} /style script //声明两个数组,用来存储歌曲名称和文件地址var musicNames=[],musicSrcs=[],randomNums=[]; var RANDOMNUM=5;//随机的歌曲数量function $(id){ return document.getElementById(id); } function initial(){ //为数组赋值musicNames[0]=“Blood Money.mp3”;musicNames[1]=“California Hotel.mp3”; musicNames[2]=“Loving You.mp3”;musicNames[3]=“Miracle.mp3”; musicNames[4]=“SantaFe.mp3”;musicNames[5]=“Wonderful Tonight.mp3”; musicSrcs[0]=“music/Blood Money.mp3”;musicSrcs[1]=“music/CalifoniaHotel.mp3”; musicSrcs[2]=“music/Loving You.mp3”;musicSrcs[3]=“music/Miracle.mp3”; musicSrcs[4]=“music/SantaFe.mp3”;musicSrcs[5]=“music/Wonderful Tonight.mp3”; //获取元素media = $(“media”);//绑定事件media.addEventListener(“canplay”,media_canplay,false); media.addEventListener(“play”,media_play,false); //获取歌曲loadMusic(); } /** * 判断r 在randomNums 中是否已经存在* return true : 已经存在* return false : 不存在*/ function checkRExists(r){ for(var i=0;i randomNums.length;i++){ if(randomNums[i] == r){ //存在return true; } } return false; } /** * 方法:用于生成指定个数随机数* 如果碰到重复的数字,则重新生成*/ function generateRandom(){ var i=0; for(;;){ var

音乐播放器需求分析

音乐播放器需求分析 项目名称音乐播放器 需求分析左茂元 界面设计杨婷、李映 程序测试杨婷、李映 程序员1 高守林 程序员2 廖敬之 总负责人魏秋兴 2016 年11 月

摘要:随着生活水平的提高,娱乐已成为非常主流的话题,人们不仅需要通过音乐陶冶情操,而且越来越多的人倾向于使用音乐、视频等娱乐和放松自己,这大大促进了媒体软件的发展.本文旨在介绍研究常用数字音频编码和解码的相关知识,并结合VS2013编写多功能音乐播放器,了解音乐播放器功能的实现,掌握开发音乐播放器所需的相关知识,采用了面向对象软件工程方法,其开发主要包括应用程序界面设计和后台代码运行两个方面,实现了多功能音乐播放器在计算机上的应用,可以在很大程度上满足用户的需求.该系统主要具备:音乐播放控制、音乐文件控制、音量控制、下载控制、歌词控制、进度控制、音乐剪辑等功能模块。 关键字:音乐播放器,音频编码格式,C#,Visual Studio 2013

1.前言 (4) 1.1选题的背景及意义 (4) 1.2项目目的 (4) 1.3参考资料 (4) 2.具体需求 (5) 3.前台功能需求 (5) 3.1用户登录需求 (5) 3.2播放器的基本控制需求 (5) 3.3播放列表管理需求 (6) 4.界面需求 (6) 5.后台管理需求 (6) 5.1管理员管理 (6) 5.2歌手管理 (7) 5.3歌曲管理 (7) 5.4类别管理: (7) 6.性能需求 (7) 7. 可靠性要求 (7) 8.音乐播放器需求修改明细 (8)

1.前言 随着社会的快速发展,现今社会生活紧张,而欣赏音乐是其中最好的舒缓压力的方式之一,音乐成了我们生活工作中的一个重要的部分。现今播放器的种类繁多,此文档是为了设计一个基于Microsoft系统而设计的一个音乐播放器。 1.1选题的背景及意义 本项目由项目经理魏秋兴提出由项目组员一起联合开发并实现其功能。开发此软件是为软件的开发者能更好的理解和明确软件开发的详细过程,安排项目与进度、组织软件开发与测试,撰写本文档。本文档供项目组成员,软件开发人员参考。 1.2项目目的 本项目的目的是开发一个可以播放主流的音乐文本格式的播放器。设计的主要实现功能是播放MP3格式的音乐文件,并且能控制播放,暂停,停止,音量控制,选择上一曲,选择下一曲,更改皮肤,歌曲列表文件的管理操作,在线播放,读取存储卡播放等多种播放控制,界面简明,操作简单。软件系统检测到错误行为时,报告错误,并提示处理操作。 1.3参考资料 待定——————————————————————————————————————————————————————————————————————————

相关主题
文本预览
相关文档 最新文档