Reading raw audio files - c

How do you
Read a 16 bit stereo raw audio file in binary mode
Convert it's values to integer for right and for left.
Save those integers back to a new 16 bit stereo raw audio file.
The final two files should be the same, with my code, they are not. Why?
My code:
char ergebnis[80];
sprintf(ergebnis,"%s.neu.raw",Datei);
FILE* ausgabe = fopen(ergebnis, "wb");
FILE* f = fopen(Datei, "rb");
if (f == NULL)
return;
int i = -1;
int r1 = 0;
int r2 = 0;
int l1 = 0;
int l2 = 0;
int l = 0;
int r = 0;
while((getc(f))!=EOF)
{
i++;
if (i == 0)
r1 = (unsigned)fgetc(f);
if (i == 1)
{
r2 = (unsigned)fgetc(f);
r = r1 | r2 << 8;
}
if (i == 2)
l1 = (unsigned)fgetc(f);
if (i == 3)
{
l2 = (unsigned)fgetc(f);
l = l1 | l2 << 8;
putc(r,ausgabe);
putc(l,ausgabe);
i = -1;
}
}
fclose(f);
fclose(ausgabe);
exit(-1);
EDIT: Solved it with
int wo = 0;
while(wo !=EOF)
{
wo = getc(f);
i++;
if (i == 0)
r1 = (unsigned)wo;
if (i == 1)
{
r2 = (unsigned)wo;
r = (r2<<8)+r1; //r1 | r2 << 8;
}
if (i == 2)
l1 = (unsigned)wo;
if (i == 3)
{
l2 = (unsigned)wo;
l = (l2<<8)+l1; //l1 | l2 << 8;
putc((char) ( r & 0xff),ausgabe);
putc((char) ((r >> 8) & 0xff),ausgabe);
putc((char) ( l & 0xff),ausgabe);
putc((char) ((l >> 8) & 0xff),ausgabe);
i = -1;
}
}

Getc in the while will skip one character.
Also if you have 16bit per channel instead of
putc(r,ausgabe);
putc(l,ausgabe);
do
putc((char) ( r & 0xff),ausgabe);
putc((char) ((r >> 8) & 0xff),ausgabe);
putc((char) ( l & 0xff),ausgabe);
putc((char) ((l >> 8) & 0xff),ausgabe);
Possibly you want a different endianness then just swaplines 1 and 2 and lines 3 and 4

Related

How do I change the bytes of a 32-bit integer?

I'm trying to add two binary numbers together using only logical statements and binary arithmetic operators. But I'm confused on how to actually change the bits. It is mostly the out variable that I am trying to change, but it keeps getting zeroed every time I print it.
#include <stdio.h>
void execute_add(int a, int b){
int i = 0;
int bit;
int bit2;
int carryOut = 0;
int out = 10;
int overflow = 0;
for(i = 0; i <32 ; i++){
bit = (a >> i) & 1;
bit2 = (b >> i) & 1;
if(bit==1 && bit2==1 && carryOut == 0){
carryOut = 1;
out = 0 | (0x1 >> i);
}else if(bit==1 && bit2==1 && carryOut == 1){
carryOut = 1;
out = 1 | (0x1 >> i);
}else if(bit==0 && bit2==0 && carryOut == 0){
carryOut = 0;
out= 0 | (0x1 >> i);
}else if(bit==0 && bit2==0 && carryOut == 1){
carryOut = 0;
out = 1 | (0x1 >> i);
}else if(bit==1 && bit2==0 && carryOut == 0){
carryOut = 0;
out = 1 | (0x1 >> i);
}else if(bit==1 && bit2==0 && carryOut == 1){
carryOut = 1;
out = 0 | (0x1 >> i);
}else if(bit==0 && bit2==1 && carryOut == 0){
carryOut = 0;
out = 1 | (0x1 >> i);
}else if(bit==0 && bit2==1 && carryOut == 1){
carryOut = 1;
out = 0 | (0x1 >> i);
}else{
}//if else
}//for loop
printf("\n");
bit = (a >> 31) & 1;
bit2 = (a >> 31)& 1;
int bit3 = (out >> 31) & 1;
if( bit == 1 && bit2== 1 && bit3 == 0){
overflow = 1;
}else if (bit == 0 && bit2 == 0 && bit3 == 1){
overflow = 1;
}else{
}//overflow check
int j;
int g = 0;
for(j = 31; j>=0; j--){
if(g%4==0 && g!=0){
printf(" ");
}
bit2 = (out >> j) & 1;
printf("%d", bit2);
g++;
}
printf("\n");
}
int main (){
int a = 34;
int b = 17;
execute_add(a, b);
return 0;
}
With each of these statements in your for loop:
out = 0 | x;
You're resetting out, and clearing away all the work you've already done. You probably mean to do:
out = out | x
Or, equivalently,
out |= x
You also are right-shifting 1 all over the place, which is not what you're looking for; for any shift greater than zero, that's going to give you zero. I think you're often looking for a left-shift where you use a right shift.
I would second kaylum's comment about using a debugger; even if you flip the appropriate shifts and | with out properly, you're still going to have logic errors that will be easily fixed with a debugger.

What is this C function doing?

I understand that it's going to take in a number and return a character. I understand what each line of code is doing, but I can't really express what it's doing overall in a meaningful way. Any ideas?
int function(uint64_t P1) {
uint64_t L1 = P1;
uint32_t L2 = 1;
while (L1 > 15) {
L2 = (uint64_t)L2 << 4;
L1 = L1 >> 4;
}
uint32_t L3 = 0;
while (L2 != 0) {
L1 = P1;
uint32_t L4 = 0;
L4 = L1 % L2;
uint64_t L5 = (uint64_t)L4;
sub_function(L1 / L2);
L3++;
P1 = L5;
L2 = (uint64_t)L2 >> 4;
}
L1 = L3;
return L1;
}
void sub_function(uint64_t P1) {
if (P1 <= 9) {
printf("%c", P1 + 48);
} else {
printf("%c", P1 + 55);
}
}
This code accepts a decimal value and prints the hexadecimal representation.
Try it out yourself
In C we can use the %x (%X) format specifier flag to printf to do it for us:
printf("%X", 16); // 10
printf("\n");
printf("%X", 42); // 2A
If you're using a C++ compiler, we can instead use the std::hex stream manipulation flag on iostream to achieve the same result:
std::cout << std::hex << 16 << std::endl; // 10
std::cout << std::hex << 42 << std::endl; // 2a

Base64 Encoding Padding in C

I am writting a base64 encoder and decoder and have it almost completly functional, I just need to be able to pad the encoded data with equal signs if the number of input bytes does not round out to a multiple of 3. I am relativly new to C and am not sure how I would detect the number of bytes or pad the output accordingly. This is what I have so far
void encode(char* src, char* dest) {
char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned char first = (src[0] >> 2);
unsigned char second = (src[0] << 4) | (src[1] >> 4);
second = (second << 2);
second = (second >> 2);
unsigned char third = (src[1] << 2) | (src[2] >> 6);
third = (third << 2);
third = (third >> 2);
unsigned char fourth = (src[2]);
fourth = (fourth << 2);
fourth = (fourth >> 2);
dest[0] = base64[first];
dest[1] = base64[second];
dest[2] = base64[third];
dest[3] = base64[fourth];
}
And my decoder method...
void decode(char* src, char* dest) {
char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int i;
int j;
int index;
for(i = 0; i < 4; i++) {
index = 0;
for(j = 0; j < 64; j++) {
if (src[i] == base64[j]) {
src[i] = index;
} else {
index++;
}
}
}
char first = (src[0] << 2) | (src[1] >> 4);
char second = (src[1] << 4) | (src[2] >> 2);
char third = (src[2] << 6) | (src[3]);
dest[0] = first;
dest[1] = second;
dest[2] = third;
}
If this is not enough and I need to also provide the rest of my code I can do so.

Send a variable to a function and modify this variable in C

I have the following vars:
char seed[NBITS + 1], x0[NBITS + 1], y0[NBITS + 1], z0[NBITS + 1], dT0[NBITS + 1];
And i want to change it values on this function:
void lfsr(char *bin, char *output)
{
//bits significativos para fazer o xor NBITS -> NBITS,126,101,99;
int bits[4];
int bit;
if(bin[0] == '0')
bits[0] = 0;
else if(bin[0] == '1')
bits[0] = 1;
if(bin[2] == '0')
bits[1] = 0;
else if(bin[2] == '1')
bits[1] = 1;
if(bin[21] == '0')
bits[2] = 0;
else if(bin[21] == '1')
bits[2] = 1;
if(bin[19] == '0')
bits[3] = 0;
else if(bin[19] == '1')
bits[3] = 1;
bit = bits[0] ^ bits[1] ^ bits[2] ^ bits[3] ^ 1;
//reconstruir o vector de char depois do lfsr
for(int i = 127; i >= 1; i--)
{
bin[i] = bin[i - 1];
}
bin[0] = (char)(48 + bit);
output = bin;
}
The way that I put the value in y0 from x is, for example, calling the lfsr functions like this:
lfsr(x0, y0);
What am I doing wrong?
I have to do 3 Fibonacci Linear Feedback Shift Register starting from x0.
x0 = 10101010101010
y0 = lfsr(101010101010)
z0 = lfsr(y0)
dT0 = lfsr(z0);
The results are good, but when I do the above code the value of x0 will be the same as dT0 if i use pointers.
Can anyone help me?
Thanks. Cumps!
Consider the following:
The numbers correspond to the taps. The bits are actually 15..0, left to right. The following is my implementation of the Fibonacci Linear Feedback Shift Register:
#include <stdio.h>
uint16_t fibLfsr(const uint16_t num)
{
uint16_t tempNum;
tempNum = (num) ^ (num >> 2) ^ (num >> 3) ^ (num >> 5);
tempNum = (tempNum & 0x1) << 15;
tempNum = (tempNum | (num >> 1));
return tempNum;
}
int main(void)
{
uint16_t testNum = 0xACE1;
printf("%#X\n", testNum);
testNum = fibLfsr(testNum);
printf("%#X\n", testNum);
return 0;
}
I'm not quite sure why you're using strings and converting them to binary. If this is necessary, you'll need some of the standard library APIs in stdlib and string to convert the string to an uint16_t before calling fibLfsr() and back to a string afterwards.

C Concatenate int

I will be the first to admit, I'm a C# guy 100% and C isn't for me. However I have problem.
I need to concatenate 7 with HashUrl(HashInt) and then with HashInt
Any help would be greatly appreciated.
int main(int argc)
{
unsigned int HashInt;
HashInt = HashURL(argc);
// I need to return 7 + CheckHash(HashInt) + HashInt but not ADDING, but concanenating them
return HOWEVERTOGETTHESTRING;
}
I should have specified the usage of this. It's actually going to be used in a students VB6 project.
Private Declare Function main Lib "checksum.dll" (ByVal pStr As String) As Long
Private Sub Command1_Click()
MsgBox main("http://hello.com")
End Sub
The full source for the C library is
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <string.h>
#include <winreg.h>
#include <stdlib.h>
int StrToInt(char *pStr, int Init, int Factor)
{
while (*pStr) {
Init *= Factor;
Init += *pStr++;
}
return Init;
}
int HashURL(char *pStr)
{
unsigned int C1, C2, T1, T2;
C1 = StrToInt(pStr, 0x1505, 0x21);
C2 = StrToInt(pStr, 0, 0x1003F);
C1 >>= 2;
C1 = ((C1 >> 4) & 0x3FFFFC0) | (C1 & 0x3F);
C1 = ((C1 >> 4) & 0x3FFC00) | (C1 & 0x3FF);
C1 = ((C1 >> 4) & 0x3C000) | (C1 & 0x3FFF);
T1 = (C1 & 0x3C0) << 4;
T1 |= C1 & 0x3C;
T1 = (T1 << 2) | (C2 & 0xF0F);
T2 = (C1 & 0xFFFFC000) << 4;
T2 |= C1 & 0x3C00;
T2 = (T2 << 0xA) | (C2 & 0xF0F0000);
return (T1 | T2);
}
char CheckHash(unsigned int HashInt)
{
int Check = 0, Flag = 0;
int Remainder;
do {
Remainder = HashInt % 10;
HashInt /= 10;
if (1 == (Flag % 2) ){
Remainder += Remainder;
Remainder = (Remainder / 10) + (Remainder % 10);
}
Check += Remainder;
Flag ++;
} while( 0 != HashInt);
Check %= 10;
if (0 != Check) {
Check = 10 - Check;
if (1 == (Flag % 2)) {
if (1 == (Check % 2)) {
Check += 9;
}
Check >>= 1;
}
}
Check += 0x30;
return Check;
}
int main(int argc)
{
unsigned int HashInt;
int result;
HashInt = HashURL(argc);
char temp[100];
sprintf(temp, "7%i%j", CheckHash(HashInt), HashInt);
result = atoi(temp);
return result;
}
give " http://www.hello.com" should return 783544359868 but its not
You can use sprintf function to create formatted strings. To concatenate 3 integers into a string you could use something like
sprintf(string, "%d%d%d", int1, int2, int3)
I'm not all that great at C, but how I would solve this problem is to first turn them into character arrays, then concatenate those. Then you could turn the result back into an int:
int main(int argc) {
unsigned int HashInt;
int result;
HashInt = HashURL(argc);
char temp[50];
sprintf(temp, "7%i%i", CheckHash(HashInt), HashInt);
result = atoi(temp);
return result;
}
Note: No guarantees on this working...
For starters, you can look at:
asprintf
Just do man asprintf on a linux system.
Here's a link that has a simple example that you can adapt:
http://www.gnu.org/s/libc/manual/html_node/Dynamic-Output.html

Resources