I tried to create a c code that produce 10 sec of C note. But it seem the output .wav file didn't produce any sound.
I'm still new in C programming and it would be helpful if you can point my mistakes.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//music note
#define C 261.6256
#define TIME 10
#define POINT 20
#define AMP 10000
#define c 5
//wav file header
typedef struct
{
char ChuckID[4];
unsigned long ChuckSize;
char format[4];
char subChunk1ID[4];
unsigned long SubChunk1Size;
unsigned short AudioFormat;
unsigned short NumChannels;
unsigned long SampleRate;
unsigned long ByteRate;
unsigned short block_allign;
unsigned short bits_per_sample;
char data[4];
unsigned long data_size;
/*char riff_tag[4];
int riff_length;
char wave_tag[4];
char fmt_tag[4];
int fmt_length;
short audio_format;
short num_channels;
int sample_rate;
int byte_rate;
short block_align;
short bits_per_sample;
char data_tag[4];
int data_length;*/
} wavheader;
int main(int argc, char **argv)
{
wavheader wave = {"RIFF",1764036,"WAVE","fmt",16,1,1,44100,176400,4,32,"data",1764000};
float data;
float f = C;
int fs = 44100;
int k;
float *buff;
FILE *out_file = fopen("ongaku.wav","w");
buff = (float*)malloc(sizeof(float)*fs*TIME);
for (k = 0; k<(int)(TIME*fs); k++)
{
data=AMP*sin(2*M_PI*f*k/fs);
//printf("%f\n",data);
}
fwrite(buff,sizeof(float),fs*TIME,out_file);
return 0;
}
I have this working with 8-bit data but unsuccessful with 12/16-bit let alone float data. One thing that's essential, is not to hard code buffer sizes in the header. Other points to watch out for are endian-ness (I happened not to need to adjust), and structure packing (ditto). My use of BPS/8 would also come unstuck when working with 12-bit data.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define FREQ 261.6256 // C
//#define FREQ 440.0 // A
#define M_PI 3.14159265358979323846
#define TIME 10
#define AMP 64.0 // don't use max volume
#define MID 128.0 // 8-bit is range 0..255
//#define MID 0.0 // 16-bit is range -32767.. 32767
#define BPS 8
#define CHANNS 1
#define RATE 44100
//wav file header
typedef struct {
char ChuckID[4];
unsigned long ChuckSize;
char format[4];
char subChunk1ID[4];
unsigned long SubChunk1Size;
unsigned short AudioFormat;
unsigned short NumChannels;
unsigned long SampleRate;
unsigned long ByteRate;
unsigned short block_allign;
unsigned short bits_per_sample;
char data[4];
unsigned long data_size;
} wavheader;
int main(int argc, char **argv)
{
int k, samples = RATE * TIME;
double data;
FILE *out_file;
unsigned char *buff;
wavheader wave = {
"RIFF",
36 + samples * CHANNS * BPS/8,
"WAVE",
"fmt ", // "fmt" was error in OP
16,
1,
CHANNS,
RATE,
RATE * CHANNS * BPS/8,
CHANNS * BPS/8,
BPS,
"data",
samples * CHANNS * BPS/8
};
buff = malloc(BPS/8 * samples);
out_file = fopen("ongaku.wav","w");
fwrite(&wave, sizeof(wave), 1, out_file);
for (k=0; k<samples; k++) {
data = MID + AMP * sin(2 * M_PI * FREQ * TIME * k / (double)samples);
buff[k] = (unsigned char)floor(data+0.5);
}
fwrite(buff, BPS/8, samples, out_file);
fclose (out_file);
free (buff);
return 0;
}
Put some data into buff, I guess your data variable is holding that value. and after that
if everything else is working correctly, use
fflush(out_file);
or use
fclose(out_file);
Related
This is simple code; I am using this code snippet in my project and its working fine.
My question if it is the best way or otherwise What is the best way to set the bit fields using loops in C?
#define NUM_OF_MAX_SENSOR 10
typedef float SENSOR_VAL ;
typedef struct
{
unsigned char bit0:1;
unsigned char bit1:1;
unsigned char bit2:1;
unsigned char bit3:1;
unsigned char bit4:1;
unsigned char bit5:1;
unsigned char bit6:1;
unsigned char bit7:1;
}BYTE_FIELD;
typedef struct
{
BYTE_FIELD funP1;
BYTE_FIELD funP2;
}LOG_DATA;
LOG_DATA xlog;
typedef struct
{
unsigned char ok:1;
unsigned char open:1;
unsigned char shrt:1;
unsigned char unused:5;
}SENSOR_FLAGS;
typedef struct
{
SENSOR_FLAGS flag;
SENSOR_VAL val;
}SENSOR_DATA;
typedef union
{
SENSOR_DATA sensor[NUM_OF_MAX_SENSOR];
unsigned char buff[sizeof(SENSOR_DATA) * NUM_OF_MAX_SENSOR];
}SENSOR;
SENSOR sensor;
These are the structures I used and these are the max details I can provide.
void UpdateLogData()
{
int i = 0;
unsigned char *funPAddr =(unsigned char *) &xlog.funP1;
for(i=0;i<8;i++)
*(funPAddr) |= sensor.sensor[i].flag.ok << i;
printf("0x%x",*(funPAddr));
}
//main
int main()
{
sensor.sensor[0].flag.ok = 1;
sensor.sensor[4].flag.ok = 1;
sensor.sensor[5].flag.ok = 1;
sensor.sensor[6].flag.ok = 1;
sensor.sensor[7].flag.ok = 1;
UpdateLogData();
}
I have a struct like the following:
struct Foo {
unsigned int id;
unsigned int flag_1 : 1;
unsigned int flag_2 : 1;
unsigned int flag_3 : 1;
// Some arbitrary number of further flags. Code is
// automatically generated and number will vary.
// Notably, it may be more than an int's worth.
int some_data;
float some_more_data;
// ...
};
From time to time, I need to reset all the flags to zero while preserving the rest of the struct. One way is obviously to set each flag to 0 individually, but it feels like there ought to be a way to do it in one fell swoop. Is that possible?
(Note that I am open to not using bit fields, but this is code that will sometimes run on memory-contrained systems, so the memory savings are very appealing.)
Edit:
There is a similar question here: Reset all bits in a c bitfield
However, the struct in that question is entirely bitfields. I cannot simply memset the entire struct to zero here, and the other answer involving unions is not guaranteed to work, especially if there are more than an int's worth of flags.
Just use a separate struct for the flags:
struct Foo_flags {
unsigned int flag_1 : 1;
unsigned int flag_2 : 1;
unsigned int flag_3 : 1;
// ...
};
struct Foo {
unsigned int id;
struct Foo_flags flags;
int some_data;
float some_more_data;
// ...
};
Or even a simpler nested struct:
struct Foo {
unsigned int id;
struct {
unsigned int flag_1 : 1;
unsigned int flag_2 : 1;
unsigned int flag_3 : 1;
// ...
} flags;
int some_data;
float some_more_data;
// ...
};
Then, later in your code:
struct Foo x;
// ...
x.flags.flag_1 = 1;
// ...
memset(&x.flags, 0, sizeof(x.flags));
With some minor adjustments, you can use the offsetof macro to find the beginning and end of the "flag" data within the structure, then use memset to clear the relevant memory. (Note that you cannot use offsetof directly on bitfields, hence the addition of the flag_beg member!)
Here's a working example:
#include <stdio.h>
#include <stddef.h> // defines offsetof
#include <string.h> // declares memset
struct Foo {
unsigned int id;
unsigned int flag_beg; // Could be unsigned char to save space
unsigned int flag_1 : 1;
unsigned int flag_2 : 1;
unsigned int flag_3 : 1;
unsigned int flag_end; // Could be unsigned char to save space
// Some arbitrary number of further flags. Code is
// automatically generated and number will vary.
// Notably, it may be more than an int's worth.
int some_data;
float some_more_data;
// ...
};
#define FBEG (offsetof(struct Foo, flag_beg))
#define FEND (offsetof(struct Foo, flag_end))
int main()
{
struct Foo f;
f.id = 3; f.flag_1 = 1; f.flag_2 = 0; f.flag_3 = 1;
f.some_data = 33; f.some_more_data = 16.2f;
printf("%u %u %u %u %d %f\n", f.id, f.flag_1, f.flag_2, f.flag_3, f.some_data, f.some_more_data);
memset((char*)(&f) + FBEG, 0, FEND - FBEG);
printf("%u %u %u %u %d %f\n", f.id, f.flag_1, f.flag_2, f.flag_3, f.some_data, f.some_more_data);
return 0;
}
While I am running this md5 code, it is taking maximum 64 characters length of input at run time. Whenever I am giving more than 64 characters, it is showing
Inconsistency detected by ld.so: dl-fini.c: 205: _dl_fini: Assertion ns != 0 || i == nloaded failed!
I need to hash nearly 10kb of input (only string). Do I need to change anything in the header file? Can anyone tell me solution please?
md5.h
#ifndef HEADER_MD5_H
#define HEADER_MD5_H
#include <openssl/e_os2.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef OPENSSL_NO_MD5
#error MD5 is disabled.
#endif
/*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* ! MD5_LONG has to be at least 32 bits wide. If it's wider, then !
* ! MD5_LONG_LOG2 has to be defined along. !
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/
#if defined(__LP64__)
#define MD5_LONG unsigned long
#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
#define MD5_LONG unsigned long
#define MD5_LONG_LOG2 3
/*
* _CRAY note. I could declare short, but I have no idea what impact
* does it have on performance on none-T3E machines. I could declare
* int, but at least on C90 sizeof(int) can be chosen at compile time.
* So I've chosen long...
* <appro#fy.chalmers.se>
*/
#else
#define MD5_LONG unsigned long
#endif
#define MD5_CBLOCK 64
#define MD5_LBLOCK (MD5_CBLOCK/2)
#define MD5_DIGEST_LENGTH 16
typedef struct MD5state_st
{
MD5_LONG A,B,C,D;
MD5_LONG Nl,Nh;
MD5_LONG data[MD5_LBLOCK];
unsigned int num;
} MD5_CTX;
#ifdef OPENSSL_FIPS
int private_MD5_Init(MD5_CTX *c);
#endif
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
void MD5_Transform(MD5_CTX *c, const unsigned char *b);
#ifdef __cplusplus
}
#endif
#endif
md5.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "md5.h"
char *pt(char *, int );
int main(int argc, char **argv)
{
char *in;
char *out;
printf("ENter the string\n");
scanf("%[^\n]s",in);
size_t len; //unsigned long len; size_t len;
len = printf("len is %d\n",strlen(in));
out = pt(in, len);
printf("MD5 is\t: %s\n", out);
free(out);
//return 0;
}
char *pt(char *str, int length)
{
int n;
MD5_CTX c;
unsigned char digest[16];
char *output = (char*)malloc(33);
MD5_Init(&c);
MD5_Update(&c, str, length);
MD5_Final(digest, &c);
for (n = 0; n < 16; ++n)
{
sprintf(&output[n*2], "%02x", (unsigned int)digest[n]);
}
return output;
}
Problem 1
For this statement:
scanf("%[^\n]s",in);
When I compile it using the -Wall flag, I get the warning:
warning: 'in' is used uninitialized in this function [-Wuninitialized]
scanf("%[^\n]s",in);
^
As you see, in is not pointing to any location in your memory, so you first need to allocate some memory either with an array or malloc():
char in[500]; //or a higher value
char *out;
printf("Enter the string\n");
scanf("%499[^\n]s", in);
printf("\nin = .%s.\n", in);
or
char *in;
char *out;
in = malloc(500); //or a higher value
printf("Enter the string\n");
scanf("%499[^\n]s", in);
printf("\nin = .%s.\n", in);
Possible problem 2
You are assigning the return from printf() to the variable len.
len = printf("len is %d\n",strlen(in));
Return value printf:
Upon successful return, it returns the number of characters printed (excluding the null byte used to end output to strings).
Assuming you want the variable len to contain the length of the string in and not the number of characters printed by printf("len is %d\n",strlen(in)), you might want to assign the return from strlen() first:
len = strlen(in);
printf("len is %d\n", len);
Here's my code snippet that fails:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct WAV {
char chunkId[4];
unsigned chunkSize;
char format[4];
char subChunk1Id[4];
unsigned subChunk1Size;
unsigned short audioFormat;
unsigned short numChannels;
unsigned sampleRate;
unsigned byteRate;
unsigned short blockAlign;
unsigned short bitsPerSample;
char subChunk2Id[4];
unsigned subChunk2Size;
} WAV;
int main() {
void printwav(const WAV *);
void openwav(FILE *, WAV *);
void makewav(FILE *, const WAV *);
char file[FILENAME_MAX];
size_t i;
short
stereo1,
stereo2,
mono1;
FILE
*fpstereo,
*fpmono;
WAV
stereo,
mono;
openwav(fpstereo, &stereo);
printwav(&stereo);
memcpy(&mono, &stereo, sizeof(WAV));
mono.chunkSize -= stereo.subChunk2Size / 2;
mono.subChunk2Size /= 2;
mono.numChannels /= 2;
mono.byteRate /= 2;
mono.blockAlign /= 2;
makewav(fpmono, &mono);
printwav(&mono);
for (i = 0; i < mono.subChunk2Size / sizeof(short); i++) {
fread(&stereo1, sizeof(short), 1, fpstereo);
fread(&stereo2, sizeof(short), 1, fpstereo);
mono1 = (stereo1 + stereo2) / 2;
fwrite(&mono1, sizeof(short), 1, fpmono);
}
fclose(fpstereo);
fclose(fpmono);
}
And my output for the program is:
Enter filepath to stereo WAV: wav11stereo.wav
RIFF
1966116
WAVE
fmt
16
1
2
44100
176400
4
16
data
1966080
Enter filepath to mono WAV: wav11mono.wav
RIFF
983076
WAVE
fmt
16
1
1
44100
88200
2
16
data
983040
Segmentation fault: 11
After testing with a bunch of printfs, I discovered the segmentation fault occurs in the line fread(&stereo1, sizeof(short), 1, fpstereo); inside the for-loop. I declared stereo1 as a short and not a short *, so I don't understand why that's happening. Can anyone explain why that's wrong?
I guess this is your problem:
void openwav(FILE *, WAV *);
void makewav(FILE *, WAV *);
With this, file open call inside the function will only available inside the function and not returned to the caller.
Normally it should be declared as below:
void openwav(FILE **, WAV *);
void makewav(FILE **, WAV *);
And call like this:
openwav(&fpstereo, &stereo);
makewav(&fpmono, &mono);
I am trying to read 1 block of first hard drive into the memory. I tried with different LBAs but it loads spaces in to the buffer. In following code, i added for loop so that i can see if it loads anything else than just spaces. Do you guys know why it's only loading spaces into the buffer?
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <bios.h>
struct DAP
{
unsigned char size;
unsigned char reserved1;
unsigned char blocks;
unsigned char reserved2;
unsigned char far *buffer;
unsigned long int lbalod;
unsigned long int lbahid;
} dap;
char st[80];
unsigned char buf[512];
FILE *fptr;
unsigned long int itrations = 16450559; //10gb
unsigned long int i = 0;
void main(void)
{
clrscr();
for(; i<itrations; i++)
{
dap.size = sizeof(dap);
dap.reserved1 = 0;
dap.blocks = 1;
dap.reserved2 = 0;
dap.buffer = (unsigned char far *)MK_FP(_DS, buf);
dap.lbalod = i;
dap.lbahid = 0;
_AH = 0x42;
_DL = 0x80;
_SI = (unsigned int)&dap;
geninterrupt(0x13);
printf("%lu: %s\n", i, buf);
}
}
It's using Borland Turbo C over VMWare virtual machine that is setup with WinXP. I have also tried the same on DOSBOX on Windows 7. Any help would be much appreciated.
These are only my suggestions in the hope that they help your debugging.
Print sizeof(dap) to ensure that it is indeed 16
Insert memset(buf, 'A', sizeof(buf)); before you issue INT 13h so that you can check buf is modified or not
Try printf("%lu: [%s]\n", i, buf); instead, because when buf contains \0 around its head printf stops there. The braces should work as marks.
Print _AH and _CF which should contain return codes of INT 13h
#include <dos.h>
#include <bios.h>
struct DAP
{
unsigned char size;
unsigned char reserved1;
unsigned char blocks;
unsigned char reserved2;
unsigned char far *buffer;
unsigned long int lbalod;
unsigned long int lbahid;
} dap;
char st[50];
unsigned char buff[256];
FILE *fptr;
main(void)
{
puts ("enter the lba low double word: ");
gets (st);
dap.lbalod=atol(st);
puts ("enter the lba high double word: ");
gets (st);
dap.lbahid=atol(st);
dap.size=16;
dap.reserved1=0;
dap.blocks1;
dap.reserved2=0
dap.buffer = (unsigned char far *)MK FP(DS.buf);
_AH = 0x42;
_DL = 0x80;
_SI = (unsigned int)%dap;
geninterrupt(0x13);
puts ("enter the path: ");
gets(st);
fptr = fopen(st, "wb");
fwrite(buf,256,1,fptr);
fclose(fptr);
}
i am getting statement missing error on this line dap.buffer = (unsigned char far *)MK_FP(_DS, buf);