I'm new with PulseAudio. I'm trying to make simple programs. One would record the sound and save it in baniry file, and the other one should open it and play. Here is my code for recording:
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#define BUFSIZE 32
int main(int argc, char*argv[])
{
/* The Sample format to use */
static const pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE, //16bit iqneba agwerili tito sample
.rate = 44100, //number of samples played in each second
.channels = 2
};
pa_simple *s_in = NULL;
int ret = 1;
int error;
int siri =0;
//file info
FILE* pFile;
char* yourFilePath = "xma.bin";
pFile = fopen(yourFilePath,"wb");
if (!(s_in = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error)))
{
fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
goto finish;
}
for (;siri<10000;siri+=1)
{
uint8_t buf[BUFSIZE];
ssize_t r;
int yorBufferSize = strlen(buf) + 1;
/* Write your buffer to disk. */
if (pa_simple_read(s_in, buf, sizeof(buf), &error) < 0)
{
fprintf(stderr, __FILE__": read() failed: %s\n", strerror(errno));
goto finish;
}
if (pFile)
{
fwrite(buf, yorBufferSize, 1, pFile);
puts("Wrote to file!");
}
else
{
puts("Something wrong writing to File.");
}
}
ret = 0;
finish:
if (s_in)
pa_simple_free(s_in);
return ret;
fclose(pFile);
}
And here is my recording program:
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#define BUFSIZE 32
int main(int argc, char*argv[])
{
/* The Sample format to use */
static const pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE, //16bit iqneba agwerili tito sample
.rate = 44100, //number of samples played in each second
.channels = 2
};
pa_simple *s_out = NULL;
int ret = 1;
int error;
//file info
FILE* pFile;
char* yourFilePath = "xma.bin";
pFile = fopen(yourFilePath, "rb");
/* Create a new playback stream */
if (!(s_out = pa_simple_new(NULL, argv[0], PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error)))
{
fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
goto finish;
}
for (;;)
{
uint8_t buf[BUFSIZE];
fread(buf, sizeof(buf), 1, pFile);
ssize_t r;
if(feof(pFile))
{
break;
}
printf("%x", buf);
/* ... and play it */
if (pa_simple_write(s_out, buf, sizeof(buf), &error) < 0)
{
fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error));
goto finish;
}
}
/* Make sure that every single sample was played */
if (pa_simple_drain(s_out, &error) < 0)
{
fprintf(stderr, __FILE__": pa_simple_drain() failed: %s\n", pa_strerror(error));
goto finish;
}
ret = 0;
finish:
if (s_out)
pa_simple_free(s_out);
return ret;
fclose(pFile);
}
For loop in record program is just for time to record something(could not figure out how to set a timer) and I know that I should not use gotos but its for educational purposes(example provided on PulseAudio website). I tried hexdump of xma.bin and it gave me totally different ouput
than printf("%x", buf); Basically printf only gives back bf9fe15c repeatedly and it make annoying sound. Hope you can help. thanks.
I deleted pa_simple_drain() (it was my mistake that i used this function in recording program)function from record program and now it works. But in printf("%x", buf) it still gives me back same hex value over and over again. But programs work great. Can someone exmplain why does it print same value?
Related
I'm writing my very first C program and I was really doing well. The application talks to RESTful server. All was good until I decided to use an embedded database(libdb) for storage. I got this code below that was part of my entire program. My problem is it keeps on crashing on this line:
my_archive->db_home_dir = DEFAULT_HOMEDIR;
I thought I was running out of stack so I malloc'd all my lengthy variables but the problem was still occuring so I decided to separate this libdb part into a new code, but the problem still remains.
Any idea what has gone wrong here?
P.S. I'm doing all the coding in Xcode and stepping through each line after debug breakpoint right after main() doesn't help me a bit. Always ends up on the same error line. Or perhaps I just don't know what I'm doing.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>
#include "db.h"
#define DEFAULT_HOMEDIR "/Users/mark/Documents/bdb/"
#define URLSDB "urls"
typedef struct archive_dbs {
DB *URLS_dbp;
char *db_home_dir;
char *URLS_db_name;
} ARCHIVE_DBS;
void initialize_archivedbs(ARCHIVE_DBS *my_archive)
{
my_archive->db_home_dir = DEFAULT_HOMEDIR; //CRASHES HERE: Thread 1: EXC_BAD_ACCESS (code=2, address=0x1000061da)
my_archive->URLS_dbp = NULL;
my_archive->URLS_db_name = NULL;
}
void set_db_filenames(ARCHIVE_DBS *my_archive)
{
size_t size;
size = strlen(my_archive->db_home_dir) + strlen(URLSDB) + 1;
my_archive->URLS_db_name = malloc(size);
snprintf(my_archive->URLS_db_name, size, "%s%s", my_archive->db_home_dir, URLSDB);
}
int open_database(DB **dbpp, const char *file_name, const char *program_name, FILE *error_file_pointer)
{
DB *dbp;
u_int32_t open_flags;
int ret;
ret = db_create(&dbp, NULL, 0);
if (ret != 0) {
fprintf(error_file_pointer, "%s: %s\n", program_name,
db_strerror(ret));
return(ret);
}
*dbpp = dbp;
dbp->set_errfile(dbp, error_file_pointer);
dbp->set_errpfx(dbp, program_name);
open_flags = DB_CREATE;
ret = dbp->open(dbp,
NULL,
file_name,
NULL,
DB_BTREE,
open_flags,
0);
if (ret != 0) {
dbp->err(dbp, ret, "Database '%s' open failed.", file_name);
return(ret);
}
return (0);
}
int databases_setup(ARCHIVE_DBS *my_archive, const char *program_name, FILE *error_file_pointer)
{
int ret;
ret = open_database(&(my_archive->URLS_dbp), my_archive->URLS_db_name, program_name, error_file_pointer);
if (ret != 0)
return (ret);
printf("databases opened successfully\n");
return (0);
}
int databases_close(ARCHIVE_DBS *my_archive)
{
int ret;
if (my_archive->URLS_dbp != NULL) {
ret = my_archive->URLS_dbp->close(my_archive->URLS_dbp, 0);
if (ret != 0)
fprintf(stderr, "URLS database close failed: %s\n",
db_strerror(ret));
}
printf("databases closed.\n");
return (0);
}
int main(void){
ARCHIVE_DBS *archivedbs;
initialize_archivedbs(archivedbs);
set_db_filenames(archivedbs);
databases_setup(archivedbs, "urlfetcher", NULL);
open_database(&archivedbs->URLS_dbp, "URLS.db", "urlfetcher",
NULL);
databases_close(archivedbs);
}
Teh function below causes a segmentation fault when it gets to the RSA_verify() part. I'm a c-beginner so it's hard for me to find the reason for the problem. Maybe someone can point out what I'm doing wrong. It would be very helpful, thanks in advance.
Here's the Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#define BUF 20000
#define DSS 20
int matchCipherToSign(unsigned char *signPath, char *cipherPath) {
unsigned char *bufCipher = malloc(BUF);
unsigned char *sha = malloc(SHA_DIGEST_LENGTH);
unsigned char *bufSign = malloc(BUF);
unsigned int retSign;
int ret=0;
int retCipher;
FILE *key;
RSA *rsa = RSA_new();
EVP_MD_CTX ctx;
key = fopen("key.bin", "rb");
if (key == NULL){
printf("Couldn't open file key.bin.\n");
exit(EXIT_FAILURE);
}
retSign = readFile(signPath, bufSign);
if (retSign == 0){
printf("Couldn't read file %s.\n", signPath);
exit(EXIT_FAILURE);
}
retCipher = readFile(cipherPath, bufCipher);
if (retCipher == 0){
printf("Couldn't open file %s.\n", cipherPath);
exit(EXIT_FAILURE);
}
rsa = PEM_read_RSA_PUBKEY(key, &rsa, NULL, NULL);
fclose(key);
if (1!=EVP_DigestInit(&ctx, EVP_sha1())) {
printf("EVP_DigestInit Error.\n");
exit(EXIT_FAILURE);
}
if (1!=EVP_DigestUpdate(&ctx, bufCipher, retCipher)) {
printf("VP_DigestUpdate Error.\n");
exit(EXIT_FAILURE);
}
if (1!=EVP_DigestFinal(&ctx, sha, NULL)) {
printf("EVP_DigestFinal Error.\n");
exit(EXIT_FAILURE);
}
ret = RSA_verify(NID_sha1, sha, SHA_DIGEST_LENGTH, bufSign, sizeof(bufSign), rsa);
RSA_free(rsa);
free(bufCipher);
free(bufSign);
free(sha);
return ret;
}
Thanks for your help!
utimensat() updates ctime when restoring atime and/or mtime, but I need to restore all 3 timestamps. I solved this in a tricky way, by saving the current clock, moving system clock to the needed ctime, calling utimensat(), restoring current clock.
It does the job, but I understand this is a bad solution, so I'm looking for a better one, all in (root) userspace without kernel mods.
Here is the code I wrote to verify utimensat() behaviour and test the solution.
/* Test utimensat() behaviour, restore also Change timestamp
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MYFILE "/home/user1/Work/myfile.txt"
static int get_timestamps(struct stat *sb, const char *descr) {
sleep(1);
if (stat(MYFILE, sb) == -1) {
perror("stat(" MYFILE ") ERROR");
return(errno);
}
char *a = ctime(&sb->st_atime);
char *m = ctime(&sb->st_mtime);
char *c = ctime(&sb->st_ctime);
printf("%s\n", descr);
printf("Last file access: %.*s.%lu\n", (int)strlen(a)-1, a, sb->st_atim.tv_nsec);
printf("Last file modification: %.*s.%lu\n", (int)strlen(m)-1, m, sb->st_mtim.tv_nsec);
printf("Last status change: %.*s.%lu\n\n", (int)strlen(c)-1, c, sb->st_ctim.tv_nsec);
return(0);
}
int main(int argc, char **argv) {
int rc = 0;
struct stat sb_original;
struct stat sb;
// Get file stats
rc = get_timestamps(&sb_original, "Initial");
if (rc) return(rc);
// Read file
FILE *myfile = fopen(MYFILE, "r");
if (myfile == NULL) {
perror("fopen(" MYFILE ") ERROR");
return(errno);
}
char buffer[10];
(void)fread(buffer, 1, 1, myfile);
(void)fclose(myfile);
rc = get_timestamps(&sb, "After fopen(); fread(); fclose()");
if (rc) return(rc);
system("touch " MYFILE);
rc = get_timestamps(&sb, "After touch");
if (rc) return(rc);
// Restore original Last Access timestamp updated after fopen(); fread(); fclose()
if (sb.st_ino) {
int have_sudo = 0;
struct timespec ts[2], tsctime, tsnow;
ts[0].tv_sec = sb_original.st_atim.tv_sec;
ts[0].tv_nsec = sb_original.st_atim.tv_nsec;
ts[1].tv_sec = sb_original.st_mtim.tv_sec;
ts[1].tv_nsec = sb_original.st_mtim.tv_nsec;
tsctime.tv_sec = sb_original.st_mtim.tv_sec;
tsctime.tv_nsec = sb_original.st_mtim.tv_nsec;
if (clock_gettime(CLOCK_REALTIME, &tsnow) < 0) {
perror("clock_gettime(CLOCK_REALTIME) ERROR");
return(errno);
}
/* ##### Fixme: is there a better way to restore all 3 timestamps? */
// Bad solution but does the job ;)
if (clock_settime(CLOCK_REALTIME, &tsctime) < 0) {
perror("clock_settime(CLOCK_REALTIME,ctime) ERROR");
if (errno != EPERM)
return(errno);
have_sudo = 1;
}
if (utimensat(0, MYFILE, ts, 0) < 0) { // This updates Change timestamp!
perror("utimensat(" MYFILE ") ERROR");
return(errno);
}
if (have_sudo && clock_settime(CLOCK_REALTIME, &tsnow) < 0) {
perror("clock_settime(CLOCK_REALTIME,now) ERROR");
return(errno);
}
rc = get_timestamps(&sb, "After utimensat()");
if (rc) return(rc);
}
return(0);
}
i am trying to record my voice from the microphone on my laptop using the simple.h pulseaudio header file into an array, but i cant seem to figure it out. Every time i record and i replay my recording , it is a high pitched beep i followed examples, etc but i can't seem to get this down can someone please help me .
I am basically hacking the example "parec-simple.c" given in the doxygen page. I've tried routing the output of buf to stdout, then using libre-office calc to plot a graph to see if the output looks anything like sound but it does not.
here is the code i used
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#define BUFSIZE 1024
FILE *output;
/* A simple routine calling UNIX write() in a loop */
void loop_write(uint8_t *data) {
register int size = 1023;
while (size > 0)
{
fprintf(output,"%"SCNu8"\n",data[size] ) ;
size --;
}
}
int main(int argc, char*argv[]) {
output = fopen("/home/donnell/output", "w");
/* The sample type to use */
static const pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE,
.rate = 41000,
.channels = 2
};
pa_simple *s = NULL;
int ret = 1;
int error;
/* Create the recording stream */
if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) {
fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
goto finish;
}
for (;;) {
uint8_t buf[BUFSIZE];
/* Record some data ... */
if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) {
fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error));
goto finish;
}
/* and write it to fle*/
loop_write(buf);
}
ret = 0;
finish:
if (s)
pa_simple_free(s);
return ret;
}
I use openssl. First off I created private/public keys, then I encrypt a string and keep the result in a file. When I try to decrypt the file my program fails. What's more, the encrypted file is different each time(I use md5sum checked). What have I missed to deal with?
/*
gcc -lssl queation.c -o test_ssl
#openssl genrsa -out test_private.key 1024
#openssl rsa -in test_private.key -pubout -out test_public.key
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<openssl/rsa.h>
#include<openssl/pem.h>
#include<openssl/err.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/netdevice.h>
#include <linux/sockios.h>
#include <linux/if.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/if_arp.h>
#include <netinet/if_ether.h>
#include <netinet/ether.h>
#include <fcntl.h>
#include <sys/socket.h>
#define OPENSSLKEY "test_private.key"
#define PUBLICKEY "test_public.key"
#define BUFFSIZE 1024
#define SIZE 1024
#define LIC_FILE "lic.rn"
#define PRTFL printf("fun = %s, line = %d\n", __FUNCTION__,__LINE__)
static char *ptr_en;
static char *p_en;
static RSA *p_rsa_public;
static FILE *fp_public;
static int flen_public, rsa_public_len;
static char *ptr_de;
static char *p_de;
static RSA *p_rsa_private;
static FILE *fp_private;
static int flen_private, rsa_private_len;
void usage( unsigned char * prog_name)
{
printf("usage: %s\n",
prog_name);
exit(1);
}
int main(int argc , char ** argv)
{
int i, ret , len;
unsigned char buf_plain[32];
unsigned char *buf_en;
unsigned char *raw_buffer;
FILE * pf_tmp;
if( argc != 1)
{
usage(argv[0]);
}
snprintf(buf_plain,sizeof(buf_plain),"this is a test line.\n");
if((fp_public=fopen(PUBLICKEY,"r"))==NULL)
{
perror("open public key file error");
ret = -1;
goto error;
}
if((p_rsa_public = PEM_read_RSA_PUBKEY(fp_public,NULL,NULL,NULL))==NULL)
{
ERR_print_errors_fp(stdout);
ret = -1;
goto error;
}
rsa_public_len=RSA_size(p_rsa_public);
p_en=(unsigned char *)malloc(rsa_public_len+1);
memset(p_en,0,rsa_public_len+1);
//printf("%s(%d)p_en = %p,rsa_public_len = %d\n", __FUNCTION__,__LINE__,p_en,rsa_public_len);
len = RSA_public_encrypt(rsa_public_len,buf_plain,p_en,p_rsa_public,RSA_NO_PADDING);
if (len !=rsa_public_len)
{
fprintf(stderr,"Error: len =%d, rsa_public_len = %d,ciphertext should match length of key\n", len,rsa_public_len);
ret = -1;
goto error;
}
pf_tmp = fopen(LIC_FILE,"w");
if( NULL == pf_tmp )
{
printf("open %s failed\n",LIC_FILE);
ret = -1;
goto error;
}
fwrite(p_en,1,128,pf_tmp);
fclose(pf_tmp);
if((fp_private=fopen(OPENSSLKEY,"r"))==NULL)
{
perror("open private key file error");
ret = -1;
goto error;
}
if((p_rsa_private=PEM_read_RSAPrivateKey(fp_private,NULL,NULL,NULL))==NULL)
{
ERR_print_errors_fp(stdout);
ret = -1;
goto error;
}
rsa_private_len = RSA_size(p_rsa_private);
pf_tmp = fopen(LIC_FILE,"r");
if( NULL == pf_tmp )
{
printf("open %s failed\n",LIC_FILE);
ret = -1;
goto error2;
}
raw_buffer = calloc(rsa_private_len,sizeof(char));
if( NULL == raw_buffer )
{
ret = -1;
goto error;
}
len = fread(raw_buffer, sizeof(char),sizeof(raw_buffer), pf_tmp);
if( len <=0 )
{
ret = -1;
goto error;
}
p_de=(unsigned char *)malloc(rsa_private_len+1);
memset(p_de,0,rsa_private_len+1);
//printf("%s(%d)p_en = %p,rsa_public_len = %d\n", __FUNCTION__,__LINE__,p_en,rsa_public_len);
len =RSA_private_decrypt (rsa_private_len,raw_buffer,p_de,p_rsa_private,RSA_NO_PADDING);
printf("%s(%d) p_de = %s\n",__FUNCTION__,__LINE__,p_de);
if ( len != rsa_private_len )
{
fprintf(stderr,"Error: ciphertext should match length of key\n");
exit(1);
}
error2:
fclose(pf_tmp);
error:
free(ptr_en);
free(ptr_de);
fclose(fp_public);
fclose(fp_private);
RSA_free(p_rsa_public);
RSA_free(p_rsa_private);
return ret;
}
It looks like you are not reading the whole file:
len = fread(raw_buffer, sizeof(char),sizeof(raw_buffer), pf_tmp);
Note that sizeof(raw_buffer) is the size of a pointer, but you wrote 128 bytes into the file (1024 bits). So you're only reading back 4 or 8 bytes and trying to decrypt that.
Try reading 128 bytes back.