Bugs and some errors with recourding code!
Lucas Adami

Hello! I made this code based on this topic:
http://www.allegro.cc/forums/thread/588370

This program records a sound, from your pc input sound...
This is the code:

1#define ALLEGRO_USE_CONSOLE 1
2#include <allegro.h>
3#include <stdio.h>
4 
5void init();
6void deinit();
7 
8SAMPLE *sample,*novo;
9FILE *fp;
10 
11int main()
12{
13 int audio, working_format, bitcap,stereocap,ratecap;
14 int ofs = 0;
15 int len;
16 int interval;
17 int foo;
18 int size = 1024*1024;
19 unsigned char *buf, *tempbuf, *tempbuf2, *start, *novoc, *start2;
20 init();
21
22 //Let's find out what we are capable of
23 bitcap = get_sound_input_cap_bits();
24 if (bitcap == 0) printf("No Audio input capabilty?");
25 
26 stereocap = get_sound_input_cap_stereo();
27 if (stereocap == 0)printf("No Stereo recording");
28 
29 ratecap = get_sound_input_cap_rate(bitcap, 0);
30 
31 working_format = get_sound_input_cap_parm(ratecap, bitcap, 0);
32 if (working_format < 1) printf("We Are not a go!"); //
33 else if (working_format == 1) printf("We Are a go but can't record and playback at the same time!");
34 else if (working_format == 2) printf("We Are a go!\n");
35
36 //Setting up the sample and the pointers
37 sample = create_sample(bitcap, 0, ratecap, size);
38 novo = create_sample(bitcap, 0, ratecap, size);
39 buf=(unsigned char*)(sample->data);
40 novoc=(unsigned char*)(novo->data);
41 start = buf;
42 start2 = novoc;
43
44 //Let's start recording
45 printf("Start Recording\n");
46 len = start_sound_input(ratecap, 16, 0);
47
48 //Find the interval to loop according to Spellcaster
49 interval = 1000 / ((len / 2) / ratecap);
50 /* use 9/10 of the max intervall */
51 interval *= 9;
52 interval /= 10;
53 printf("length of buffer in bytes = %d, max interval = %d\n", len, interval);
54
55 //Start the looping to transfer the data into the sample...again this is taken from spellcaster
56 while (!keypressed() && ofs < size)
57 {
58 foo = read_sound_input(buf);
59 if (foo > 0)
60 {
61 ofs += len;
62 buf += len;
63 }
64 rest(interval);
65 }
66 if (keypressed())
67 {
68 foo = read_sound_input(buf);
69 if (foo > 0)
70 {
71 ofs += len;
72 buf += len;
73 }
74 }
75
76 //Stop the sound recording
77 stop_sound_input();
78
79 int total = buf-start;
80 //lets put a pointer to the first memory location and output the contents
81 tempbuf = start;
82 printf("tamanho do buf: %p\n",total);
83 
84 //printf("in %p is %u\n", tempbuf,*tempbuf); //changed to %p and %u from %i
85 for(int x = 0;x < total;x++)
86 {
87 fprintf(fp,"%c",*tempbuf);
88 tempbuf++;
89 }
90 
91 for(int x = 0;x < total;x++)
92 {
93 fscanf_s(fp,"%c",novoc);
94 novoc++;
95 }
96
97 //Finally lets play it
98 //play_sample(novo, 255, 128, 1000,0);
99 
100 tempbuf = start;
101 tempbuf2 = start2;
102 
103 for(int x = 0;x < 100;x++)
104 {
105 printf("In sample: %u In novo: %u\n",*tempbuf,*tempbuf2);
106 tempbuf++;
107 tempbuf2++;
108 }
109 
110 clear_keybuf();
111 rest(500);
112 while(!keypressed());
113 
114 deinit();
115 return 0;
116}
117END_OF_MAIN()
118 
119void init()
120{
121 allegro_init();
122 install_keyboard();
123 install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT, NULL);
124 install_sound_input(DIGI_AUTODETECT,MIDI_NONE);
125 fopen_s(&fp,"som.txt","w+");
126}
127 
128void deinit()
129{
130 clear_keybuf();
131 destroy_sample(sample);
132 destroy_sample(novo);
133 fclose(fp);
134 allegro_exit();
135}

Here is the bug:

- When i write to the file, reading it does not give me the same value it was before, check it on this line when running: printf("In sample: %u In novo: %u\n",*tempbuf,*tempbuf2);

A question:

- Why i need that interval? And how to get it? Why it need to be calculated and its not a fixed value, like 500?

Another question:

- What would you do to make this code better? What errors or bugs i did not mentioned before you found?

Thx a lot! Cya! ;D

Kitty Cat
fscanf_s
fopen_s

These make baby jesus cry. :'( Should use

instead.

And you're not getting the same value because you don't rewind the file the file after writing it.

Lucas Adami

Its because i am using visual c++ express, so there is a new function with the _s, i will try to use the rewind thx!
But there are more questions:

- Why i need that interval? And how to get it? Why it need to be calculated and its not a fixed value, like 500?

- How to write to file and make it a VALID .wav format?

TY!

Kitty Cat
Quote:

Its because i am using visual c++ express, so there is a new function with the _s

VC++ has fopen and fscanf, however only newer versions of VC++ have fopen_s and fscanf_s.. no other compiler or OS does.

Quote:

- Why i need that interval? And how to get it? Why it need to be calculated and its not a fixed value, like 500?

It should work as a fixed value, but the interval value helps to make it so you get back when enough data is ready.

Quote:

How to write to file and make it a VALID .wav format?

save_sample

Lucas Adami

Ty but its returning an error!

At this function: if(save_sample("test.wav",sample)!=0) printf("ERROR!");

Why its returning an error? Omg what a headake!!!!!!!! :-X

Kitty Cat

Sorry, it appears Allegro doesn't fully implement that yet. Here's something that should work:

1int my_save_wav(const char *fname, SAMPLE *spl)
2{
3 PACKFILE *pf = pack_fopen(fname, F_WRITE);
4 if(!pf)
5 return 1;
6 
7 pack_fwrite("RIFF", 4, pf);
8 pack_iputl(spl->len*spl->bits/8 + 36, pf);
9 pack_fwrite("WAVE", 4, pf);
10 
11 
12 pack_fwrite("fmt ", 4, pf);
13 pack_iputl(16, pf);
14 
15 pack_iputw(1, pf);
16 pack_iputw(spl->stereo?2:1, pf);
17 pack_iputl(spl->freq, pf);
18 pack_iputw(spl->bits*(spl->stereo?2:1)/8, pf);
19 pack_iputl(spl->bits*(spl->stereo?2:1)/8*spl->freq, pf);
20 pack_iputw(16, pf);
21 
22 
23 pack_fwrite("data", 4, pf);
24 pack_iputl(spl->len*spl->bits/8, pf);
25 
26 pack_fwrite(spl->data, spl->len*spl->bits/8, pf);
27 
28 
29 pack_fclose(pf);
30 return 0;
31}

Note that I haven't tested it or even tried to compile it, but hopefully will work with few changes needed.

Lucas Adami

Well, it didnt worked fine, so i wrote everything in a text file, then i read it and put in a sample :), but the file its getting too big! How i could minimize that?

Code:
To write:

fprintf(fp,"%d %d %d\n",bitcap,ratecap,size);

for(int x = 0;x < total;x++)
{
  fprintf(fp,"%u ",*tempbuf);
  tempbuf++;
}

To read:

fscanf_s(fp,"%d %d %d",&bitcap,&ratecap,&size);

sample = create_sample(bitcap, 0, ratecap, size);

while(!feof(fp))
{
  fscanf_s(fp,"%u ",buf);
  buf++;
}

In a simple 5 seconds of recording the file gets around 1.5 MB :S

Ty for attention, hope you can help me in this problem! Cya!

Kitty Cat
Quote:

Well, it didnt worked fine

What was the problem with it?

Quote:

, so i wrote everything in a text file, then i read it and put in a sample :), but the file its getting too big! How i could minimize that?

You're converting them to ascii numbers. Leave them as normal pcm data:

1fprintf(fp,"MYHEADER %d %d %d\n",bitcap,ratecap,size);
2 
3for(int x = 0;x < total;x++)
4{
5 fputc(fp,*tempbuf);
6 tempbuf++;
7}
8 
9// To read:
10if(fscanf(fp,"MYHEADER %d %d %d",&bitcap,&ratecap,&size) != 3)
11{
12 printf("Error!\n");
13 exit(1);
14}
15 
16sample = create_sample(bitcap, 0, ratecap, size);
17 
18while(!feof(fp))
19{
20 *buf = fgetc(fp);
21 buf++;
22}

Note that this will create files that only your program read. Nothing else will be able to load it. Also not that it will still cause somewhat large files since it's uncompressed data.

Lucas Adami

Hello again!
By your way of making an wav file, when you load it the sound quality decreases 10x!
And by my way, puting then into a text file as chars, when i read it it dont work!

Omg! Can you help me with that? Ty!

EDITED----------------

By my way writing in charr worked now, after debugging a lot i found that some chars where considered '\n' or something like that! So i used now binary files and it worked fine! The file is now about 200kb for 5 sec! It reduced a lot :D

How to compress data? Ty!

Kitty Cat
Quote:

By your way of making an wav file, when you load it the sound quality decreases 10x!

Hmm, woops. That one part should be...

    pack_iputw(spl->bits*(spl->stereo?2:1)/8, pf);
    pack_iputl(spl->bits*(spl->stereo?2:1)/8*spl->freq, pf);
    pack_iputw(spl->bits, pf);

(change that one '16' to 'spl->bits').

Quote:

How to compress data? Ty!

Use something like oggdropXPd to compress it as an Ogg, then use AlOgg or APEG to play it in Allegro.

Lucas Adami

Ty a lot, but i have some strange ting, not a problem, i get the sound save it in the file, when i play it there is something strange in the end of it, the sound make a 'stop recording' sound, then pass more 3 sec and then another 'stop recording' sound!

Very strange, do you see (or hear ;p) something strange?

Ty!Cya!

Thread #591876. Printed from Allegro.cc