Linux下编写了一个小程序,播放wav文件成功。
今天,看了下wav文件格式,在Linux下尝试了读取wav文件数据写往声卡文件/dev/dsp,播放成功。<br />没想到Linux下声卡编程竟然如此简单,就是把音频数据写到/dev/dsp文件即可。<br /><br />源代码如下<br /><br />/* filename: wavplay.c */<br /><br />#include <unistd.h><br />#include <fcntl.h><br />#include <sys/types.h><br />#include <sys/ioctl.h><br />#include <stdlib.h><br />#include <stdio.h><br />#include <stdint.h><br />#include <linux/soundcard.h><br /><br />#define BUFSIZE 512<br /><br />struct RIFF_Header{<br /> char RIFF_ID;<br /> uint32_t RIFF_Size;<br /> char RIFF_Format;<br />};<br /><br />struct Chunk_Header{<br /> char Chunk_ID;<br /> uint32_t Chunk_Size;<br />};<br /><br />struct Wave_Format{<br /> uint16_t AudioFormat;<br /> uint16_t NumChannels;<br /> uint32_t SampleRate;<br /> uint32_t AvgBytesPerSec;<br /> uint16_t BlockAlign;<br /> uint16_t BitsPerSample;<br />};<br /><br />int main(int argc, char *argv[])<br />{<br /> struct RIFF_Header riff_header;<br /> struct Chunk_Header fmt_chunk, data_chunk;<br /> struct Wave_Format wavfmt;<br /><br /> char buf;<br /> FILE * fwave;<br /> int sndfd; <br /> int status;<br /> int arg;<br /> int readbytes;<br /> int writebytes;<br /> int writed;<br /> <br /> if( argc < 2 ){<br /> fprintf(stderr, "Usage: wavplay <filename>\n");<br /> exit(-1);<br /> }<br /> <br /> fwave = fopen( argv, "r");<br /> if( fwave == NULL ){<br /> fprintf(stderr, "Can't open file %s\n", argv);<br /> exit(-1);<br /> }<br /> <br /> fread(&riff_header, 1, sizeof(struct RIFF_Header), fwave);<br /> if( strncmp(riff_header.RIFF_ID, "RIFF", 4) || strncmp(riff_header.RIFF_Format, "WAVE",4)){<br /> fprintf(stderr, "Unknown file format.\n");<br /> exit(-1);<br /> }<br /><br /> sndfd = open("/dev/dsp", O_RDWR);<br /> if (sndfd < 0) {<br /> perror("open of /dev/dsp failed");<br /> exit(-1);<br /> }<br /><br /> fread(&fmt_chunk, 1, sizeof(struct Chunk_Header), fwave);<br /> if( !strncmp(fmt_chunk.Chunk_ID, "fmt ", 4) ){<br /> /* this is a fmt chunk */<br /> fread(&wavfmt, 1, sizeof(struct Wave_Format), fwave);<br /> <br /> arg = wavfmt.BitsPerSample;<br /> status = ioctl(sndfd, SOUND_PCM_WRITE_BITS, &arg);<br /> if (status == -1)<br /> perror("SOUND_PCM_WRITE_BITS ioctl failed");<br /> if (arg != wavfmt.BitsPerSample)<br /> perror("unable to set sample size");<br /> <br /> arg = wavfmt.NumChannels; <br /> status = ioctl(sndfd, SOUND_PCM_WRITE_CHANNELS, &arg);<br /> if (status == -1)<br /> perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");<br /> if (arg != wavfmt.NumChannels)<br /> perror("unable to set number of channels");<br /><br /> arg = wavfmt.SampleRate;<br /> status = ioctl(sndfd, SOUND_PCM_WRITE_RATE, &arg);<br /> if (status == -1)<br /> perror("SOUND_PCM_WRITE_WRITE ioctl failed");<br /><br /> /* skip extra bytes */<br /> fseek(fwave, fmt_chunk.Chunk_Size - 16 + fmt_chunk.Chunk_Size%2, SEEK_CUR);<br /> }else{<br /> fprintf(stderr, "Can't find fmt chunk.\n");<br /> exit(-1);<br /> }<br /> <br /> while( fread(&data_chunk, 1, sizeof(struct Chunk_Header), fwave) != 0 )<br /> if( !strncmp(data_chunk.Chunk_ID, "data", 4) ){<br /> printf("Begin Play\n");<br /> /* this is a data chunk */<br /> writed = 0;<br /> while(writed < data_chunk.Chunk_Size){<br /> readbytes = fread(buf, 1, BUFSIZE, fwave);<br /> writebytes = write(sndfd, buf, readbytes);<br /> if( writebytes != readbytes )<br /> perror("wrote wrong number of bytes");<br /> writed += readbytes;<br /> }<br /> }else{<br /> /* skip unknown chunks */<br /> fseek(fwave, data_chunk.Chunk_Size + fmt_chunk.Chunk_Size%2, SEEK_CUR);<br /> }<br /> <br /> fclose(fwave);<br /> close(sndfd);<br /> <br /> return 0;<br />} 顶
大哥,啥时候写个MP3的啊?嗯!恭喜LZ啦!
嘻....嘻...在linux下面裸奔呀
用GStreamer库的小播放器,指定文件路径就行.....<br />#include <gst/gst.h><br />#include <stdbool.h><br />static GMainLoop *loop;<br />static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer user_data)<br />{<br /> switch (GST_MESSAGE_TYPE (msg))<br /> {<br /> case GST_MESSAGE_EOS:<br /> g_message ("End-of-stream");<br /> g_main_loop_quit (loop);<br /> break;<br /> case GST_MESSAGE_ERROR:<br /> g_message ("Error");<br /> g_main_loop_quit (loop);<br /> break;<br /> default:<br /> break;<br /> }<br /> return true;<br />}<br /><br />void play_uri (gchar *uri)<br />{<br /> GstElement *pipeline;<br /><br /> loop = g_main_loop_new (NULL, FALSE);<br /><br /> pipeline = gst_element_factory_make ("playbin", "player");<br /><br /> if (uri)<br /> g_object_set (G_OBJECT (pipeline), "uri", uri, NULL);<br /><br /> {<br /> GstBus *bus;<br /><br /> bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));<br /> gst_bus_add_watch (bus, bus_call, NULL);<br /> gst_object_unref (bus);<br /> }<br /><br /> gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);<br /><br /> g_main_loop_run (loop);<br /><br /> gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);<br /> gst_object_unref (GST_OBJECT (pipeline));<br />}<br /><br />int main (int argc, char *argv[])<br />{<br /> gst_init (&argc, &argv);<br /><br /> if (argc > 1)<br /> play_uri (argv);<br /><br /> return 0;<br />}re
LS,你上面那个Streamer库是播什么格式的?回sodwell
mp3是有损格式,不太想搞。学习关注,
同时顶一下好
好ding
页:
[1]