Skip to content

Commit

Permalink
Added a c version cos why not lol
Browse files Browse the repository at this point in the history
  • Loading branch information
mini-ninja-64 authored Aug 8, 2018
1 parent f56b018 commit d5a83d1
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 34 deletions.
16 changes: 16 additions & 0 deletions Source/c version/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "wavLoader.h"

#include <ncurses.h>

int main(int argc, char* argv[])
{
struct wavFile * myCoolWav;
if(argc > 1){
myCoolWav = loadWav(argv[1]);
}else{
return -1;
}


return 0;
}
78 changes: 78 additions & 0 deletions Source/c version/wavLoader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "wavLoader.h"

unsigned long pullFromBuffer(unsigned char * buffer, int length, int startAddress, int dataType){
unsigned long byteSet;
if (dataType){ //little endian
byteSet = buffer[startAddress+(length-1)];
for (int i = length-2; i >= 0; i--){ // -2 offset as need -1 cos array start at 0 and -1 as we already done one above
//std::cout << std::hex << byteSet << " " << buffer[startAddress+i] << std::endl;
byteSet = byteSet << 8 | buffer[startAddress+i];
}
}else{
byteSet = buffer[startAddress];
for (int i = 1; i < length; i++){
byteSet = byteSet << 8 | buffer[startAddress+i];
}
}
return byteSet;
}

struct wavFile * loadWav(char * filePath){
//open file and get size
FILE *fptr;
unsigned long fSize;
fptr = fopen(filePath,"rb");
if (fptr == NULL){
fprintf(stderr, "%s", "File could not be opened!\n");
return NULL;
}
fseek ( fptr , 0 , SEEK_END );
fSize = ftell(fptr);
rewind(fptr);

//create file buffer
unsigned char * buffer = (unsigned char*) malloc (sizeof(char)*fSize);
if (buffer == NULL){
fprintf(stderr, "%s", "Memory allocation error will attempt to read from disk!\n");
//TODO: disk streaming
}

//populate buffer in 1 byte increments
if (fread(buffer,1,fSize,fptr) != fSize){
fprintf(stderr, "%s", "File could not be read!\n");
return NULL;
}else{
fclose(fptr);
}

if (!( (pullFromBuffer(buffer, 4, 8, BIG_ENDIAN_TAG) == 0x57415645) && (pullFromBuffer(buffer, 2, 20, LITTLE_ENDIAN_TAG) == 1) )){ //byte 8 is format, byte 20 is audioFormat
fprintf(stderr, "%s", "File is not standard wav!\n");
return NULL;
}

struct wavFile *wf;
//file info
wf->Channels = pullFromBuffer(buffer, 2, 22, LITTLE_ENDIAN_TAG);//2 bytes at 20
wf->SampleRate = pullFromBuffer(buffer, 2, 24, LITTLE_ENDIAN_TAG);//4 bytes at 24
wf->BlockAlign = pullFromBuffer(buffer, 2, 32, LITTLE_ENDIAN_TAG);//2 bytes at 32
wf->BitsPerSample = pullFromBuffer(buffer, 2, 34, LITTLE_ENDIAN_TAG);//2 bytes at 34

//file data
unsigned long audioDataSize = pullFromBuffer(buffer, 4, 40, LITTLE_ENDIAN_TAG);
wf->AudioData = (unsigned char*) malloc (sizeof(char)*audioDataSize); //4 bytes at 40

//move the data array
memmove(wf->AudioData, buffer+44, audioDataSize);
free(buffer);

printf ("Channels: %d\n", wf->Channels);
printf ("Sample Rate: %d\n", wf->SampleRate);
printf ("Block Align: %d\n", wf->BlockAlign);
printf ("Bits Per Sample: %d\n", wf->BitsPerSample);
printf ("Audio Data Size: %lu\n\n", audioDataSize);

printf ("Audio Data: %x %x %x %x\n", wf->AudioData[0], wf->AudioData[1], wf->AudioData[2], wf->AudioData[3]);


return NULL;
}
62 changes: 62 additions & 0 deletions Source/c version/wavLoader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#ifndef WAVLOADER_H
#define WAVLOADER_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BIG_ENDIAN_TAG 0
#define LITTLE_ENDIAN_TAG 1

/*
wav format
wav is actually a wrapper for another format which is the riff format
riff files store everything in juicy lil chunks
every riff chunk has this layout:
4 byte ChunkID
4 byte ChunkSize (this excludes the size of chunk id and chunk size)
the rest of the chunks info
How are Wave files stored:
Chunk 1 ("Riff Chunk Descriptor"):
Endian |Pos| Size |Data Stored | Descriptions
big | 0 |4 bytes |Chunk ID | RIFF (0x52494646)
little | 4 |4 bytes |Chunk Size | 4 + (8 + Chunk2Size) + (8 + Chunk3Size) (size of full file excluding the first 8 bytes)
big | 8 |4 bytes |Format | WAVE (0x57415645)
Chunk 2 ("Format chunk"):
big | 12 |4 bytes |Chunk ID | fmt (0x666D7420)
little | 16 |4 bytes |Chunk Size | 16 (0x10000000)
little | 20 |2 bytes |AudioFormat | If this is equal to 1 its PCM audio otherwise its got some compression or something
little | 22 |2 bytes |NumChannels | number of channels
little | 24 |4 bytes |Sample Rate | sample rate like 8000 or 44100
little | 28 |4 bytes |Byte Rate | SampleRate * NumChannels * BitsPerSample/8
little | 32 |2 bytes |Block Align | NumChannels * BitsPerSample/8 (num of bytes per one audio sample)
little | 34 |2 bytes |Bits Per Sample | number of bits per sample
Chunk 2 ("Data Chunk"):
big | 36 |4 bytes |Chunk ID | data (0x64617461)
little | 40 |4 bytes |Chunk Size | wav data size
little | 44 |X bytes |WAV Data | The actual sound data
how is the wav data stored:
each sample has (Block Align)Bytes, the left channel is the first half of the sample and the right channel is the second half.
*/

//struct sample??

struct wavFile{
int Channels;
int SampleRate;
int BlockAlign;
int BitsPerSample;
unsigned char * AudioData;
};

struct wavFile * loadWav(char * filePath);

unsigned long pullFromBuffer(unsigned char * buffer, int length, int startAddress, int dataType);

#endif /* WAVLOADER_H */
64 changes: 46 additions & 18 deletions Source/wavLoader.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
#include "wavLoader.h"

unsigned long pullFromBuffer(unsigned char * buffer, int length, int startAddress, int dataType){
unsigned long byteSet;
if (dataType){ //little endian
byteSet = buffer[startAddress+(length-1)];
for (int i = length-2; i >= 0; i--){ // -2 offset as need -1 cos array start at 0 and -1 as we already done one above
//std::cout << std::hex << byteSet << " " << buffer[startAddress+i] << std::endl;
byteSet = byteSet << 8 | buffer[startAddress+i];
}
}else{
byteSet = buffer[startAddress];
for (int i = 1; i < length; i++){
byteSet = byteSet << 8 | buffer[startAddress+i];
}
}
return byteSet;
}

wavFile * loadWav(char * filePath){
//open file and get size
FILE *fptr;
long fSize;
unsigned long fSize;
fptr = fopen(filePath,"rb");
if (fptr == NULL){
fprintf(stderr, "%s", "File could not be opened!\n");
Expand All @@ -14,37 +31,48 @@ wavFile * loadWav(char * filePath){
rewind(fptr);

//create file buffer
char * buffer = (char*) malloc (sizeof(char)*fSize);
unsigned char * buffer = (unsigned char*) malloc (sizeof(char)*fSize);
if (buffer == NULL){
fprintf(stderr, "%s", "Memory allocation error will attempt to read from disk!\n");
//TODO: disk streaming
}

//populate buffer in 1 byte increments
if (fread(buffer,1,fSize,fptr) !=fSize){
if (fread(buffer,1,fSize,fptr) != fSize){
fprintf(stderr, "%s", "File could not be read!\n");
return NULL;
}else{
fclose(fptr);
}


unsigned int fmt;
memcpy(&fmt, buffer, sizeof(unsigned int)); //this boy gonna be backwards cos lil endian
std::cout << std::hex << fmt << std::endl;
std::cout << std::hex << (int)buffer[8] << std::endl;

/*if (!( (fmt == WAVE) && (audioFMT == 1) )){ //byte 8 is format, byte 18 is audioFormat
if (!( (pullFromBuffer(buffer, 4, 8, BIG_ENDIAN_TAG) == 0x57415645) && (pullFromBuffer(buffer, 2, 20, LITTLE_ENDIAN_TAG) == 1) )){ //byte 8 is format, byte 20 is audioFormat
fprintf(stderr, "%s", "File is not standard wav!\n");
return null;
return NULL;
}

wavFile *wf;
//file info
wf.Channels = ;//2 bytes at 20
wf.SampleRate = ;//4 bytes at 24
wf.BitsPerSample = ;//2 bytes at 32
wf->Channels = pullFromBuffer(buffer, 2, 22, LITTLE_ENDIAN_TAG);//2 bytes at 20
wf->SampleRate = pullFromBuffer(buffer, 2, 24, LITTLE_ENDIAN_TAG);//4 bytes at 24
wf->BlockAlign = pullFromBuffer(buffer, 2, 32, LITTLE_ENDIAN_TAG);//2 bytes at 32
wf->BitsPerSample = pullFromBuffer(buffer, 2, 34, LITTLE_ENDIAN_TAG);//2 bytes at 34

//file data
wf.AudioData = ;//memcpy from address 44 for address 40 bytes
*/
fclose(fptr);
unsigned long audioDataSize = pullFromBuffer(buffer, 4, 40, LITTLE_ENDIAN_TAG);
wf->AudioData = (unsigned char*) malloc (sizeof(char)*audioDataSize); //4 bytes at 40

//move the data array
memmove(wf->AudioData, buffer+44, audioDataSize);
free(buffer);

printf ("Channels: %d\n", wf->Channels);
printf ("Sample Rate: %d\n", wf->SampleRate);
printf ("Block Align: %d\n", wf->BlockAlign);
printf ("Bits Per Sample: %d\n", wf->BitsPerSample);
printf ("Audio Data Size: %lu\n\n", audioDataSize);

printf ("Audio Data: %x %x %x %x\n", wf->AudioData[0], wf->AudioData[1], wf->AudioData[2], wf->AudioData[3]);


return NULL;
}
47 changes: 31 additions & 16 deletions Source/wavLoader.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
#ifndef WAVLOADER_H
#define WAVLOADER_H

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>

#define BIG_ENDIAN_TAG 0
#define LITTLE_ENDIAN_TAG 1

/*
wav format
wav is actually a wrapper for another format which is the riff format
Expand All @@ -15,37 +21,46 @@ the rest of the chunks info
How are Wave files stored:
Chunk 1 ("Riff Chunk Descriptor"):
0 |4 bytes |Chunk ID | RIFF (0x52494646)
4 |4 bytes |Chunk Size | 4 + (8 + Chunk2Size) + (8 + Chunk3Size) (size of full file excluding the first 8 bytes)
8 |4 bytes |Format | WAVE (0x57415645)
Endian |Pos| Size |Data Stored | Descriptions
big | 0 |4 bytes |Chunk ID | RIFF (0x52494646)
little | 4 |4 bytes |Chunk Size | 4 + (8 + Chunk2Size) + (8 + Chunk3Size) (size of full file excluding the first 8 bytes)
big | 8 |4 bytes |Format | WAVE (0x57415645)
Chunk 2 ("Format chunk"):
12|4 bytes |Chunk ID | fmt (0x666D7420)
16|4 bytes |Chunk Size | 16 (0x10000000)
18|2 bytes |AudioFormat | If this is equal to 1 its PCM audio otherwise its got some compression or something
20|2 bytes |NumChannels | number of channels
24|4 bytes |Sample Rate | sample rate like 8000 or 44100
28|4 bytes |Byte Rate | SampleRate * NumChannels * BitsPerSample/8
32|2 bytes |Block Align | NumChannels * BitsPerSample/8 (num of bytes per one audio sample)
34|2 bytes |Bits Per Sample | number of bits per sample
big | 12 |4 bytes |Chunk ID | fmt (0x666D7420)
little | 16 |4 bytes |Chunk Size | 16 (0x10000000)
little | 20 |2 bytes |AudioFormat | If this is equal to 1 its PCM audio otherwise its got some compression or something
little | 22 |2 bytes |NumChannels | number of channels
little | 24 |4 bytes |Sample Rate | sample rate like 8000 or 44100
little | 28 |4 bytes |Byte Rate | SampleRate * NumChannels * BitsPerSample/8
little | 32 |2 bytes |Block Align | NumChannels * BitsPerSample/8 (num of bytes per one audio sample)
little | 34 |2 bytes |Bits Per Sample | number of bits per sample
Chunk 2 ("Data Chunk"):
36|4 bytes |Chunk ID | data (0x64617461)
40|4 bytes |Chunk Size | wav data size
44|X bytes |WAV Data | The actual sound data
big | 36 |4 bytes |Chunk ID | data (0x64617461)
little | 40 |4 bytes |Chunk Size | wav data size
little | 44 |X bytes |WAV Data | The actual sound data
how is the wav data stored:
each sample has (Block Align)Bytes, the left channel is the first half of the sample and the right channel is the second half.
*/

class wavFile{
//struct sample??

struct wavFile{
public:
int Channels;
int SampleRate;
int BlockAlign;
int BitsPerSample;
int * AudioData;
unsigned char * AudioData;
private:

};

wavFile * loadWav(char * filePath);

unsigned long pullFromBuffer(unsigned char * buffer, int length, int startAddress, int dataType);

#endif /* WAVLOADER_H */

0 comments on commit d5a83d1

Please sign in to comment.