Appending to arrays

I'm reading in data buffers from multiple files and I'd like to append data.

I'm doing something like this to read the data:
1
2
3
4
5
6
7
8
unsigned long data_size;
unsigned char* cData;

std::ifstream file1("file1.wav", std::ifstream::in | std::ifstream::binary);
file1.read((char*)&data_size, sizeof(data_size));

cData = new unsigned char[data_size];
file1.read((char*)cData, data_size);


Now I'd like to open file2 in the same sort of manner and append the data to cData as efficiently as possible. I'd love to use a vector because it'd be so easy, but the buffer is going into an OpenAL function which accepts unsigned char*.

This leads me to two questions:
1. Can I extract a TYPE* from a vector<TYPE> object?

2. Can I increase the size of the cData array without losing the data that was already saved and without copying the entire array which could contain a few million values?

For #2 I'm thinking of something like this:
1
2
3
4
5
6
7
8
unsigned long data_size2;
std::ifstream file2("file2.wav", std::ifstream::in | std::ifstream::binary);
file1.read((char*)&data_size2, sizeof(data_size2));

unsigned char* cDataAPP = new unsigned char[data_size + data_size2];
memcpy(cDataAPP, cData, data_size);
delete cData;
file2.read((char*)&cDataAPP[data_size], data_size2);


But I'm not crazy about using the second variable since it makes looping this stuff for appending a variable number of files more difficult.
Last edited on
I don't see why you can't store data chunks in a vector:

1
2
3
4
std::vector<unsigned char*> wav_data;
unsigned char*chunk = unsigned char[chunk_size];
file.read((char*)&chunk,chunk_size);
wav_data.push_back(chunk);


Just need to make sure you clean up by delete []ing the data in the vector properly when done.
Solved:
This is my solution:

1
2
3
4
5
unsigned char* temp = cData;                       // Make a new pointer that points to cData, no copying of data is involved.
cData = new unsigned char[data_size + data_size2]; // cData now points to a bigger array
memcpy(cData, temp, data_size);                    // Copy the old data to the new space
delete temp;                                       // Delete the old data
file2.read((char*)&cData[data_size], data_size2);  // read new data to the new space, starting at an index=datasize 


The problem with putting it in a vector is I would somehow need to copy it to a char* for use in the OpenAL functions. I don't think you can just pass a vector into it. I'm not sure how to do that (unless vector<char>::iterator it = MyVector.begin() would actually conform to a char* type).


Here is my whole appending function. It's part of a class that does everything with wav files, so I've displayed member variables with this->.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
int wavFile::Append(string fname)
{
	std::ifstream fin(fname, std::ifstream::in | std::ifstream::binary);

	// Load header
	wavFile WavAPP;
	this->LoadHdr(fin, WavAPP);

	// Compare header
	if (WavAPP.nChannels != this->nChannels)
	{
		cout << "Error: There are a different number of channels in these two files." << endl;
		return 1;
	}
	if (WavAPP.nSamplesPerSec != this->nSamplesPerSec)
	{
		cout << "Error: The sample rate is different in these two files." << endl;
		return 1;
	}
	if (WavAPP.nAvgBytesPerSec != this->nAvgBytesPerSec)
	{
		cout << "Error: Byterate doesn't match in these two files." << endl;
		return 1;
	}

	// Load and append data
	unsigned char* temp = this->cData;
	this->cData = new unsigned char[this->data_size + WavAPP.data_size];
	memcpy(this->cData, temp, this->data_size);
	delete temp;
	fin.read((char*)&this->cData[data_size], WavAPP.data_size);

	// Adjust header
	this->data_size	+= WavAPP.data_size;
	this->size	+= WavAPP.data_size;

	fin.close();
	return 0;
}
Last edited on
You might want to look at the data() method of std::vector.
Topic archived. No new replies allowed.