二、音箱初始化

news/2024/11/24 13:48:35/

首先创建vim main.c初始化设备文件

#include <stdio.h>
int g_buttonfd ;
int g_ledfd;
int g_mixerfd;int main()
{InitDriver();return 0;
}
  1. 按键设备文件,用于操作硬件设备

vim deviece.c

//用于操作硬件设备
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#extern int g_buttonfd;
extern int g_ledfd;
extern int g_mixerfd;int InitDriver()
{//打开按键设备文件g_buttonfd = open("/dev/buttons", O_RDONLY);if (-1 == g_buttonfd){return FAILURE;}//打开led设备文件g_ledfd = open("/dev/leds", O_WRONLY);if (-1 == g_ledfd){return FAILURE;}//打开minxer设备文件g_mixerfd = open("/dev/mixer", O_WRONLY);if (-1 == g_mixerfd){return FAILURE;}return SUCCESS;
}

新建vim main.h

#ifndef MAIN_H
#define MAIN_H#define SUCCESS     10000
#define FAILURE     10001#endif

声明设备头文件vim devide.h

#ifndef DEVICE_H
#define DEVICE_Hint InitDriver();#endif

对主函数做返回值判断main.c

#include <stdio.h>
int g_buttonfd ;
int g_ledfd;
int g_mixerfd;int main()
{int ret;ret = InitDriver();     //打开设备文件if (FAILURE == ret){printf("初始化设备文件失败\n");exit(1);}return 0;
}

设备初始化完后对网络进行初始化

#include <stdio.h>
int g_buttonfd ;
int g_ledfd;
int g_mixerfd;int main()
{int ret;ret = InitDriver();     //打开设备文件if (FAILURE == ret){printf("初始化设备文件失败\n");exit(1);}ret = InitSocket();      //初始化网络if (FAILURE == ret){printf("初始化网络失败\n");//初始化失败,点亮 2 个LED灯led_on(0);led_on(1);}return 0;
}

下面实现网络初始化代码:

vim socket.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "main.h"
int InitSocket()
{g_sockfd = socket(PF_INET, SOCK_STREAM, 0);if (-1 == g_sockfd){return FAILURE;}
}

socket头文件socket.h

#ifndef SOCKET_H
#define SOCKET_H#define SERVER_PORT   8000
#define SERVER_IP     "47.101.128.140"int InitSocket();
#endif

当socket创建好后,启动线程发起服务器连接

socket.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "main.h"extern int g_sokcetfd;int InitSocket()
{g_sockfd = socket(PF_INET, SOCK_STREAM, 0);if (-1 == g_sockfd){return FAILURE;}pthread_t tid;int ret = pthread_create(&tid, NULL, connect_cb, NULL);if (ret != 0){return FAILURE;}}

创建线程后启动一个线程函数connect_cb

void *connect_cb(void *arg)
{int count = 5, ret;struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = PF_INET;server_addr.sin_port = htons(SERVER_PORT);server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);while (count--){ret = connect(g_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));if (ret == -1){sleep(5);continue;}//连接成功,点亮 4 个LED灯led_on(0);led_on(1);led_on(2);led_on(3);break;}return NULL;
}

考虑到会连接失败,线程会向服务器发起5次连接,如果五次均为成功,返回失败。

因为开发板有led,现在考虑连接的时候用led提示,发起连接的时候第一个灯亮,初始化时led灭,

连接成功4个灯都亮

device.c

    //所有LED灭int i;for (i = 0; i < 4; i++){ioctl(g_ledfd, 0, i);}void led_on(int which)
{ioctl(g_ledfd, 1, which);    
}void led_off(int which)
{ioctl(g_ledfd, 0, which);
}

device.h

#ifndef DEVICE_H
#define DEVICE_Hint InitDriver();
int led_on(int which);
int led_off(int which);#endif

在socket.c加入device.h头文件

#include <sys/socket.h>
#include "main.h"
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#include "device.h"

在main.c中做一个判断,当网络初始化失败后亮两个灯

ret = InitSocket();      //初始化网络if (FAILURE == ret){printf("初始化网络失败\n");//初始化失败,点亮 2 个LED灯led_on(0);led_on(1);}

初始化网络,一旦连接成功后,下面就要监听,到底是按键还是网络有信息发过来

音箱的触发要么是按键触发g_buttonfd,要么是app触发g_sockfd

下面写一个函数采用select复用io来监听fd

在main.c中

m_select();

新建一个vim selec.c

#include <stdio.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>extern int g_buttonfd;
extern int g_sockfd;void show()
{printf("1、开始播放\n");printf("2、结束播放\n");printf("3、暂停播放\n");printf("4、继续播放\n");printf("5、上一首\n");printf("6、下一首\n");printf("7、增加音量\n");printf("8、减小音量\n");printf("9、顺序播放\n");printf("a、随即播放\n");printf("b、单曲循环\n");
}void m_select()
{show();fd_set readfd, tmpfd;int ret;int maxfd = (g_buttonfd > g_sockfd) ? g_buttonfd : g_sockfd;FD_ZERO(&readfd);FD_ZERO(&tmpfd);FD_SET(g_buttonfd, &readfd);FD_SET(g_sockfd, &readfd);FD_SET(0, &readfd);//标准输入添加到集合,调试用while (1){tmpfd = readfd;ret = select(g_maxfd + 1, &tmpfd, NULL, NULL, NULL);if (-1 == ret && errno != EINTR){perror("select");}else if (-1 == ret && errno == EINTR){continue;}if (FD_ISSET(g_sockfd, &tmpfd))           //TCP有数据可读{}else if (FD_ISSET(g_buttonfd, &tmpfd))    //按键有数据可读{}}
}

再开始播放音乐的时候,需要把所有音乐的名字读出来。

main.c

    //读取音乐GetMusic();

音乐的名字用链表来存储,需要初始化链表

vim main.c中

#include "main.h"
#include "device.h"
#include <stdlib.h>int g_buttonfd ;
int g_ledfd;
int g_mixerfd;
int g_sockfd ;
struct Node *head;int main()
{//初始化链表ret = InitLink();if (FAILURE == ret){printf("链表初始化失败\n");exit(1);}
}

新建一个链表link.h头文件

#ifndef LINK_H
#define LINK_Hstruct Node
{char music_name[64];struct Node *next;};
typedef struct Node Node;int InitLink();#endif

初始化链表link.c

#include <stdio.h>
#include <stdlib.h>
#include "main.h"
#include <string.h>
#include "link.h"
extern struct Node *head;//初始化链表
int InitLink()
{head = (Node *)malloc(sizeof(Node) * 1);if (NULL == head){return FAILURE;}head->next = NULL;return SUCCESS;
}

下面要读取音乐vim player.h

#ifndef PLAYER_H
#define PLAYER_H#include <unistd.h>#define MUSICPATH   "/root/music_list/"
//测试中音乐所在文件目录
#endif

下面需要从目录中获取音乐的名字放在链表中,打开目录用opendir

vim player.c

#include <stdio.h>
#include "link.h"
#include "main.h"
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include "player.h"extern Node *head;void GetMusic()
{//打开目录DIR *dir = opendir(MUSICPATH);if (NULL == dir){perror("opendir");exit(1);}struct dirent *file = NULL;//读取目录while ((file = readdir(dir)) != NULL){if (file->d_type != 8)      //不是普通文件{continue;}if (!m_mp3_end(file->d_name))   //不是mp3文件{continue;}printf("%s\n", file->d_name);    //如果是.mp3结尾,输出读取到的文件名字int ret = InsertLink(head, file->d_name); //把音乐名字插入到链表if (FAILURE == ret){printf("歌曲插入失败\n");exit(1);}}
}

判断歌曲是不是.mp3结尾是返回1不是返回0,m_mp3_end

//判断是不是.mp3结尾
int m_mp3_end(const char *name)
{const char *ptr = name; //传进来的文件名字while (*ptr != '\0')    //循环到文件名字末尾{ptr++;}int i;for (i = 0; i < 4; i++)  //因为现在ptr在\0位置,所以需要往前走四个位置定位到。MP3,运行结束在.位置{ptr--;}if (ptr < name)return 0;return (strcmp(ptr, ".mp3") == 0) ? 1 : 0; //判断是不是.mp3
}

vim link.c

int InsertLink(Node *h, const char *name)
{if (NULL == h || NULL == name) //链表初始化失败为空或者传入文件名有问题为空{return FAILURE;}Node *p = h; //新建节点指向头结点while(p->next){p=p->next;  // 定位到链表最后一个位置}Node *n = (Node *)malloc(sizeof(Node) * 1);if (NULL == n){return FAILURE;}n->next = h;strcpy(n->music_name, name); //将音乐的名字写道新建的节点中p->next = n;return SUCCESS;
}

在select.c中加一个标准输入 的测试代码,后续会删除,主要用于测试功能

#include <stdio.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>extern int g_buttonfd;
extern int g_sockfd;void show()
{printf("1、开始播放\n");printf("2、结束播放\n");printf("3、暂停播放\n");printf("4、继续播放\n");printf("5、上一首\n");printf("6、下一首\n");printf("7、增加音量\n");printf("8、减小音量\n");printf("9、顺序播放\n");printf("a、随即播放\n");printf("b、单曲循环\n");
}void m_select()
{show();fd_set readfd, tmpfd;int ret;int maxfd = (g_buttonfd > g_sockfd) ? g_buttonfd : g_sockfd;FD_ZERO(&readfd);FD_ZERO(&tmpfd);FD_SET(g_buttonfd, &readfd);FD_SET(g_sockfd, &readfd);FD_SET(0, &readfd);//标准输入添加到集合,调试用while (1){tmpfd = readfd;ret = select(g_maxfd + 1, &tmpfd, NULL, NULL, NULL);if (-1 == ret && errno != EINTR){perror("select");}else if (-1 == ret && errno == EINTR){continue;}if (FD_ISSET(g_sockfd, &tmpfd))           //TCP有数据可读{}else if (FD_ISSET(g_buttonfd, &tmpfd))    //按键有数据可读{}else if(FD_ISSET(0, &tmpfd){int func;scanf(“%d”,&func);switch(func){case 1:break;case2:break;}}}
}

http://www.ppmy.cn/news/139308.html

相关文章

[转]音箱摆放位置

我们很容易理解&#xff0c;所谓音箱就是还原声音的&#xff0c;那么从音箱出来的自然就是录音现场的声音&#xff0c;也就是所谓的重现当时的场景。 人的耳朵是一个非常奇妙的东西&#xff0c;尤其是对于声波达到左右耳的时间差和强度差的感知非常灵敏。同时&#xff0c;如果…

云音箱服务器对接

一、 云音箱工作原理 通过流程图介绍云音箱的工作原理 二、 4G 云音箱写码 设置云音箱的服务器参数&#xff0c;及配置参数 三、 通用网络协议 云音箱默认支持的网络协议&#xff0c;服务器根据协议选择性进行对接。 四、 4G 云 音 箱 服 务 器 对 接 1、自建 MQTT 接入指…

音箱箱体的分类(二)

如今&#xff0c;按照箱体的不同结构来分类&#xff0c;有密闭式音箱、倒相式音箱、迷宫式音箱、声波管式音箱和多腔谐振式音箱等。今天&#xff0c;给大家介绍常见的两种音箱——密闭式音箱和倒相式音箱。 密闭式音箱其结构上除了扬声器孔外其余部分都是密封的&#xff0c;这…

耳机及音响--煲机软件

煲机软件 煲机通俗的解释就是一种快速使器材老化稳定的措施&#xff0c;一般新买的耳机听音乐并不是音效最佳的时候&#xff0c;而是像电脑一样需要一个磨合期&#xff0c;一定老化程度后的音效才是最佳的&#xff0c;因此耳机煲机软件就可以帮助耳机快速达到最佳音效的效果。…

关于煲耳机的探讨

发烧鱼 &#xff1a;最 近经常有网友询问我如何去煲耳机&#xff0c;其实我一直不太赞成刻意去煲一副耳机&#xff0c;因为煲得好的话只不过让它快一些进入状态&#xff0c;比如HD600&#xff0c;如果天天听2小时左右 的话&#xff0c;原来需要1个月才能进入状态&#xff0c;但…

电脑外设-煲耳机

何谓煲耳机 没想到此文章在这里有如此多的阅读量&#xff0c;那么&#xff0c;先说几句题外话。 &#xff01;用耳机听音乐时间过长对听力会造成不可挽回的影响 珍惜耳朵 每次听半小时就休息一下。 &#xff01;&#xff01;买耳机有三点要注意 &#xff1a;1、量力而行&#x…

fatal: unable to connect to github.com

1.背景 下载这个项目vue-element-admin-master的依赖的时候报错 npm ERR! Error while executing: npm ERR! D:\Program File\11_git\Git\mingw64\bin\git.EXE ls-remote -h -t git://://github.com/nhn/raphael.git npm ERR! npm ERR! fatal: unable to connect to github.c…

“煲”耳塞

Q:为什么要“煲”耳塞 A: 随身听爱好者们常常会拥有一副好的耳塞&#xff0c;但在开始使用时发现并没有像其他人谈论的这么好&#xff0c;难道是自己买到了假货&#xff1f;非也&#xff01;其实那是因为没有进行购买后的第一道工序——“煲”。 为什么要“煲”耳塞 其实在音…