File Copy
Hey i have a problem about file copying. I have a source file opened with fstream and a destination file opened with FILE*...im trying to copy a chunk of the source file into the destination (the function receives as parameters the start second on the source file in which we should start "recording" and the duration of the file to generate from the copy). It seems to be copying the bytes correctly (at least it generates the file, with something in it), but when i try with several different media players the file is impossible to open.
void Mp3::writeFrame(const Frame& f, FILE * dst, long start, long dur)
{
fstream file(this->name, ios::in || ios::binary);
int btr = (f.getBitrate() * 1000);
int currpos = f.get_start();
int start_byte = (currpos + (start * (btr/8)));
int finish_byte = ((dur * (btr/8)) + start_byte);
int memblock = (finish_byte - start_byte);
char * block = new char[memblock];
cout<<dec<<start_byte<<'\t'<<dec<<finish_byte<<'\n';
cout<<dec<<currpos<<'\t'<<dec<<memblock<<'\n';
cout<<dec<<start<<'\t'<<dec<<dur<<'\n';
cout<<dec<<btr<<'\t'<<'\n';
file.seekg(start_byte, ios::beg);
file.read(block,memblock);
cout<<hex<<block[0]<<'\t'<<hex<<block[1]<<'\n';
fwrite(block,memblock,1,dst);
}
Can anyone help me here? what am i doing wrong? the FILE* is already opened in main in binary mode.
Thanks
Nogat21
Junior Poster in Training
60 posts since Jul 2009
Reputation Points: 10
Solved Threads: 0
I did this same function in C and it worked...the file was generated and i could play it in windows media player. I know that C is a more low level language and debugging these functions is quite easy...but in c++ im having a really hard time trying to understand this :S
Here's the same function in C:
void create_new(FILE * fp, unsigned int start, unsigned int duration,const char * new_file)
{
FILE * novo;
UInt32 start_byte;
UInt32 finish_byte;
UInt32 chunk;
UInt32 bitr;
unsigned char * var;
unsigned char * str;
UInt32 p = 0;
str = (unsigned char*) malloc ((sizeof(unsigned char*)) * 4);
p = ftell(fp);
fread(str,1,4,fp);
novo = fopen(new_file,"wb");
bitr=sync_items(fp,str,p,"-xed"); //bitrate médio??
start_byte = p +(start * ((bitr)/8));
finish_byte = (duration *((bitr)/8)) + start_byte;
chunk = (finish_byte - start_byte);
var =(unsigned char *) malloc((sizeof(unsigned char *)) * chunk);
fseek(fp,start_byte,SEEK_SET);
free(str);
fread(var,chunk,1,fp);
fwrite(var,chunk,1,novo);
free(var);
fclose(novo);
}
I'll apreciate some ideas about this...thanks ;)
Nogat21
Junior Poster in Training
60 posts since Jul 2009
Reputation Points: 10
Solved Threads: 0
have you tried making your output stream a fstream like your input stream and using the write() function?
NathanOliver
Veteran Poster
1,084 posts since Apr 2009
Reputation Points: 215
Solved Threads: 189
Well the file is created, but now with nothing in it :S
void Mp3::writeFrame(const Frame& f, fstream& dst, long start, long dur)
{
const char * nome = this->Getname();
fstream file(nome, ios::in || ios::out || ios::binary);
int btr = (f.getBitrate() * 1000);
int currpos = f.get_start();
int start_byte = (currpos + (start * (btr/8)));
int finish_byte = ((dur * (btr/8)) + start_byte);
int memblock = (finish_byte - start_byte);
char * block = new char[memblock+1];
char * test = new char[4];
file.seekg(start_byte, ios::beg);
file.read(block,memblock);
cout<<block[0]<<block[1]<<block[2]<<endl;
dst.write(block,memblock);
dst.seekg(0,ios::beg);
dst.read(test,3);
cout<<test[0]<<test[1]<<test[2]<<endl;
file.close();
delete [] test;
delete [] block;
}
The first print gives the correct chars, which means that we are reading correctly from the file...but the second print is wrong...which means that the writing is doing wrong. But why? i cant seem to understan this :S
Nogat21
Junior Poster in Training
60 posts since Jul 2009
Reputation Points: 10
Solved Threads: 0
line 6: >> fstream file(nome, ios::in || ios::out || ios::binary);
You are using the boolean || operator, not the bitwise | operator
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
when you are writing to the file you are using the memblock variable when you should be using sizeof(block) so that write knows how many bites to write to the file.
dst.write(block, sizeof(block));
also on line 15 you are using 4 for the size of test. are you sure that is the size you need? otherwise i would use the same size that you have for block of [memblock + 1].
NathanOliver
Veteran Poster
1,084 posts since Apr 2009
Reputation Points: 215
Solved Threads: 189
Thanks a lot!! It's solved...here's the final version of the method:
void Mp3::writeFrame(const Frame& f, fstream& dst, long start, long dur)
{
const char * nome = this->Getname();
fstream file(nome, ios::in | ios::out | ios::binary);
int btr = (f.getBitrate() * 1000);
int currpos = f.get_start();
int start_byte = (currpos + (start * (btr/8)));
int finish_byte = ((dur * (btr/8)) + start_byte);
int memblock = (finish_byte - start_byte);
char * block = new char[memblock+1];
char * test = new char[memblock+1];
file.seekg(start_byte, ios::beg);
file.read(block,memblock);
cout<<block[0]<<block[1]<<block[2]<<block[memblock-1]<<endl;
dst.write(block,memblock); //if i did //dst.write(block,sizeof(block)) it would only write 4 bytes into the //file
dst.seekg(0,ios::beg);
dst.read(test,sizeof(test));
cout<<test[0]<<test[1]<<test[2]<<test[memblock-1]<<endl;
file.close();
delete [] test;
delete [] block;
}
Thanks for your help...i'll close this thread now :)
Nogat21
Junior Poster in Training
60 posts since Jul 2009
Reputation Points: 10
Solved Threads: 0