I am trying to store data of .wav file in an array. I am not able to find a way to store data from subchunk2 in an array. Can anybody help me with this?
This is the code which I have used till now
typedef struct header_file
{
char chunk_id[4];
int chunk_size;
char format[4];
char subchunk1_id[4];
int subchunk1_size;
short int audio_format;
short int num_channels;
int sample_rate; // sample_rate denotes the sampling rate.
int byte_rate;
short int block_align;
short int bits_per_sample;
char subchunk2_id[4];
int subchunk2_size; // subchunk2_size denotes the number of samples.
} header;
typedef struct header_file* header_p;
Main Part
//Load wave file
FILE* infile = fopen("E:/fCWT-main/MATLAB/1s_speech.wav", "rb"); // Open wave file in read mode
int BUFSIZE = 512; // BUFSIZE can be changed according to the frame size required (eg:512)
int count = 0; // For counting number of frames in wave file.
short int buff16[BUFSIZE]; // short int used for 16 bit as input data format is 16 bit PCM audio
header_p meta = (header_p)malloc(sizeof(header)); // header_p points to a header struct that contains the wave file metadata fields
int nb; // variable storing number of byes returned
if (infile)
{
fread(meta, 1, sizeof(header), infile);
//fwrite(meta, 1, sizeof(*meta), outfile);
int samples = meta->subchunk2_size;
size_t result;
tmp = (float*)malloc(sizeof(float) * samples);
while (!feof(infile))
{
nb = fread(buff16, 1, BUFSIZE, infile); // Reading data in chunks of BUFSIZE
cout << nb << endl;
count++; // Incrementing Number of frames
}
cout << " Number of frames in the input wave file are " << count << endl;
}
Basically here I want to store and display the data of wav file into an array so that I can use that array for further processing and I don't have any idea how to do it. I have tried searching it online but that solutions were limited to reading Header File.
I am new in C++ so any help regarding this will work.
Thanks!
Related
I have this code snippet,
int main(int argc, char *argv[])
{
//################################
// Variables
//################################
// common
int num_of_params; // number of command-line parameters
// related to files
//string data_filename;
char data_filename[CHUNK_BUF_SIZE]; // input file path
int data_filesize = 0; // data file size
// related to chunks
int fd; // file descriptor to check boundary
int size; // size of input data
unsigned char *buf; // input data
int offset = 0; // file offset
int chunk_b_pos = 0 ; // beginning position of a chunk in a file
int chunk_e_pos = -1; // ending position of a chunk in a file
// *** NOT 0 ** due to "set_breakpoint() in chunk_sub.c"
//
int cur_chunk_size = 0; // !!!! Accumulated chunk size !!!!
// This value is compared to minimum chunk size and maximum chunk size
int chunk_index_fd; // file which contains chunk indexes for a document
char chunk_index_filepath[CHUNK_BUF_SIZE]; // chunk index file path
// parameters
int avg_chunk_size; // expected averge chunk size
int min_chunk_size; // minimum chunk size
int max_chunk_size; // maximum chunk size
// temporary command
char cmd[CHUNK_BUF_SIZE];
int num_of_breakpoints = 0;
//################################
// Check parameters
//################################
// get number of command-line parameters
num_of_params = argc - 1;
if (num_of_params != 4)
{
printf("usage : %s <input file> <expected avg chunk size> <min chuk size> <max chunk size>\n",
argv[0]);
printf("e.g. %s body 8192 2048 65535\n", argv[0]);
printf("*** try to change 1024 to 2048, 4096, and 8192, and see results\n");
exit(1);
}
strcpy(data_filename, argv[1]); // input data filename
avg_chunk_size = atoi(argv[2]);
min_chunk_size = atoi(argv[3]);
max_chunk_size = atoi(argv[4]);
this program takes commandline argument,
eg. >chunk body 8192 2048 65535
where body is filename and others are chunk parameters
my question is i dont want commandline parameters, i want to take input while running the program. how to do it.
Here is an example of how to take runtime input using C++:
#include <iostream>
#include <cstdlib>
int main(void)
{
std::cout << "Enter a number: ";
int number;
std::cin >> number;
std::cout << "\nYour number is: " << number << "\n";
std::cout << "\n\nPaused. Press Enter to continue.\n";
std::cin.ignore(1000000, '\n'); // Wait for Enter to be pressed.
return EXIT_SUCCESS;
}
The "std::cin >> number" is how to input from standard input using C++.
To read from a file, use std::ifstream to create the file. For more examples, search the internet for "c++ ifstream open file".
Here's my first post, and first question.
Why shouldn't I use:bmpFile.read((char*)(&bmpImageData),bmpImageDataSize); to read data block from BMP file, and how should I do this properly (I know about BGR triplets, but as for now I do not really care about them existing) EDIT: Maybe I should clarify something - as the code is right now it compiles pretty well, but stops working on the line provided higher.
#include "stdafx.h"
#include "mybmp.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
filebuf bmpBuff;
ifstream bmpFile("test.bmp", ios::binary);
bmpBuff.open("test_zapis.bmp", ios::binary | ios::out);
ostream bmpSaved(&bmpBuff);
unsigned long bmpSizeBuffer;
bmpFile.seekg(2, ios::beg); // Missing BMP, DIB identification for good byte adjustment
mybmp bmpHeader;
bmpFile.read((char*)(&bmpHeader),sizeof(mybmp));
if(bmpHeader.FReadFileSize()>0)
{
unsigned long bmpImageDataSize = bmpHeader.FReadFileSize()-bmpHeader.FReadOffset(); // Reading ImageData size
char* bmpImageData = new char[bmpImageDataSize];
bmpFile.seekg(bmpHeader.FReadOffset(),ios::beg); // Positioning pointer to ImageData start point
bmpFile.read((char*)(&bmpImageData),bmpImageDataSize); // This breaks down // Reading ImageData to bmpImageData buffer
// Fun with buffer //
for(int i = 0; i < bmpImageDataSize; i++)
{
bmpImageData[i]++;
}
// Saving (...) //
}
else
{
cout << "Plik nie zostal wczytany"<<endl;
}
return 0;
}
My mybmp.h header:
#pragma pack(push,1)
class mybmp
{
unsigned long fileSize; // BMP overall filesize in bytes
unsigned long reserved; // filled with 0
unsigned long fileOffset; // Offset before Raster Data
//---------------------------//
unsigned long size; // Size of InfoHeader = 40
unsigned long width; // overall image width
unsigned long height; // overall image height;
unsigned short planes; // = 1;
unsigned short bitCounts; // Bits per Pixel
unsigned long compression; // Type of compression
unsigned long typeOfImage; // compressed size of Image. 0 if compression parameter = 0;
unsigned long xPixelsPerM; // horizontal resolution - Pixels/Meter
unsigned long yPixelsPerM; // vertical resolution - Pixels/Meter
unsigned long colorsUsed; // Number of colors actually used
unsigned long colorsImportant; // Number of important colors, 0 if all
//--------------------------//
public:
mybmp(void);
unsigned long FReadFileSize();
void FPrintObject();
unsigned long FReadOffset();
~mybmp(void);
};
#pragma pack(pop)
The line bmpFile.read((char*)(&bmpImageData),bmpImageDataSize); looks wrong, the bmpImageData is already a char *. Taking the address gives you a char ** (which will probably be on the stack), which you then write to, corrupting your stack.
Change your problem line to this bmpFile.read (bmpImageData, bmpImageDataSize); does that help?
I need to read a binary file containing several bytes and divide the contents into frames, each consisting of 535 bytes each. The number of frames present in the file is not known at runtime and thus I need to dynamically allocate memory for them. The code below is a snippet and as you can see, I'm trying to create a pointer to an array of bytes (uint8_t) and then increment into the next frame and so on, in the loop that reads the buffered data into the frames. How do I allocate memory at runtime and is this the best way to do the task? Please let me know if there is a more elegant solution. Also, how I manage the memory?
#include <cstdio>
using namespace std;
long getFileSize(FILE *file)
{
long currentPosition, endPosition;
currentPosition = ftell(file);
fseek(file, 0, 2);
endPosition = ftell(file);
fseek(file, currentPosition, 0);
return endPosition;
}
int main()
{
const char *filePath = "C:\Payload\Untitled.bin";
uint8_t *fileBuffer;
FILE *file = NULL;
if((file = fopen(filePath, "rb")) == NULL)
cout << "Failure. Either the file does not exist or this application lacks sufficient permissions to access it." << endl;
else
cout << "Success. File has been loaded." << endl;
long fileSize = getFileSize(file);
fileBuffer = new uint8_t[fileSize];
fread(fileBuffer, fileSize, 1, file);
uint8_t (*frameBuffer)[535];
for(int i = 0, j = 0; i < fileSize; i++)
{
frameBuffer[j][i] = fileBuffer[i];
if((i % 534) == 0)
{
j++;
}
}
struct frame {
unsigned char bytes[535];
};
std::vector<frame> frames;
Now your loop can simply read a frame and push it into frames. No explicit memory management needed: std::vector does that for you.
I am trying to learn more about binary files, so I started with HexEdit, and I manually wrote a file and created a template for it. Here is my work:
Now, I started working on a console application in C++ Win32 to read the contents in that file and make them look friendly. Here is part my code:
typedef unsigned char BYTE;
long getFileSize(FILE *file)
{
long lCurPos, lEndPos;
lCurPos = ftell(file);
fseek(file, 0, 2);
lEndPos = ftell(file);
fseek(file, lCurPos, 0);
return lEndPos;
}
int main()
{
const char *filePath = "D:\\Applications\\ColorTableApplication\\file.clt";
BYTE *fileBuf; // Pointer to our buffered data
FILE *file = NULL; // File pointer
if ((file = fopen(filePath, "rb")) == NULL)
printf_s("Could not open specified file\n");
else {
printf_s("File opened successfully\n");
printf_s("Path: %s\n", filePath);
printf_s("Size: %d bytes\n\n", getFileSize(file));
}
long fileSize = getFileSize(file);
fileBuf = new BYTE[fileSize];
fread(fileBuf, fileSize, 1, file);
for (int i = 0; i < 100; i++){
printf("%X ", fileBuf[i]);
}
_getch();
delete[]fileBuf;
fclose(file); // Almost forgot this
return 0;
}
(I provided that much code because I want to be clear, to help you get the idea about what I am trying to do)
First of all, I need to get the first 14 bytes and write them in the console as text, and then, in a for I need to write something like this for each color:
black col_id = 1; R = 00; G = 00; B = 00;
red col_id = 2; R = FF; G = 00; B = 00;
etc...
How can I read and translate these bytes?
It is correct as you have it to write out the 14 bytes.
a technique is to create a struct with the layout of your records, then cast e.g. (C-style)
typedef struct
{
char name[10];
long col_id;
unsigned char R;
unsigned char G;
unsigned char B;
} rec;
rec* Record = (rec*)(fileBuf + StartOffsetOfRecords);
now you can get the contents of the first record
Record->name, ...
getting next record is just a matter of moving Record forward
++Record;
You could also have a struct for the header to make it more convenient to pickout the number of records, it is good to use stdint.h in order to get well defined sizes. also to pack structures on byte boundary to make sure no padding is done by the compiler i.e. #pragma pack(1) at the top of your source.
typedef struct
{
char signature[14];
uint32_t tableaddress;
uint32_t records;
} header;
typedef struct
{
char name[10];
uint32_t col_id;
unsigned char R;
unsigned char B;
unsigned char G;
} rec;
so instead when you read you could do like this
header Header;
rec* Record;
fread(&Header,sizeof(header),1,file);
fread(fileBuf,1,fileSize,file);
Record = (rec*)(fileBuf); // first record can be accessed through Record
I am working on firmware of an ATMEL sensor board (accelerometer and gyro)and trying to read the data in a platform in Ubuntu.
Currently the firmware is like this:
Ubuntu sends a character "D" and the firmware in response sends back 20 bytes of data that ends in "\n" then ubuntu uses serialport_read_until(fd, buff, '\n') and assumes that buff[0] is byte zero and so on.The frequency of acquisition is 200hz.
BUT using this method sometimes I receive corrupted values and it is not working well. Also there are many "Unable to write on serial port" error in ubuntu.
I have found an example code from ATMEL for the firmware and there the data is sent in different packages and continuously (without waiting for the computer to ask for it) the structure is like this:
void adv_data_send_3(uint8_t stream_num, uint32_t timestamp,
int32_t value0, int32_t value1, int32_t value2)
{
/* Define packet format with 3 data fields */
struct {
adv_data_start_t start; /* Starting fields of packet */
adv_data_field_t field [3]; /* 3 data fields */
adv_data_end_t end; /* Ending fields of packet */
} packet;
/* Construct packet */
packet.start.header1 = ADV_PKT_HEADER_1;
packet.start.header2 = ADV_PKT_HEADER_2;
packet.start.length = cpu_to_le16(sizeof(packet));
packet.start.type = ADV_PKT_DATA;
packet.start.stream_num = stream_num;
packet.start.time_stamp = cpu_to_le32(timestamp);
packet.field[0].value = cpu_to_le32(value0);
packet.field[1].value = cpu_to_le32(value1);
packet.field[2].value = cpu_to_le32(value2);
packet.end.crc = 0x00; /* Not used */
packet.end.mark = ADV_PKT_END;
/* Write packet */
adv_write_buf((uint8_t *)&packet, sizeof(packet));
}
but I don't know how I can continuously read the data that is sent in a structure like above.
Sorry if it is a trivial question. I am not a programmer but I need to solve this and I could not find a solution (that I can understand!) after searching for a couple of days.
The reading function I use in linux:
int serialport_read_until(int fd, unsigned char* buf, char until){
char b[1];
int i=0;
do {
int n = read(fd, b, 1); // read a char at a time
if( n==-1) return -1; // couldn't read
if( n==0 ) {
usleep( 1 * 1000 ); // wait 1 msec try again
continue;
}
buf[i] = b[0]; i++;
} while( b[0] != until );
buf[i] = 0; // null terminate the string
return 0;}
The new Reading Func:
// Read the header part
adv_data_start_t start;
serial_read_buf(fd, reinterpret_cast<uint8_t*>(&start), sizeof(start));
// Create a buffer for the data and the end marker
std::vector<uint8_t> data_and_end(start.length - sizeof(start));
// Read the data and end marker
serial_read_buf(fd, data_and_end.data(), data_and_end.size());
// Iterate over the data
size_t num_data_fields = (data_and_end.size() - sizeof(adv_data_end_t)) / sizeof(adv_data_field_t);
adv_data_field_t* fields = reinterpret_cast<adv_data_field_t*>(data_and_end.data());
for (size_t i = 0; i < num_data_fields; i++)
std::cout << "Field #" << (i + 1) << " = " << fields[i].value << '\n';
The data packets that are sent from the firmware:
typedef struct {
uint8_t header1; // header bytes - always 0xFF5A
uint8_t header2; // header bytes - always 0xFF5A
uint16_t length; // packet length (bytes)
uint32_t time_stamp; // time stamp (tick count)
} adv_data_start_t;
typedef struct {
int32_t value; // data field value (3 VALUES)
} adv_data_field_t;
typedef struct {
uint8_t crc; // 8-bit checksum
uint8_t mark; // 1-byte end-of-packet marker
uint16_t mark2; // 2-byte end-of-packet marker (Added to avoid data structure alignment problem)
} adv_data_end_t;
Well you have the length of the packet in the packet "header", so read the header fields (the start structure) in one read, and in a second read you read the data and the end.
If the start and end parts are the same for all packets (which I guess they are), you can easily figure out the amount of data fields after the second read.
Something like this:
// Read the header part
adv_data_start_t start;
adv_read_buf(reinterpret_cast<uint8_t*>(&start), sizeof(start));
// Create a buffer for the data and the end marker
std::vector<uint8_t> data_and_end(start.length - sizeof(start));
// Read the data and end marker
adv_read_buf(data_and_end.data(), data_and_end.size());
// Iterate over the data
size_t num_data_fields = (data_and_end.size() - sizeof(adv_data_end_t)) / sizeof(adv_data_field_t);
adv_data_end_t* fields = reinterpret_cast<adv_data_end_t*>(data_and_end.data());
for (size_t i = 0; i < num_data_fields; i++)
std::cout << "Field #" << (i + 1) << " = " << fields[i] << '\n';
Possible read_buf implementation:
// Read `bufsize` bytes into `buffer` from a file descriptor
// Will block until `bufsize` bytes has been read
// Returns -1 on error, or `bufsize` on success
int serial_read_buf(int fd, uint8_t* buffer, const size_t bufsize)
{
uint8_t* current = buffer;
size_t remaining = bufsize
while (remaining > 0)
{
ssize_t ret = read(fd, current, remaining);
if (ret == -1)
return -1; // Error
else if (ret == 0)
{
// Note: For some descriptors, this means end-of-file or
// connection closed.
usleep(1000);
}
else
{
current += ret; // Advance read-point in buffer
remaining -= ret; // Less data remaining to read
}
}
return bufsize;
}