Compiling globecomice
src/globecomice.c:144: parse error before '*' token
src/globecomice.c: In function `playFile':
src/globecomice.c:151: `filename' undeclared (first use in this function)
src/globecomice.c:151: (Each undeclared identifier is reported only once
src/globecomice.c:151: for each function it appears in.)
src/globecomice.c:185: `conn' undeclared (first use in this function)
src/globecomice.c: In function `main':
src/globecomice.c:251: `shout_conn_t' undeclared (first use in this function)
src/globecomice.c:251: parse error before "conn"
src/globecomice.c:263: `conn' undeclared (first use in this function)
Icecast will not be supported (You can still use the jukebox via soundcard)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
struct MP3Header {
int ID;
int layer;
int protection;
int bitrate_index;
int sampling_freq;
int emphasis;
int version_index;
int mode;
int mode_extension;
int invalid;
/* The MP3 bitrate is interpretted liberally from the MP3::Info perl package
* although I ignore variable bitrates, hopefully that isn't a problem. The
* only thing that can actually happend is FF/Rewind going in not quite
* 10s increments.
*/
int getV2Size(int fd)
{
char id3head[10];
lseek(fd,0,0);
if (read(fd,id3head,10)!=10) {
return 0;
}
if (head.bitrate_index==15||!head.layer)
head.bitrate=0;
else
head.bitrate=bitrates[head.ID][3-head.layer][head.bitrate_index];
return head;
}
int checkMP3(struct MP3Header head)
{
if (head.bitrate_index==0)
return 0;
if (head.version_index==1)
return 0;
if (head.invalid==1)
return 0;
if (!head.bitrate)
return 0;
if (head.bitrate_index==15)
return 0;
if (!head.layer)
return 0;
if (head.sampling_freq==3)
return 0;
if (head.emphasis==2)
return 0;
if (!head.bitrate_index)
return 0;
if (head.ID==1&&head.layer==3&&head.protection==1)
return 0;
if (head.mode_extension!=0&&head.mode!=1)
return 0;
return 1;
}
int goSeek=0;
int goQuit=0;
pid_t pid=-1;
void Quit(int a)
{
goQuit=1;
}
void RealQuit(int a)
{
if (pid>=0)
kill(pid,a);
exit(0);
}
void Forward(int a)
{
goSeek++;
}
void Rewind(int a)
{
goSeek--;
}
#define BUFSIZE 4096
void playFile(shout_t *conn,char *filename)
{
int fd;
int searchsize;
int offset;
struct MP3Header head;
char* chopped_filename;
shout_metadata_t *metadata;
fd=open(filename,O_RDONLY);
if (fd<0) {
printf("Couldn't open %s\n",filename);
return;
}
if (checkMP3(head)) {
char buff[BUFSIZE];
long rbuf, ret, total=0;
int sec10=head.bitrate*1280;
metadata=shout_metadata_new();
ret=shout_metadata_add(metadata,"song",chopped_filename);
if (ret!=SHOUTERR_SUCCESS) printf ("Error adding metadata\n");
ret=shout_set_metadata(conn,metadata);
if (ret!=SHOUTERR_SUCCESS) printf ("Error setting metadata\n");
shout_metadata_free(metadata);
printf("Playing %s (%s) with bitrate %d\n",filename,chopped_filename,head.bitrate);
lseek(fd,0,0);
while (1) {
if (goSeek) {
lseek(fd,goSeek*sec10,1);
goSeek=0;
}
if (goQuit) {
goQuit=0;
//break;
}
rbuf = read(fd,buff,BUFSIZE);
if (rbuf < 0) printf("error %s\n", strerror(errno));
total = total + rbuf;
if (rbuf > 0) {
ret = shout_send(conn, buff, rbuf);
if (ret != SHOUTERR_SUCCESS) {
/* Something wrong occured (timeout?) */
printf("globecomice: Send error: %s...\n", shout_get_error(conn));
/* Try to reconnect before giving up */
printf("globecomice: Reconnecting to the icecast srver...\n");
shout_close(conn);
if (!shout_open(conn)) {
printf("globecomice: Error, couldn't reconnect to server.\n");
break;
}
/* Try to send data again */
ret = shout_send(conn, buff, rbuf);
if (ret != SHOUTERR_SUCCESS) {
printf("globecomice: Send data FAILED again: %s\n", shout_get_error(conn));
break;
}
}
} else {
break;
}
shout_sync(conn);
}
}
close(fd);
}
int getFilename(int connected,char *filename,const char *user)
{
int pipes[2];
FILE *fs;
char *pos;
if (pipe(pipes)<0) {
printf("Pipe failed\n");
exit(2);
}
pid=fork();
if (pid<0) {
printf("Fork failed\n");
exit(2);
} else if (pid==0) {
char execbuf[BUFSIZE];
sprintf(execbuf,"%s/getnextmp3.pl",getenv("JUKEBOXBIN"));
dup2(pipes[1],1);
execl(execbuf,execbuf,user,"novol",NULL);
fprintf(stderr,"Couldn't run %s\n",execbuf);
exit(2);
}
close(pipes[1]);
filename[BUFSIZE]=0;
{
int pos=read(pipes[0],filename,BUFSIZE);
pid_t died;
filename[pos]=0;
do {
int status;
died=wait(&status);
} while(died>=0);
}
close(pipes[0]);
pos=strchr(filename,'\n');
if (!pos) {
if (connected)
return 0;
do {
printf("%s\n",filename);
getFilename(1,filename,user);
sleep(5);
} while(!strlen(filename));
return 1;
}
*pos=0;
pid=-1;
return 1;
}
int main(int argc,char **argv)
{
shout_t *conn;
int connected=0;
const char *user;
char* chopped_filename;
char host[1024];
if (argc!=6) {
printf("Usage globecomice {icecasthost} {port} {password} {user} {queue}\n");
exit(1);
}
if (!getenv("JUKEBOXBIN")) {
printf("Must set environment variable JUKEBOXBIN\n");
exit(2);
}
shout_init();
conn=shout_new();
gethostname(host,1024);
Thanks for this... I had this problem in another thread, and I guess I'm getting closer with your modifications - but now globecomice.c fails compilation with the following message:
/usr/local/lib/libshout.so: undefined reference to 'pthread_create'
/usr/local/lib/libshout.so: undefined reference to 'pthread_rwlock_rdlock'
/usr/local/lib/libshout.so: undefined reference to 'pthread_rwlock_init'
/usr/local/lib/libshout.so: undefined reference to 'pthread_rwlock_destroy'
/usr/local/lib/libshout.so: undefined reference to 'pthread_rwlock_create'.....
I guess something's not right, but I have no clue as to what to try next! Any help, greatly appreciated!
Cheers,
Dave
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
How do I resolve these compile errors?
Compiling globecomice
src/globecomice.c:144: parse error before '*' token
src/globecomice.c: In function `playFile':
src/globecomice.c:151: `filename' undeclared (first use in this function)
src/globecomice.c:151: (Each undeclared identifier is reported only once
src/globecomice.c:151: for each function it appears in.)
src/globecomice.c:185: `conn' undeclared (first use in this function)
src/globecomice.c: In function `main':
src/globecomice.c:251: `shout_conn_t' undeclared (first use in this function)
src/globecomice.c:251: parse error before "conn"
src/globecomice.c:263: `conn' undeclared (first use in this function)
Icecast will not be supported (You can still use the jukebox via soundcard)
This may be the same problem as came up in https://sourceforge.net/forum/message.php?msg_id=2126880
I don't know if my advice there actually works, but it might :)
The problem seems to be a new API to the libstream library. I have ported globecomice.c to the new API. Code is pasted below:
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <shout/shout.h>
#include <string.h>
#include <unistd.h>
#define SEARCHSIZE 4096
struct MP3Header {
int ID;
int layer;
int protection;
int bitrate_index;
int sampling_freq;
int emphasis;
int version_index;
int mode;
int mode_extension;
int invalid;
int bitrate;
};
int bitrates[2][3][15]={
{
{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256},
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
},{
{0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448},
{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384},
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320}
}
};
/* The MP3 bitrate is interpretted liberally from the MP3::Info perl package
* although I ignore variable bitrates, hopefully that isn't a problem. The
* only thing that can actually happend is FF/Rewind going in not quite
* 10s increments.
*/
int getV2Size(int fd)
{
char id3head[10];
lseek(fd,0,0);
if (read(fd,id3head,10)!=10) {
return 0;
}
if (strcmp(id3head,"ID3")) {
return 0;
}
return 10+id3head[6]+id3head[7]*128+id3head[8]*128*128+id3head[9]+128*128*128;
}
struct MP3Header getHead(int fd,int offset)
{
unsigned char data[4];
unsigned long info;
struct MP3Header head;
lseek(fd,offset,0);
read(fd,data,4);
info=data[0]*0x1000000+data[1]*0x10000+data[2]*0x100+data[3];
head.ID=(info>>19)&1;
head.layer=(info>>17)&3;
head.protection=(info>>16)&1;
head.bitrate_index=(info>>12)&15;
head.sampling_freq=(info>>10)&3;
head.emphasis=info&3;
head.version_index=(info>>19)&3;
head.mode=(info>>6)&3;
head.mode_extension=(info>>4)&3;
head.invalid=((info&0xffff0000)==0xfffe0000)||((info&0xffe00000)!=0xffe00000);
if (head.bitrate_index==15||!head.layer)
head.bitrate=0;
else
head.bitrate=bitrates[head.ID][3-head.layer][head.bitrate_index];
return head;
}
int checkMP3(struct MP3Header head)
{
if (head.bitrate_index==0)
return 0;
if (head.version_index==1)
return 0;
if (head.invalid==1)
return 0;
if (!head.bitrate)
return 0;
if (head.bitrate_index==15)
return 0;
if (!head.layer)
return 0;
if (head.sampling_freq==3)
return 0;
if (head.emphasis==2)
return 0;
if (!head.bitrate_index)
return 0;
if (head.ID==1&&head.layer==3&&head.protection==1)
return 0;
if (head.mode_extension!=0&&head.mode!=1)
return 0;
return 1;
}
int goSeek=0;
int goQuit=0;
pid_t pid=-1;
void Quit(int a)
{
goQuit=1;
}
void RealQuit(int a)
{
if (pid>=0)
kill(pid,a);
exit(0);
}
void Forward(int a)
{
goSeek++;
}
void Rewind(int a)
{
goSeek--;
}
#define BUFSIZE 4096
void playFile(shout_t *conn,char *filename)
{
int fd;
int searchsize;
int offset;
struct MP3Header head;
char* chopped_filename;
shout_metadata_t *metadata;
fd=open(filename,O_RDONLY);
if (fd<0) {
printf("Couldn't open %s\n",filename);
return;
}
searchsize=SEARCHSIZE;
offset=getV2Size(fd);
searchsize+=offset;
do {
head=getHead(fd,offset);
offset++;
} while(!checkMP3(head)&&offset<searchsize);
chopped_filename = (char*)malloc(strlen(filename)*sizeof(char));
strcpy(chopped_filename, filename);
chopped_filename[strlen(chopped_filename)-4] = '\0';
chopped_filename = chopped_filename+(strlen(chopped_filename)-1);
while ((*chopped_filename != '/') && (*chopped_filename != '\0'))
chopped_filename--;
chopped_filename++;
if (checkMP3(head)) {
char buff[BUFSIZE];
long rbuf, ret, total=0;
int sec10=head.bitrate*1280;
metadata=shout_metadata_new();
ret=shout_metadata_add(metadata,"song",chopped_filename);
if (ret!=SHOUTERR_SUCCESS) printf ("Error adding metadata\n");
ret=shout_set_metadata(conn,metadata);
if (ret!=SHOUTERR_SUCCESS) printf ("Error setting metadata\n");
shout_metadata_free(metadata);
printf("Playing %s (%s) with bitrate %d\n",filename,chopped_filename,head.bitrate);
lseek(fd,0,0);
while (1) {
if (goSeek) {
lseek(fd,goSeek*sec10,1);
goSeek=0;
}
if (goQuit) {
goQuit=0;
//break;
}
rbuf = read(fd,buff,BUFSIZE);
if (rbuf < 0) printf("error %s\n", strerror(errno));
total = total + rbuf;
if (rbuf > 0) {
ret = shout_send(conn, buff, rbuf);
if (ret != SHOUTERR_SUCCESS) {
/* Something wrong occured (timeout?) */
printf("globecomice: Send error: %s...\n", shout_get_error(conn));
/* Try to reconnect before giving up */
printf("globecomice: Reconnecting to the icecast srver...\n");
shout_close(conn);
if (!shout_open(conn)) {
printf("globecomice: Error, couldn't reconnect to server.\n");
break;
}
/* Try to send data again */
ret = shout_send(conn, buff, rbuf);
if (ret != SHOUTERR_SUCCESS) {
printf("globecomice: Send data FAILED again: %s\n", shout_get_error(conn));
break;
}
}
} else {
break;
}
shout_sync(conn);
}
}
close(fd);
}
int getFilename(int connected,char *filename,const char *user)
{
int pipes[2];
FILE *fs;
char *pos;
if (pipe(pipes)<0) {
printf("Pipe failed\n");
exit(2);
}
pid=fork();
if (pid<0) {
printf("Fork failed\n");
exit(2);
} else if (pid==0) {
char execbuf[BUFSIZE];
sprintf(execbuf,"%s/getnextmp3.pl",getenv("JUKEBOXBIN"));
dup2(pipes[1],1);
execl(execbuf,execbuf,user,"novol",NULL);
fprintf(stderr,"Couldn't run %s\n",execbuf);
exit(2);
}
close(pipes[1]);
filename[BUFSIZE]=0;
{
int pos=read(pipes[0],filename,BUFSIZE);
pid_t died;
filename[pos]=0;
do {
int status;
died=wait(&status);
} while(died>=0);
}
close(pipes[0]);
pos=strchr(filename,'\n');
if (!pos) {
if (connected)
return 0;
do {
printf("%s\n",filename);
getFilename(1,filename,user);
sleep(5);
} while(!strlen(filename));
return 1;
}
*pos=0;
pid=-1;
return 1;
}
int main(int argc,char **argv)
{
shout_t *conn;
int connected=0;
const char *user;
char* chopped_filename;
char host[1024];
if (argc!=6) {
printf("Usage globecomice {icecasthost} {port} {password} {user} {queue}\n");
exit(1);
}
if (!getenv("JUKEBOXBIN")) {
printf("Must set environment variable JUKEBOXBIN\n");
exit(2);
}
shout_init();
conn=shout_new();
gethostname(host,1024);
shout_set_host(conn,argv[1]);
shout_set_port(conn,atoi(argv[2]));
shout_set_password(conn,argv[3]);
shout_set_mount(conn,argv[5]);
shout_set_name(conn,host);
shout_set_description(conn,"GlobeCom Jukebox");
shout_set_protocol(conn,SHOUT_PROTOCOL_HTTP);
shout_set_format(conn,SHOUT_FORMAT_MP3);
shout_open(conn);
user=argv[4];
signal(SIGINT,Forward);
signal(SIGQUIT,Quit);
signal(SIGHUP,Rewind);
signal(SIGABRT,Quit);
signal(SIGTERM,RealQuit);
while(1) {
char filename[BUFSIZE+1];
if (!getFilename(connected,filename,user)) {
shout_close(conn);
exit(1);
}
if (!connected) {
if (shout_get_connected(conn) != SHOUTERR_CONNECTED) {
printf("Couldn't connect to icecast server: %s\n",shout_get_error(conn));
exit(2);
}
connected=1;
}
playFile(conn,filename);
}
}
Oops - I meant libshout and not libstream
Thanks for this... I had this problem in another thread, and I guess I'm getting closer with your modifications - but now globecomice.c fails compilation with the following message:
/usr/local/lib/libshout.so: undefined reference to 'pthread_create'
/usr/local/lib/libshout.so: undefined reference to 'pthread_rwlock_rdlock'
/usr/local/lib/libshout.so: undefined reference to 'pthread_rwlock_init'
/usr/local/lib/libshout.so: undefined reference to 'pthread_rwlock_destroy'
/usr/local/lib/libshout.so: undefined reference to 'pthread_rwlock_create'.....
I guess something's not right, but I have no clue as to what to try next! Any help, greatly appreciated!
Cheers,
Dave
Have a look at
https://sourceforge.net/forum/message.php?msg_id=2060132
I suspect this may be the same issue.