00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "RawFileSource.h"
00020
00021 using namespace std;
00022 using namespace Marsyas;
00023
00024 RawFileSource::RawFileSource(mrs_string name):AbsSoundFileSource("RawFileSource", name)
00025 {
00026 sfp_ = NULL;
00027 buffer_ = NULL;
00028
00029 phaseOffset_ = 0.0;
00030 bufferSize_ = 0;
00031 time_ = 0.0;
00032
00033 hasData_ = true;
00034
00035 addControls();
00036 }
00037
00038 RawFileSource::~RawFileSource()
00039 {
00040 if (sfp_ != NULL)
00041 fclose(sfp_);
00042
00043 delete [] buffer_;
00044
00045 }
00046
00047 MarSystem* RawFileSource::clone() const
00048 {
00049 return new RawFileSource(*this);
00050 }
00051
00052 void
00053 RawFileSource::addControls()
00054 {
00055 addctrl("mrs_natural/nChannels",1);
00056 addctrl("mrs_real/frequency",440.0);
00057 setctrlState("mrs_real/frequency",true);
00058 addctrl("mrs_natural/size", 0);
00059 addctrl("mrs_natural/pos", 0);
00060 setctrlState("mrs_natural/pos", true);
00061 addctrl("mrs_string/filename", "defaultfile.au");
00062 setctrlState("mrs_string/filename", true);
00063 addctrl("mrs_bool/hasData", true);
00064 addctrl("mrs_bool/noteon", false);
00065 setctrlState("mrs_bool/noteon", true);
00066 addctrl("mrs_string/filetype", "raw");
00067 addctrl("mrs_bool/currentHasData", true, ctrl_currentHasData_);
00068 }
00069
00070
00071 void RawFileSource::openFile(mrs_string filename)
00072 {
00073 getHeader(filename);
00074 rate_ = fileSize_ * getctrl("mrs_real/frequency")->to<mrs_real>() / getctrl("mrs_real/israte")->to<mrs_real>();
00075 }
00076
00077
00078
00079 bool RawFileSource::getRawInfo( const char *fileName )
00080 {
00081
00082 struct stat filestat;
00083 if ( stat(fileName, &filestat) == -1 ) {
00084 return false;
00085 }
00086
00087
00088 fileSize_ = (mrs_natural) filestat.st_size / 2;
00089 bufferSize_ = fileSize_;
00090
00091
00092 byteSwap_ = true;
00093
00094 return true;
00095 }
00096
00097
00098
00099
00100 void RawFileSource::getHeader(mrs_string fileName)
00101 {
00102
00103 sfp_ = fopen(fileName.c_str(), "raw");
00104 if (sfp_ == NULL) {
00105 MRSWARN("Could not open file: " + fileName);
00106 return;
00107 }
00108
00109 bool result = getRawInfo( fileName.c_str() );
00110 if ( ! result ) {
00111 MRSWARN("Could not get raw data information from file: " + fileName);
00112 return;
00113 }
00114
00115
00116 mrs_natural samples = (bufferSize_+1)* getctrl("mrs_natural/nChannels")->to<mrs_natural>();
00117 data_.create(samples);
00118
00119 if(buffer_)
00120 delete [] buffer_;
00121 buffer_ = new short[bufferSize_];
00122
00123
00124 readData(0);
00125 }
00126
00127
00128 void RawFileSource::swap16(unsigned char *ptr)
00129 {
00130 register unsigned char val;
00131
00132
00133 val = *(ptr);
00134 *(ptr) = *(ptr+1);
00135 *(ptr+1) = val;
00136 }
00137
00138
00139
00140
00141
00142 void RawFileSource::readData(unsigned long index)
00143 {
00144 mrs_natural i;
00145 mrs_natural length = bufferSize_;
00146
00147
00148 if (fseek(sfp_, index, SEEK_SET) == -1) {
00149 MRSWARN("ERROR(fseek): could not read raw file data.");
00150 return;
00151 }
00152
00153 if (fread(buffer_, length, 2, sfp_) != 2 ) {
00154 MRSWARN("ERROR(fread): could not read raw file data");
00155 return;
00156 }
00157
00158
00159 byteSwap_ = true;
00160 if ( byteSwap_ ) {
00161 short* ptr = buffer_;
00162 for ( i=length; i>=0; i-- )
00163 swap16((unsigned char *)(ptr++));
00164 }
00165
00166 for ( i=length-1; i>=0; i-- ) {
00167 data_(i) = buffer_[i];
00168 }
00169
00170
00171 data_(length) = data_(length-1);
00172
00173
00174 mrs_real max = 0.0;
00175 for (i=0; i < length; ++i) {
00176 if (fabs(data_(i)) > max)
00177 max = (mrs_real) fabs((double) data_(i));
00178 }
00179
00180
00181 if (max > 0.0) {
00182 max = (mrs_real)(1.0 / max);
00183 max *= 1.0;
00184 for ( i=0; i <= length; ++i ) {
00185 data_(i) *= max;
00186 }
00187 }
00188
00189 }
00190
00191 void RawFileSource::myUpdate(MarControlPtr sender)
00192 {
00193 (void) sender;
00194
00195 nChannels_ = getctrl("mrs_natural/nChannels")->to<mrs_natural>();
00196 inSamples_ = getctrl("mrs_natural/inSamples")->to<mrs_natural>();
00197 inObservations_ = getctrl("mrs_natural/inObservations")->to<mrs_natural>();
00198 israte_ = getctrl("mrs_real/israte")->to<mrs_real>();
00199
00200 setctrl("mrs_natural/onSamples", inSamples_);
00201 setctrl("mrs_natural/onObservations", inObservations_);
00202 setctrl("mrs_real/osrate", israte_);
00203
00204 filename_ = getctrl("mrs_string/filename")->to<mrs_string>();
00205 pos_ = getctrl("mrs_natural/pos")->to<mrs_natural>();
00206
00207 rate_ = fileSize_ * getctrl("mrs_real/frequency")->to<mrs_real>() / israte_;
00208 }
00209
00210
00211 void RawFileSource::myProcess(realvec& in,realvec &out)
00212 {
00213 (void) in;
00214
00215
00216 mrs_real alpha;
00217 mrs_natural i, index;
00218
00219 if (!getctrl("mrs_bool/noteon")->isTrue()) {
00220 return;
00221 }
00222
00223 for (i = 0; i < inSamples_; ++i ) {
00224
00225
00226 if (time_ >= fileSize_) {
00227 time_ -= fileSize_;
00228 }
00229
00230
00231 index = (mrs_natural) time_;
00232 alpha = time_ - (mrs_real) index;
00233 out(0,i) = data_(index);
00234 out(0,i) += (alpha * (data_(index+1) - data_(index)));
00235
00236 time_ += rate_;
00237
00238 }
00239 ctrl_currentHasData_->setValue(hasData_);
00240 }