I'm having a bit o a problem with inheritance. The context is this assignment i have in which we have to read from an mp3 file, extacting the informations within it as well as provide other informations not explicitly contained in it (for instance the total audio time of the file, which result from a calculation involving some explicit parameter of the file).
Said that, i organized my implementation in 2 classes: The Mp3 class, that will be responsible for opening the stream and fill a list of valid frames (frames with actual audio content aka "non-garbage frames"). Problem is when i try to compile, the compiler says Frame is not a recognizable type. That gets me confused. I cannot use instances of derived classes within the respective base class? I was kinda of used to do that in java :S
I could make Mp3 as an interface, but the .cpp with the main (which has been given by the professor) contains instanciation of this type. What should i do? here's the code:
Mp3.h:
#ifndef MP3_H
#define MP3_H
#include <fstream>
#include <list>
using namespace std;
class Mp3 {
list<Frame> frames;
fstream myfile;
unsigned long length;
public:
char * name;
Mp3(){}
Mp3(const char * n);
const char * Getname();
unsigned long getLen(const char * path);
bool isOk();
bool getFirstFrame(Frame& f);
list<Frame> getFrames(const char * path);
int visitFrames(FrameVistior fv);
void WriteFrame(Frame fr, FILE * dst);
};
#endif
#ifndef FRAME_H
#define FRAME_H
//
#define MASK_EMPH 3
#define MASK_ORIG 4
#define MASK_COPY 8
#define MASK_EXT 48
#define MASK_MODE 192
#define MASK_PRIV 1
#define MASK_PAD 2
#define MASK_FREQ 12
#define MASK_BITR_IDX 240
#define MASK_PROT 1
#define MASK_LAYER 6
#define MASK_VERS 24
#define OFFSET_ORIG 2
#define OFFSET_COPY 3
#define OFFSET_EXT 4
#define OFFSET_MODE 6
#define OFFSET_PAD 1
#define OFFSET_FREQ 2
#define OFFSET_BIDX 4
#define OFFSET_LAYER 1
#define OFFSET_VERS 3
#include <fstream>
using namespace std;
//
class Frame : public Mp3{
unsigned long position;
unsigned long length;
unsigned long numelems;
unsigned char * bitmap;
public:
Frame();
unsigned long getLength(){ return length; }
void addByte(char ch);
void clear();
void getFrame(const char * path);
int fastValidation();
long getTimeMilis();
int getVersion();
int getLayer();
int getBitrate();
int getFrequency();
};
#endif
Mp3.cpp:
#include "Mp3.h"
//#include "cmd.h"
#include<stdio.h>
#include<string.h>
Mp3::Mp3(const char * n)
{
name = new char [strlen(n)+1];
strcpy(name,n);
myfile.open (name,fstream::in|fstream::out|fstream::binary);//pointer aponta para o inicio do file
length = getLen(myfile);
frames = get_frames(n);
}
const char * Mp3::Getname(){ return name; }
unsigned long Mp3::getLen(const char * path)
{
ifstream file;
file.open(path,fstream::in | fstream::binary);
file.seekg(0,ios::end);
return file.tellg();
}
bool Mp3::isOk()
{
if (!myfile.is_open()) return false;
return true;
}
bool Mp3::getFirstFrame(Frame& f)
{
if(!frames.empty())
{
f = frames.front();
return true;
}
return false;
}
list<Frame> Mp3::get_frames(const char* myfilePath)
{
fstream file(myfilePath, ios::in | ios::binary);
char * memblock = new char [4]; //1º 4 bytes da frame...header.
char * start = memblock;
int i = 0;
char c;
list<Frame> lst;
Frame f;
while(!file.eof()){
while(i<4){
c=file.get();
f.addByte(c);
memblock[i++]=c;
}
file.seekg(-4,ios::cur);
i = 0;
if((memblock[0] == 0xFF) && ((memblock[1])& 0xE0) == 0xE0)
{
f.getFrame(myfilePath);//Pedaço do ficheiro ate encontrar prox header.
//Construir uma frame para meter na lista.
if(f.fastValidation() == 0)
{
lst.push_back((f));
memblock = start;
}
else
{
f.clear();
memblock = start;
file.seekg(1,ios::cur);
}
f.clear();
memblock = start;
file.seekg(1,ios::cur);
}
}
return lst;
}
void Mp3::WriteFrame(Frame& f, FILE * dst)
{
size_t num_bytes = f.getLength();
memcpy(dst,f.frame,num_bytes);
}
Frame.cpp
Frame::Frame()
{
Mp3();
numelems = 0;
length = 4;
bitmap= NULL;
}
void Frame::addByte(char byte)
{
if(numelems == length)
{
length *=2;
bitmap[numelems] = byte;
numelems++;
}
else
{
bitmap[numelems] = byte;
numelems++;
}
}
void Frame::clear()
{
bitmap= NULL;
numelems = 0;
}
void Frame::getFrame(fstream& file)
{
while(!file.eof())
{
if(file.get() == 0xFF && ((file.get() & 0xE0) == 0xE0))
return;
else
file.seekg(-2, ios_base::cur);
addByte(file.get());
}
return;
}
int Frame::getVersion()
{
return (bitmap[1] & MASK_VERS);
}
int Frame::getLayer()
{
return ((bitmap[1] & MASK_LAYER) >> OFFSET_LAYER);
}
int Frame::getBitrate()
{
return ((bitmap[2] & MASK_BITR_IDX) >> OFFSET_BIDX);
}
int Frame::getFrequency()
{
return ((bitmap[2] & MASK_FREQ) >> OFFSET_FREQ);
}
int Frame::fastValidation(Frame f)
{
if((f.getVersion() ==1) || (f.getLayer() == 0) || (f.getBitrate() == 0 || f.getBitrate() == 15) || (f.getFrequency() == 3))
return -1;
return 0;
}
I'm a bit unexperienced in coding with c++. So i apologize for some stupid mistakes u may encounter in this.
Cheers