Lyrics parsing under Ubuntu

We need to make clear the purpose to achieve synchronization of songs and lyrics.

1. Remove the lyrics file to memory at once.(Take Zhou Dong's "simple love" as an example)

a. Open the lyrics file FILE *fp = fopen with fopen ("simple love.lrc", "r"); (r->read-only)

b. Use fseek to position the file stream pointer to the end of the file, ftell or get the total file size;

c. Use rewind to reset the file stream pointer;

d. Request appropriate space from the heap area based on the total file size;

e. Use fread to read file data into memory;

 

2. Cut the memory data that arr points to by line'\r\n'and save it in the character pointer array char *buf[128] = {NULL};

1 strtok Function Cutting
2 //arr Lyrics pointing to memory storage
3 char *buf[128]={arr,NULL};
4 int i=0;
5 //cutting
6 while(buf[i++] = strtok(buf[i],"\r\n"));

Keep each line of lyrics in an array of pointers Remember to save the number of lines cut

3. Line by line analysis buf[0] represents line 0, buf[n] represents line n

a. First analyze the first four lines separately

Original data

[ti: Simple love]
[ar:Jay Chou]
[al:Van Tessi]
[by:cat with big face]

To get the result:

 

 

 

1 int i=0;
2 for(i=0;i<4;i++)
3 {
4     char tmp[128]="";
5     //[ti:Simple love]  -->sscanf(buf[0],"%*[^:]:%[^]]", tmp);//tmp--simple
6     buf[i];//Analysis
7 }

b. Line-by-line analysis of remaining lines inserting time + lyrics into the list

Design of chain table nodes:

1 typedef struct lrc
2 {
3      //Data Domain
4      int time;
5      char lrc[128];
6      
7      //Pointer field
8      struct lrc *next; 
9 }LRC;    

4. Analog timer i++.

The timer compares the member fields in the list for every second it walks. When the time is equal, the member field lyrics (lrc_sentence) are output.

5. Scroll screen (4 lines)

//Cursor positioning: (Note)

6. Reverse that the current lyrics are red Other lyrics are black

7. Start mplayer

Steps 6 and 7 can call someone else's API interface directly, now I paste out the code, just meaning it won't tell you anything.

main.c

 1 #include "lrc.h"
 2 #include "console.h"
 3 #include "start_mplayer.h"
 4 #include <unistd.h>
 5 
 6 int main(int argc, char *argv[])
 7 {
 8     char *lrc_condent = NULL;
 9     LRC *head = NULL;
10     char *arr[128]={lrc_condent,NULL};
11     int i = 0;
12     
13     lrc_condent = read_song_lrc("./lrc/Simple love.lrc");
14     //printf("%s",lrc_condent);
15     arr[0] = lrc_condent;
16     //Cut each line
17     while(arr[i++] = strtok(arr[i],"\r\n"));
18 
19     head = lrc_handle(arr, head);
20 
21     
22     mplayer_play("./song/love.mp3");
23     lrc_print(head);
24     
25     
26     return 0;
27 }

lrc.c

  1 #include<stdlib.h>
  2 #include <unistd.h>
  3 #include "lrc.h"
  4 #include"console.h"
  5 LRC *lrc_create_head()
  6 {
  7     LRC *head = (LRC*)calloc(1, sizeof(LRC));
  8     head->next = NULL;
  9     return head;
 10 }
 11 //Take out the lyrics
 12 char *read_song_lrc(char *lrc_name)
 13 {
 14     FILE *fp = fopen(lrc_name,"r");
 15     char *lrc_content = NULL;
 16     unsigned long int length;
 17     if(fp == NULL)
 18     {
 19         perror("fopen");
 20         return NULL;
 21     }
 22 
 23     fseek(fp,0,2);
 24     length = ftell(fp);
 25     rewind(fp);
 26     lrc_content = (char *)calloc(1,length);
 27     if (lrc_content == NULL)
 28     {
 29         perror("calloc");
 30         return NULL;
 31     }
 32 
 33     fread(lrc_content,length,1,fp);
 34     fclose(fp);
 35 
 36     return lrc_content;
 37 }
 38 //Split Lyrics
 39 void lrc_strtok(char *lrc_condent)
 40 {
 41     char *arr[128]={lrc_condent,NULL};
 42     int i = 0;
 43 
 44     while((arr[i++] = strtok(arr[i],"\r\n")));
 45     i= 0;
 46     while(arr[i] != NULL)
 47         printf("%s\n", arr[i++]);
 48 }
 49 //Sequential insertion
 50 LRC * lrc_insert(LRC *head, LRC tmp)
 51 {
 52     //1,To insert a node pi Request heap space
 53     LRC *pi = (LRC *)calloc(1,sizeof(LRC));
 54     if(pi == NULL)
 55     {
 56         perror("calloc");
 57         return head;
 58     }
 59 
 60     //2,take tmp Content is assigned to *pi
 61     *pi = tmp;
 62     pi->next = NULL;
 63 
 64     //3,struct Node pi Insertion of
 65     if(head == NULL)//Chain list does not exist
 66     {
 67         head = pi;
 68         return head;
 69     }
 70     else//existence
 71     {
 72         //a,Find Insertion Point
 73         LRC *pb = head, *pf = head;
 74         while(pb->time < pi->time && pb->next != NULL)
 75         {
 76             pf = pb;
 77             pb = pb->next;
 78         }
 79 
 80         //b,Judgment of Insertion Point
 81         if(pb->time >= pi->time)//Middle head insertion
 82         {
 83             if(pb == head)//Insert before head
 84             {
 85                 pi->next = head;
 86                 head = pi;
 87                 return head;
 88             }
 89             else//Middle insertion
 90             {
 91                 pf->next = pi;
 92                 pi->next = pb;
 93                 return head;
 94             }
 95         }
 96         else//Tail Insert
 97         {
 98             pb->next = pi;
 99             return head;
100         }
101     }
102     return head;
103 }
104 //Handle lyrics
105 LRC * lrc_handle(char *buf[128], LRC *head)
106 {
107     int i = 0;
108     //Starting singer, composer, etc.
109     char *song_infor[] = {"ti", "ar", "al", "by"};
110     
111     system("clear");
112     while(buf[i] != NULL)
113     {
114         char flag = 0;
115         sscanf(buf[i],"%*c%c", &flag);
116         if(flag >= '0' && flag <= '9')//Except for the first four lines
117         {
118             char *str_lrc = buf[i], *str_time = buf[i];
119             //Every time you encounter"["Determine if this lyric has occurred
120             while(*str_lrc == '[')
121                 str_lrc += 10;
122 
123            
124             while(*str_time == '[')
125             {
126                 LRC temp;
127                 int minute = 0, second = 0, ms = 0;
128                 //Hours and seconds to remove each node
129                 sscanf(str_time, "[%d:%d.%d]", &minute, &second, &ms);
130                 //Unified Unit to ms
131                 temp.time = minute * 60 + second + ((ms > 50)?1:0);//ms Rounding
132                  //Assign lyrics to this sub-list lrc_sentence
133                 strcpy(temp.lrc_sentence, str_lrc);
134                 //Loop inserts time into the list node
135                 head = lrc_insert(head, temp);
136                 str_time += 10;
137             }
138         }
139 
140         else
141         {
142             //Split the first four lines,Get the song title, etc.
143             
144             char tmp[128]="";
145             sscanf(buf[i], "%*[^:]:%[^]]", tmp);
146             if(i==0)
147             {
148                 cusor_moveto(17,1);
149                 printf("%s\n", tmp);
150             }
151             else if(i==1)
152             {
153                 cusor_moveto(17,2);
154                 printf("%s\n", tmp);
155             }
156             else if(i==2)
157             {
158                 cusor_moveto(17,3);
159                 printf("%s\n", tmp);
160             }
161             else if(i==3)
162             {
163                 cusor_moveto(17,4);
164                 printf("%s\n", tmp);
165             }
166         }
167         i++;
168     }
169 
170     return head;
171 }
172 //Lyrics Roll Screen
173 int times = 0;
174 int screen = 0;
175 
176 LRC* lrc_print(LRC *head)
177 {
178     int time=0;
179     char buf1[128]="";
180     char buf2[128]="";
181     char buf3[128]="";
182     char buf4[128]="";
183     while(1)
184     {
185         //Cursor positioning
186         cusor_moveto(20,6);
187         printf("%02d:%02d",time/60,time%60 );
188         fflush(stdout);
189 
190         LRC *ret = search_link(head, time);
191         if(ret != NULL)
192         {
193             //start a fist fight
194             strcpy(buf1,buf2);
195             strcpy(buf2,buf3);
196             strcpy(buf3,buf4);
197             strcpy(buf4, ret->lrc_sentence);
198             
199             cusor_moveto(15,8);
200             printf("%s                                       ", buf1);
201 
202             cusor_moveto(15,9);
203             printf("%s                                      ", buf2);
204 
205             cusor_moveto(15,10);
206             printf("%s                                           ", buf3);
207 
208             cusor_moveto(15,11);
209             set_fg_color(COLOR_RED);
210             printf("%s                                         ", buf4);//Current lyrics
211             set_fg_color(COLOR_BLACK  );
212             fflush(stdout);
213         }
214         //Roll screen display lyrics
215         //first line
216         
217 
218         sleep(1);
219         time++;
220     }
221     
222 }
223 
224 LRC* search_link(LRC *head, int time)
225 {
226     //1,Determine if a chain list exists
227     if(head == NULL)//Non-existent
228     {
229         printf("link not found\n");
230         return NULL;
231     }
232     else//Chain list exists
233     {
234         LRC *pb = head;
235 
236         //Put node by node name and name Compare If Not Equal pb=pb->next
237         while(pb->time != time && pb->next != NULL)
238             pb = pb->next;
239 
240         //Determine whether or not to find
241         if(pb->time == time)//find
242             return pb;
243         else//Can't find
244             return NULL;
245     }
246 
247     return NULL;
248 }
249 
250 void mplayer_play(char * song_path)
251 {
252     pid_t pid;
253     pid=fork();
254     if(pid<0)
255     {
256         perror("fork");
257     }
258     else if(pid==0)
259     {
260         close(1);
261         close(2);
262         execlp("mplayer","mplayer","-slave","-quiet",song_path,NULL);
263         exit(0);
264     }
265     else;
266 }

lrc.h

 1 #ifndef __LRC_H__
 2 #define __LRC_H__
 3 
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6 #include <string.h>
 7 
 8 typedef struct lrc
 9 {
10     int time;
11     char lrc_sentence[128];
12     
13     struct lrc *next;
14 }LRC;
15 //Create Chain Header
16 LRC *lrc_create_head(void);
17 //Sequential insertion
18 LRC * lrc_insert(LRC *head, LRC tmp);
19 //Read lyrics
20 char *read_song_lrc(char *lrc_name);
21 //Cut lyrics
22 void lrc_strtok(char *lrc_condent);
23 //Handle lyrics
24 LRC * lrc_handle(char *buf[128], LRC *head);
25 //Traverse lyrics
26 LRC* lrc_print(LRC *head);
27 extern LRC* search_link(LRC *head, int time);
28 void mplayer_play(char * song_path);
29 
30 #endif

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Tags: C

Posted on Thu, 19 Mar 2020 21:44:53 -0400 by fwegan