Ejemplo n.º 1
0
uint16_t Buzzer::getInfo(uint16_t time)
{
    uint16_t v = time%2000;
    return wave(v, 10);
}
Ejemplo n.º 2
0
int main(int argc, char **argv)
{
   ros::init(argc, argv, "wave");
   wave();
   return 0;
}
Ejemplo n.º 3
0
int main(){
    int n = 200;
    double N = (double) n;
    double rho_max = 10.;
    double rho_min = 0.;
    double h = (rho_max - rho_min)/N;
    double omega_r = 1.;
    double TIME1, TIME2;
    vec rho(n), V(n-2), eigval;
    mat A = zeros<mat>(n-2,n-2);
    mat eigvec;

    clock_t start, finish, start2, finish2; // Declare start and finish time
    for(int i=1; i<n-1; i++){
        rho[i] = rho_min + (i+1)*h;
        V[i] = omega_r*omega_r*rho[i]*rho[i] + 1./rho[i];
        }
    rho[0] = 0.;
    rho[n-1] = rho_max;

    //Initializes the matrix A:
    A.diag(-1) += -1./(h*h);
    A.diag(+1) += -1./(h*h);
    A.diag() = (2./(h*h)) + V;

    // Eigenvector matrix:
    mat R = eye<mat>(n-2,n-2);

    // Built in eigenvalue/eigenvector procedure in armadillo:
    start2 = clock();
    eig_sym(eigval, eigvec, A);
    finish2 = clock();

    // Jacobi method:
    start = clock();
    Jacobi(&A, &R, (n-2));
    finish = clock();

    TIME1 = (finish - start)/(double)CLOCKS_PER_SEC;
    TIME2 = (finish2 - start2)/(double)CLOCKS_PER_SEC;

    vec l;
    l = A.diag();

    // Wavefunction for the lowest energy level:

    double MIN = max(l);
    int index = 0;
    for(int i=0; i<n-2; i++){
        if(l(i) <= MIN){
            MIN = l(i);
            index = i;
        }
    }

    vec u_1 = R.col(index);
    vec wave(n);
    for(int i=1; i<n-1; i++){
        wave(i) = u_1(i-1);
    }

    // Dirichlet boundary conditions
    wave(0) = 0;
    wave(n-1) = 0;

    //Writing wave and rho to file:
    string filename;
    string Omega = static_cast<ostringstream*>( \
                &(ostringstream() << omega_r*100) )->str();
    filename = "wavefunc2_omega"+Omega+".dat";

    ofile.open(filename.c_str(), ios::out);
    for(int i=0; i<n; i++){ ofile << rho[i] << ' ' << wave[i] << endl; }
    ofile.close();

    vec lam = sort(l);
    cout << "omega_r = " << omega_r << endl;
    cout << "three lowest eigenvalues:" << endl;
    for(int i=0;i<3;i++){
        cout << "lambda = " << lam(i) << endl;
    }

    cout << "computation time for jacobi.cpp with n = " << n << ": " << TIME1 << " s" << endl;
    cout << "computation time for built in procedure with n = " << n << ": " << TIME2 << " s" << endl;

    return 0;
}
Ejemplo n.º 4
0
	///////////////////////////////////////////////////////////////////////////////
	//                                                                           //
	// Setup                                                                     //
	//                                                                           //
	///////////////////////////////////////////////////////////////////////////////
	aalError StreamWAV::SetStream(FILE * _stream)
	{
		if (!_stream) return AAL_ERROR_FILEIO;

		stream = _stream;

		format = malloc(sizeof(WAVEFORMATEX));

		if (!format) return AAL_ERROR_MEMORY;

		ChunkFile wave(stream);

		// Check for 'RIFF' chunk id and skip file size
		if (wave.Check("RIFF") ||
		        wave.Skip(4) ||
		        wave.Check("WAVE") ||
		        wave.Find("fmt ") ||
		        wave.Read(&AS_FORMAT_PCM(format)->wFormatTag, 2) ||
		        wave.Read(&AS_FORMAT_PCM(format)->nChannels, 2) ||
		        wave.Read(&AS_FORMAT_PCM(format)->nSamplesPerSec, 4) ||
		        wave.Read(&AS_FORMAT_PCM(format)->nAvgBytesPerSec, 4) ||
		        wave.Read(&AS_FORMAT_PCM(format)->nBlockAlign, 2) ||
		        wave.Read(&AS_FORMAT_PCM(format)->wBitsPerSample, 2))
			return AAL_ERROR_FORMAT;

		// Get codec specific infos from header for non-PCM format
		if (AS_FORMAT_PCM(format)->wFormatTag != WAVE_FORMAT_PCM)
		{
			aalVoid * ptr;

			//Load extra bytes from header
			if (wave.Read(&AS_FORMAT_PCM(format)->cbSize, 2)) return AAL_ERROR_FORMAT;

			ptr = realloc(format, sizeof(WAVEFORMATEX) + AS_FORMAT_PCM(format)->cbSize);

			if (!ptr) return AAL_ERROR_MEMORY;

			format = ptr;
			wave.Read((char *)format + sizeof(WAVEFORMATEX), AS_FORMAT_PCM(format)->cbSize);

			// Get sample count from the 'fact' chunk
			wave.Find("fact");
			wave.Read(&outsize, 4);
		}

		// Create codec
		switch (AS_FORMAT_PCM(format)->wFormatTag)
		{
			case WAVE_FORMAT_PCM   :
				codec = new CodecRAW;
				break;
			case WAVE_FORMAT_ADPCM :
				outsize <<= 1;
				codec = new CodecADPCM;
				break;
			default                :
				return AAL_ERROR_FORMAT;
		}

		// Check for 'data' chunk id, get data size and offset
		wave.Restart();
		wave.Skip(12);

		if (wave.Find("data")) return AAL_ERROR_FORMAT;

		size = wave.Size();

		if (AS_FORMAT_PCM(format)->wFormatTag == WAVE_FORMAT_PCM) outsize = size;
		else outsize *= AS_FORMAT_PCM(format)->nChannels;

		offset = FileTell(stream);

		aalError error;
		error = codec->SetStream(stream);

		if (error) return error;

		error = codec->SetHeader(format);

		if (error) return error;

		return AAL_OK;
	}
Ejemplo n.º 5
0
int
main(void) {
  const unsigned int pixels = 1920, piyels = 1920;
  const unsigned int nwave = 7;

  const float freq = 1.0/5.0;
  const float phases[] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0};

  const float angles[] = {0, M_PI/nwave, 2*M_PI/nwave, 3*M_PI/nwave,
                          4*M_PI/nwave, 5*M_PI/nwave, 6*M_PI/nwave,
                          7*M_PI/nwave, 8*M_PI/nwave, 9*M_PI/nwave};

  /* Uncomment this line (and its companions below) to actually render
   * the image! */
  /* greyscale_image *out = alloc_img(pixels, piyels); */

  /* A dummy buffer for outputting 32-bit RGBA fixed-point image
   * data. */
  uint32_t *img = NULL;
  if ((img = malloc(pixels * piyels * sizeof(*img))) == NULL)
    return 1;

  struct timespec before, after;
  clock_gettime(CLOCK_REALTIME, &before);

  for (unsigned int x = 0; x < pixels; x++)
    for (unsigned int y = 0; y < piyels; y++) {
      const unsigned int idx = pixels * x + y;
      /* Uncomment me and my undef buddy to output the real image! */
/* #define p out->v[idx] */
#ifndef p
      float p;
#endif  /* p */
      p = 0;
      for (unsigned int w = 0; w < nwave; w++)
        p += wave(freq, phases[w], angles[w], x - pixels / 2, y - piyels / 2);
      p = (cos(M_PI * p) + 1) / 2;
      const uint8_t tmp = (uint8_t) (255 * MIN(1, MAX(p, 0)));
/* #undef p */
      img[idx] = (0xff << 24) | tmp << 16 | tmp << 8 | tmp;
    }

  clock_gettime(CLOCK_REALTIME, &after);

  printf("elapsed time: %lf seconds.\n",
         after.tv_sec - before.tv_sec +
         (after.tv_nsec - before.tv_nsec) * 1e-9);

  /* Make sure GCC doesn't cheat and not calculate anything! */
  printf("First element of img: 0x%08X\n", img[0]);

  /* Uncomment me to output the real image! */
  /* write_img("c_out.png", out); */

  /* Uncomment everything here to output some data for comparison with
   * the qc.hs module. */

  /* printf("phase\tangle\n"); */
  /* for (unsigned int i = 0; i < nwave; i++) */
  /*   printf("%f\t%f\n", phases[i], angles[i]); */
  /* printf("\n"); */

  /* #define testwrite(call) printf("\t" #call " = %f\n", call) */

  /* printf("Tests:\n"); */
  /* testwrite(wave(0.2, 0, 0, 0, 0)); */
  /* testwrite(wave(0.2, 0, 0, 2, 2)); */
  /* testwrite(wave(0.2, 22, 22, 2, 2)); */
  /* testwrite(wave(0.2, 22, 22, 22, 22)); */
  /* testwrite(wave(0.2, 0.2, 0.2, 500, 600)); */

  return 0;
}
Ejemplo n.º 6
0
void SPO2H(int transmit_mode)
{
	USE_LCD();
	SpO2_lcd();
    int_adc();

    Init_UART2();
    UCA0IE |= UCRXIE;

    //PMM_setVCore(PMM_BASE, PMM_CORE_LEVEL_2);
    initClocks(20000000);   // Config clocks. MCLK=SMCLK=FLL=8MHz; ACLK=REFO=32kHz
    delay_2();
    delay_2();
//    USB_setup(TRUE,TRUE);
    BUTTON_S4=0;
    while(!(buttonsPressed & BUTTON_S4))
    {
        Init_UART2();
        UCA0IE |= UCRXIE;
        _EINT();
       // delay_2();
      //  delay_2();
        ad();
        if(BUTTON_S4==0){
        on_ired();
        wave(1);    //显示红光
      /*  for(i=0;i<480;i++){
            results[i+480]=results[i];
        }*/
        NONUSE_LCD();
        save();  //      前0-480为红外 1000-1480为
       // delay_2();
  //      delay_2();
        ad();
        if(BUTTON_S4==0){
        on_red();
        wave(0);    //显示红外
       unsigned int count=0;   //ired
       unsigned int count1=0;  //red
       unsigned int count_spa=0;
       unsigned int count1_spa=0;
       //调试时 使用

       int red_hr=0;
       int hr = 0; //心率
       unsigned int j = 0, j1 = 0;


       for(i = 9; i < max-10 ;i++)  //ired
       {
           if(results[i]>=results[i+1]&&results[i]>=results[i+2]&&results[i]>=results[i+3]&&results[i]>=results[i-1]&&results[i]>=results[i-2]&&results[i]>=results[i-3]&&j<4&&
                   results[i]>=results[i+4]&&results[i]>=results[i+5]&&results[i]>=results[i+6]&&results[i]>=results[i-4]&&results[i]>=results[i-5]&&results[i]>=results[i-6]&&
                   results[i]>=results[i+7]&&results[i]>=results[i+8]&&results[i]>=results[i+9]&&results[i]>=results[i-7]&&results[i]>=results[i-8]&&results[i]>=results[i-9])
           {
               r_locate[count] = i;
               count++;
               if(count>=10)break;
               i = i+40;
           }

       }

       for(i = 9+480; i < max-10+480 ;i++)  //red
       {
           if(results[i]>=results[i+1]&&results[i]>=results[i+2]&&results[i]>=results[i+3]&&results[i]>=results[i-1]&&results[i]>=results[i-2]&&results[i]>=results[i-3]&&j1<4&&
                   results[i]>=results[i+4]&&results[i]>=results[i+5]&&results[i]>=results[i+6]&&results[i]>=results[i-4]&&results[i]>=results[i-5]&&results[i]>=results[i-6]&&
                   results[i]>=results[i+7]&&results[i]>=results[i+8]&&results[i]>=results[i+9]&&results[i]>=results[i-7]&&results[i]>=results[i-8]&&results[i]>=results[i-9])
           {
               r1_locate[count1] = i;
               count1++;
               if(count1>=10)break;
               i=i+40;
           }
       }

       /*计算心率 其实最后一个峰值坐标减去第一个 再除以个数就可以了哦*/
       count_spa = count - 1;
       count1_spa = count1 - 1;

      hr = (r_locate[count_spa]-r_locate[0])/count_spa;
      hr=(1.0/(float)(hr*0.01))*60;

      red_hr = (r1_locate[count1_spa]-r1_locate[0])/count1_spa;
      red_hr=(1.0/(float)(red_hr*0.01))*60;  //


      /*直流算平均值*/
      red_dc = 0.0;
      ired_dc = 0.0;
      length_idc = (float)(r_locate[count_spa]-r_locate[count_spa -2]);    //ired
      length_dc = (float)(r1_locate[count1_spa] - r1_locate[count1_spa -2]);
      for(i = r1_locate[count1_spa -2] ; i <r1_locate[count1_spa];i++)    //最后的位置是采样到最后一个峰峰值的坐标
      {
          red_dc += (float)results1[i]/length_dc;
      }
      for(i = r_locate[count_spa -2] ; i <r_locate[count_spa];i++)    //最后的位置是采样到最后一个峰峰值的坐标
      {
          ired_dc += (float)results1[i]/length_idc;
      }

      /*最小值及交流峰峰值 最后2个周期才稳定 可以用最后2个周期算峰峰值*/
      /*同时 红光用前一个峰值减去谷值 红外用后一个峰值减去谷值 去基线漂移*/
       red_min = results[1+480];//(float)red[0];
       ired_min = results[1];//(float)results[0];  避免第一个数采得不准
       ired_ac = 0;
       red_ac = 0;

       for(i =( count_spa -2); i <count_spa ;i++)  //ired
       {
           for(j=r_locate[i]; j < r_locate[i+1] ;j++)
           {
               if(results[j]<ired_min){ired_min=results[j];}
           }
           ired_ac += results[r_locate[i+1]] - ired_min;
           nr_locate[i]=ired_min;
           ired_min = results[1]; //更新初值
       }
       ired_ac = ired_ac/2;

       for(i = (count1_spa -2); i <count1_spa ;i++)  //red
       {
           for(j=r1_locate[i]; j < r1_locate[i+1] ;j++)
           {
               if(results[j]<red_min){red_min=results[j];}
           }
           red_ac += results[r1_locate[i]] - red_min;
           nr1_locate[i] = red_min;
           red_min = results[481];
       }
       red_ac = red_ac/2;


       /*计算血氧含量*/
       Q1 = (float)(red_ac/red_dc);
       Q2 = (float)ired_ac/(float)ired_dc ;
       Q = Q1/Q2 ;
       sao2 = (-4.1768)*Q + 100.9352 + 0.5;

       if(abs(hr-red_hr)>=10)                  //两次采样的心率值相差不大的情况下才更新Q
       {
           Q = pre_Q;
       }

       /*显示*/
       USE_LCD();
       SPILCD_Clear_Lim(212,260,18,52,WHITE); //371 355
       SPILCD_Clear_Lim(348,396,18,52,WHITE);
       unsigned int temp1,temp10,temp100;
       long temp_final1;
       long temp_final2;

       temp1=hr%10;             //计算心率个位
       temp10=(hr%100-temp1)/10;    //计算心率十位
       temp100=(hr-temp10*10-temp1)/100;    //计算心率百位
       temp_final1=(long)(temp1+temp10*10+temp100*100);
       if(temp100>0)    DRAW_NUM(244,20,temp100,BLUE);  //显示心率百位
       DRAW_NUM(228,18,temp10,BLUE);         //显示心率十位
       DRAW_NUM(212,18,temp1,BLUE);       //显示心率个位

       sao2=99;
       temp1=sao2%10;                  //计算个位
       temp10=(sao2%100-temp1)/10;    //计算十位
       temp100=(sao2-temp10*10-temp1)/100;    //计算百位
       temp_final2=(long)(temp1+temp10*10+temp100*100);
       if(temp100>0)    DRAW_NUM(380,18,temp100,BLUE);  //显示心率百位
       DRAW_NUM(364,18,temp10,BLUE);  //显示十位
       DRAW_NUM(348,18,temp1,BLUE);    //显示个位
       NONUSE_LCD();
       i = 0;

       pre_Q = Q;   //记录这次显示的Q

  /*     char start[7]={'S','T','A','R','T','S','O'};
       long a;
       char b[5];
       char c[3];
       char d[3];
       ltoa(temp_final1,b);
       if(temp_final1>=0&&temp_final1<=9)
       {
       c[0]='0';
       c[1]='0';
       c[2]=b[0];
       }
       if(temp_final1>=10&&temp_final1<=99)
       {
       c[0]='0';
       c[1]=b[0];
       c[2]=b[1];
       }
       if(temp_final1>=100&&temp_final1<=999)
       {
       c[0]=b[0];
       c[1]=b[1];
       c[2]=b[2];
       }

       ltoa(temp_final2,b);
       if(temp_final2>=0&&temp_final2<=9)
       {
       d[0]='0';
       d[1]='0';
       d[2]=b[0];
       }
       if(temp_final2>=10&&temp_final2<=99)
       {
       d[0]='0';
       d[1]=b[0];
       d[2]=b[1];
       }
       if(temp_final2>=100&&temp_final2<=999)
       {
       d[0]=b[0];
       d[1]=b[1];
       d[2]=b[2];
       }

       char end[3]={'E','N','D'};
       j=0;
       for(j=0;j<960;j++)        //采样数据除以40转化成两位,便于传送
           {
           results[j]=results[j]/40;
           }*/
       int i;
       for(i=959;i>=0;i--)
       {
           results[i+10]=results[i]>>5;
       }
       results[0]='S';
       results[1]='T';
       results[2]='A';
       results[3]='R';
       results[4]='T';
       results[5]='S';
       results[6]='O';
       if(hr>=127){
       results[7]=0x7F;
       results[8]=(char)(hr-127);}
       else{
     	  results[7]=(char)(hr);
     	  results[8]=0;
       }
       results[9]=sao2;
       results[970]='A';
       results[971]='A';
       results[972]='A';
       results[973]='A';
       results[974]='A';
//       results[974]=0x7F;
       results[975]='E';
       results[976]='N';
       results[977]='D';
//       CRCresult=0;
//       for(i=9;i<969;i++)
//       {
//           results[i]=results[i]>>5;
//           CRCtmp = CRCresult%256;
//           CRCindex = CRCtmp^results[i];
//           CRCtmp = CRCresult/256;   //除以256
//           CRCresult = CRCtmp;
//           CRCresult = CRCresult^CRC_TA[CRCindex];
//       }
//       long a;
//       char b[5];
//       a=CRCresult;
//       ltoa(a,b);
//       results[969]=b[0];
//       results[970]=b[1];
//       results[971]=b[2];
//       results[972]=b[3];
//       results[973]=b[4];
//       results[974]='E';
//       results[975]='N';
//       results[976]='D';



       if(transmit_mode==1){
           bcUartInit();
           bcUartSend_char(results,978);//buf_bcuartToUsb
       }


       if(transmit_mode==2){
           hidSendDataInBackground(results,1956, HID0_INTFNUM,10000);
       }


        if(transmit_mode==3){
      	 int i;
      	 for(i=0;i<978;i++)
      	 {
               UCA0TXBUF = results[i];

               while(!(UCTXIFG==(UCTXIFG & UCA0IFG))&&((UCA0STAT & UCBUSY)==UCBUSY));

               int a,k;
               for(a=0;a<10;a++)
               {
                    for(k=0;k<80;k++);
               }
      	 }
       }

	   BUTTON_S4=0;
	   buttonsPressed=0;
	   NONUSE_LCD();
        }
        }
Ejemplo n.º 7
0
void
main(void)
{
//	int i;
	extern char bdata[], edata[], end[], etext[];
	static ulong vfy = 0xcafebabe;

	/* l.s has already printed "Plan 9 from Be" */
//	m = mach;					/* now done in l.s */

	/* realign data seg; apparently -H0 -R4096 does not pad the text seg */
	if (vfy != 0xcafebabe) {
//		wave('<'); wave('-');
		memmove(bdata, etext, edata - bdata);
	}
	/*
	 * once data segment is in place, always zero bss since we may
	 * have been loaded by another Plan 9 kernel.
	 */
	memset(edata, 0, end - edata);		/* zero BSS */
	cacheuwbinv();
	l2cacheuwbinv();

	if (vfy != 0xcafebabe)
		panic("data segment misaligned");
	vfy = 0;

wave('l');
	machinit();
	mmuinit();

	optionsinit("/boot/boot boot");
	quotefmtinstall();

	/* want plan9.ini to be able to affect memory sizing in confinit */
	plan9iniinit();		/* before we step on plan9.ini in low memory */

	trapinit();		/* so confinit can probe memory to size it */
	confinit();		/* figures out amount of memory */
	/* xinit prints (if it can), so finish up the banner here. */
	delay(500);
	iprint("l Labs\n\n");
	delay(500);
	xinit();

	mainmem->flags |= POOL_ANTAGONISM /* | POOL_PARANOIA */ ;

	/*
	 * Printinit will cause the first malloc call.
	 * (printinit->qopen->malloc) unless any of the
	 * above (like clockinit) do an irqenable, which
	 * will call malloc.
	 * If the system dies here it's probably due
	 * to malloc(->xalloc) not being initialised
	 * correctly, or the data segment is misaligned
	 * (it's amazing how far you can get with
	 * things like that completely broken).
	 *
	 * (Should be) boilerplate from here on.
	 */

	archreset();			/* configure clock signals */
	clockinit();			/* start clocks */
	timersinit();
	watchdoginit();

	delay(250);			/* let uart catch up */
	printinit();
//	kbdenable();

	cpuidprint();
//	chkmissing();

	procinit0();
	initseg();

	dmainit();
	links();
	conf.monitor = 1;
	screeninit();
	chandevreset();			/* most devices are discovered here */

//	i8250console();			/* too early; see init0 */

	pageinit();
	swapinit();
	userinit();
	schedinit();
}
/**
        \fn parseStbl
        \brief parse sample table. this is the most important function.
*/
uint8_t       MP4Header::parseStbl(void *ztom,uint32_t trackType,uint32_t w,uint32_t h,uint32_t trackScale)
{
  adm_atom *tom=(adm_atom *)ztom;
  ADMAtoms id;
  uint32_t container;
  MPsampleinfo  info;


  memset(&info,0,sizeof(info));


  printf("<<Parsing Stbl>>\n");
  while(!tom->isDone())
  {
     adm_atom son(tom);
     if(!ADM_mp4SearchAtomName(son.getFCC(), &id,&container))
     {
       adm_printf(ADM_PRINT_DEBUG,"[STBL]Found atom %s unknown\n",fourCC::tostringBE(son.getFCC()));
       son.skipAtom();
       continue;
     }
     switch(id)
     {
       case ADM_MP4_STSS:  // Sync sample atom (i.e. keyframes)
       {
          son.read32();
          info.nbSync=son.read32();
          printf("Stss:%u\n",info.nbSync);
          if(info.nbSync)
          {
                  info.Sync=new uint32_t[info.nbSync];
                  for(int i=0;i<info.nbSync;i++)
                  {
                          info.Sync[i]=son.read32();
                  }
          }
          break;

       }
       case ADM_MP4_STTS:
            {
                printf("stts:%lu\n",son.read32()); // version & flags
                info.nbStts=son.read32();
                printf("Time stts atom found (%lu)\n",info.nbStts);
                printf("Using myscale %lu\n",trackScale);
                info.SttsN=new uint32_t[info.nbStts];
                info.SttsC=new uint32_t[info.nbStts];
                //double dur;
                for(int i=0;i<info.nbStts;i++)
                {

                        info.SttsN[i]=son.read32();
                        info.SttsC[i]=son.read32();
                        adm_printf(ADM_PRINT_VERY_VERBOSE,"stts: count:%u size:%u (unscaled)\n",info.SttsN[i],info.SttsC[i]);
                        //dur*=1000.*1000.;; // us
                        //dur/=myScale;
                }
            }
            break;
       case ADM_MP4_STSC:
            {
                son.read32();
                info.nbSc=son.read32();
                info.Sc=new uint32_t[info.nbSc];
                info.Sn=new uint32_t[info.nbSc];
                for(int j=0;j<info.nbSc;j++)
                {

                        info.Sc[j]=son.read32();
                        info.Sn[j]=son.read32();
                        son.read32();
                        adm_printf(ADM_PRINT_VERY_VERBOSE,"\t sc  %d : sc start:%u sc count: %u\n",j,info.Sc[j],info.Sn[j]);
                }

            }
            break;
       case ADM_MP4_STSZ:
          {
            uint32_t n;
              son.read32();
              n=son.read32();
              info.nbSz=son.read32();
              info.SzIndentical=0;
              printf("%lu frames /%lu nbsz..\n",n,info.nbSz);
              if(n)
                      {
                            adm_printf(ADM_PRINT_VERY_VERBOSE,"\t\t%lu frames of the same size %lu , n=%lu\n",
                                info.nbSz,info.SzIndentical,n);
                            info.SzIndentical=n;
                            info.Sz=NULL;
                      }
              else
              {
                      info.Sz=new uint32_t[info.nbSz];
                      for(int j=0;j<info.nbSz;j++)
                      {
                                      info.Sz[j]=son.read32();
                      }
              }
          }
          break;
           case ADM_MP4_CTTS: // Composition time to sample
            {
                uint32_t n,i,j,k,v;

                  printf("ctts:%lu\n",son.read32()); // version & flags
                  n=son.read32();
                  if(n==1) // all the same , ignore
                  {
                    break;
                  }
                uint32_t *values=new uint32_t [n];
                uint32_t *count=new uint32_t [n];
                for(i=0;i<n;i++)
                {
                    count[i]=son.read32();
                    values[i]=son.read32();
                }
                uint32_t sum=0;
                for(i=0;i<n;i++)
                {
                    sum+=count[i];
                }
                info.Ctts=new uint32_t[sum+1]; // keep a safe margin

                for(i=0;i<n;i++)
                {
                    if(i<20)
                    {
                        adm_printf(ADM_PRINT_VERY_VERBOSE,"Ctts: nb: %u (%x) val:%u (%x)\n",count[i],count[i],values[i],values[i]);
                    }
                    for(k=0;k<count[i];k++)
                    {
                        info.Ctts[info.nbCtts++]=values[i];
                    }
                }
                delete [] values;
                delete [] count;
                if(!info.nbCtts)
                {
                    delete [] info.Ctts;
                    info.Ctts=NULL;
                    printf("Destroying Ctts, seems invalid\n");
                }
                ADM_assert(info.nbCtts<sum+1);
                printf("Found %u elements\n",info.nbCtts);
            }
            break;
       case ADM_MP4_STCO:
       {
		   son.skipBytes(4);

		   info.nbCo = son.read32();
		   printf("\t\tnbCo: %u\n", info.nbCo);

		   info.Co = new uint64_t[info.nbCo];

		   for(int j = 0; j < info.nbCo; j++)
		   {
			   info.Co[j] = son.read32();
			   adm_printf(ADM_PRINT_VERY_VERBOSE, "Chunk offset: %u / %u : %"LLU"\n", j, info.nbCo - 1, info.Co[j]);
		   }
       }
       break;
       case ADM_MP4_STCO64:
       {
		   son.skipBytes(4);

		   info.nbCo = son.read32();
		   printf("\t\tnbCo: %u\n", info.nbCo);

		   info.Co = new uint64_t[info.nbCo];

		   for(int j = 0; j< info.nbCo; j++)
		   {
			   info.Co[j] = son.read64();
			   adm_printf(ADM_PRINT_VERY_VERBOSE, "Chunk offset: %u / %u : %"LLU"\n", j, info.nbCo - 1, info.Co[j]);
		   }
       }
       break;
       case ADM_MP4_STSD:
       {
                son.read32(); // flags & version
                int nbEntries=son.read32();
                int left;
                adm_printf(ADM_PRINT_DEBUG,"[STSD]Found %d entries\n",nbEntries);
                for(int i=0;i<nbEntries;i++)
                {
                   int entrySize=son.read32();
                   int entryName=son.read32();
                   left=entrySize-8;
                   if(i || (trackType==TRACK_VIDEO && _videoFound) || (trackType==TRACK_OTHER))
                   {
                    son.skipBytes(left);
                    printf("[STSD] ignoring %s, size %u\n",fourCC::tostringBE(entryName),entrySize);
                    if(trackType==TRACK_OTHER) printf("[STSD] because track=other\n");
                    continue;
                   }
                   switch(trackType)
                   {
                     case TRACK_VIDEO:
                     {
                          uint32_t lw=0,lh=0;
                                printf("[STSD] VIDEO %s, size %u\n",fourCC::tostringBE(entryName),entrySize);
                                son.skipBytes(8);  // reserved etc..
                                left-=8;
                                son.read32(); // version/revision
                                left-=4;
                                printf("[STSD] vendor %s\n",fourCC::tostringBE(son.read32()));
                                left-=4;

                                son.skipBytes(8); // spatial qual etc..
                                left-=8;

                                printf("[STSD] width :%u\n",lw=son.read16());
                                printf("[STSD] height :%u\n",lh=son.read16());
                                left-=4;

                                son.skipBytes(8); // Resolution
                                left-=8;

                                printf("[STSD] datasize :%u\n",son.read32());
                                left-=4;

                                printf("[STSD] FrameCount :%u\n",son.read16());
                                left-=4;

                                // Codec name
                                uint32_t u32=son.read();
                                if(u32>31) u32=31;
                                printf("Codec string :%d <",u32);
                                for(int i=0;i<u32;i++) printf("%c",son.read());
                                printf(">\n");
                                son.skipBytes(32-1-u32);
                                left-=32;
                                //
                                if(left>=4)
                                {
                                    son.read32();
                                    left-=4; //Depth & color Id
                                }else left=0;
                                //
                                printf("LEFT:%d\n",left);

                                if(left>8)
                                {
//                                  decodeVideoAtom(&son);
                                }
                                //
#define commonPart(x)             _videostream.fccHandler=_video_bih.biCompression=fourCC::get((uint8_t *)#x);


                                 _video_bih.biWidth=_mainaviheader.dwWidth=lw ;
                                  _video_bih.biHeight=_mainaviheader.dwHeight=lh;
                                  _video_bih.biCompression=_videostream.fccHandler;

                                //
                                switch(entryName)
                                {
                                  case MKFCCR('m','j','p','b'):  //mjpegb
                                  {
                                        commonPart(MJPB);
                                        left=0;
                                  }
                                  case MKFCCR('m','j','p','a'):  //mjpegb
                                 {
                                       commonPart(MJPG);
                                       left=0;
                                 }
                                  break;
                                case MKFCCR('s','2','6','3'):  //s263 d263
                                  {
                                        commonPart(H263);
                                         adm_atom d263(&son);
                                         printf("Reading s253, got %s\n",fourCC::tostringBE(d263.getFCC()));
                                          left=0;
                                  }
                                  break;
                                   case MKFCCR('m','p','4','v'):  //mp4v
                                  {
                                        commonPart(DIVX);
                                         adm_atom esds(&son);
                                         printf("Reading esds, got %s\n",fourCC::tostringBE(esds.getFCC()));
                                         if(esds.getFCC()==MKFCCR('e','s','d','s'))
                                              decodeEsds(&esds,TRACK_VIDEO);
                                          left=0;
                                  }
                                        break;
                                  case MKFCCR('S','V','Q','3'):
                                  {//'SVQ3':
                                    // For SVQ3, the codec needs it to begin by SVQ3
                                    // We go back by 4 bytes to get the 4CC
                                            printf("SVQ3 atom found\n");
                                            VDEO.extraDataSize=left+4;
                                            VDEO.extraData=new uint8_t[ VDEO.extraDataSize ];
                                            if(!son.readPayload(VDEO.extraData+4,VDEO.extraDataSize-4 ))
                                            {
                                              GUI_Error_HIG(QT_TR_NOOP("Problem reading SVQ3 headers"), NULL);
                                            }
                                            VDEO.extraData[0]='S';
                                            VDEO.extraData[1]='V';
                                            VDEO.extraData[2]='Q';
                                            VDEO.extraData[3]='3';
                                            printf("SVQ3 Header size : %lu",_videoExtraLen);
                                            commonPart(SVQ3);
                                            left=0;
                                  }
                                            break;
                                  case MKFCCR('d','v','c',' ') : //'dvc ':
                                  case MKFCCR('d','v','c','p'): //'dvcp':
                                          commonPart(DVDS);
                                          break;
                                  case MKFCCR('c','v','i','d'): //'cvid'
                                          commonPart(cvid);
                                          break;
                                  case MKFCCR('h','2','6','3'): //'dv':
                                          commonPart(H263);
                                          break;
                                  case MKFCCR('M','J','P','G'): //'jpeg':
                                  case MKFCCR('j','p','e','g'): //'jpeg':
                                  case MKFCCR('A','V','D','J'): //'jpeg':
                                          commonPart(MJPG);
                                          break;
                                  case MKFCCR('a','v','c','1'): // avc1
                                          {
                                          commonPart(H264);
                                          // There is a avcC atom just after
                                          // configuration data for h264
nextAtom:
                                          adm_atom avcc(&son);
                                          printf("Reading avcC, got %s\n",fourCC::tostringBE(avcc.getFCC()));
                                          switch(avcc.getFCC())
                                          {
                                              case MKFCCR('a','v','c','C'): break;
                                              default:
                                              case MKFCCR('c','o','l','r'):  // Color atom
                                              case MKFCCR('p','a','s','p'):
                                              case MKFCCR('c','l','a','p'):
                                                  avcc.skipAtom();
                                                  goto nextAtom;
                                                  break;
                                          }
                                          int len,offset;
                                          VDEO.extraDataSize=avcc.getRemainingSize();
                                          VDEO.extraData=new uint8_t [VDEO.extraDataSize];
                                          avcc.readPayload(VDEO.extraData,VDEO.extraDataSize);
                                          printf("avcC size:%d\n",VDEO.extraDataSize);
                                    // Dump some info
                                        #define MKD8(x) VDEO.extraData[x]
                                        #define MKD16(x) ((MKD8(x)<<8)+MKD8(x+1))
                                        #define MKD32(x) ((MKD16(x)<<16)+MKD16(x+2))

                                            printf("avcC Revision             :%x\n", MKD8(0));
                                            printf("avcC AVCProfileIndication :%x\n", MKD8(1));
                                            printf("avcC profile_compatibility:%x\n", MKD8(2));
                                            printf("avcC AVCLevelIndication   :%x\n", MKD8(3));

                                            printf("avcC lengthSizeMinusOne   :%x\n", MKD8(4));
                                            printf("avcC NumSeq               :%x\n", MKD8(5));
                                            len=MKD16(6);
                                            printf("avcC sequenceParSetLen    :%x ",len );
                                            offset=8;
                                            mixDump(VDEO.extraData+offset,len);

                                            offset=8+len;
                                            printf("\navcC numOfPictureParSets  :%x\n", MKD8(offset++));
                                            len=MKD16(offset);
                                            offset++;
                                            printf("avcC Pic len              :%x\n",len);
                                            mixDump(VDEO.extraData+offset,len);
                                            left=0;
                                            }
                                            break;
                                  default:
                                            if(left>10)
                                            {
                                                adm_atom avcc(&son);
                                                printf("Reading , got %s\n",fourCC::tostringBE(avcc.getFCC()));
                                                left=0;

                                            }
                                            break;
                                } // Entry name
                     }
                     break;
                     case TRACK_AUDIO:
                     {
                        uint32_t channels,bpp,encoding,fq,packSize;

                                // Put some defaults
                                ADIO.encoding=1234;
                                ADIO.frequency=44100;
                                ADIO.byterate=128000>>3;
                                ADIO.channels=2;
                                ADIO.bitspersample=16;

                                printf("[STSD] AUDIO <%s>, 0x%08x, size %u\n",fourCC::tostringBE(entryName),entryName,entrySize);
                                son.skipBytes(8);  // reserved etc..
                                left-=8;

                                int atomVersion=son.read16();  // version
                                left-=2;
                                printf("[STSD]Revision       :%d\n",atomVersion);
                                son.skipBytes(2);  // revision
                                left-=2;

                                printf("[STSD]Vendor         : %s\n",fourCC::tostringBE(son.read32()));
                                left-=4;

                                ADIO.channels=channels=son.read16(); // Channel
                                left-=2;
                                printf("[STSD]Channels       :%d\n",ADIO.channels);
                                ADIO.bitspersample=bpp=son.read16(); // version/revision
                                left-=2;
                                printf("[STSD]Bit per sample :%d\n",bpp);

                                encoding=son.read16(); // version/revision
                                left-=2;
                                printf("[STSD]Encoding       :%d\n",encoding);

                                packSize=son.read16(); // Packet Size
                                left-=2;
                                printf("[STSD]Packet size    :%d\n",encoding);


                                fq=ADIO.frequency=son.read16();
                                printf("[STSD]Fq:%u\n",fq);
                                if(ADIO.frequency<6000) ADIO.frequency=48000;
                                printf("[STSD]Fq       :%d\n",ADIO.frequency); // Bps
                                        son.skipBytes(2); // Fixed point
                                left-=4;
                                if(atomVersion)
                                {
                                    info.samplePerPacket=son.read32();
                                    info.bytePerPacket=son.read32();
                                    info.bytePerFrame=son.read32();
                                    printf("[STSD] Sample per packet %u\n",info.samplePerPacket);
                                    printf("[STSD] Bytes per packet  %u\n",info.bytePerPacket);
                                    printf("[STSD] Bytes per frame   %u\n",info.bytePerFrame);
                                    printf("[STSD] Bytes per sample   %u\n",son.read32());
                                    left-=16;
                                }else
                                {
                                  info.samplePerPacket=1;
                                  info.bytePerPacket=1;
                                  info.bytePerFrame=1;
                                }
                                switch(atomVersion)
                                {
                                  case 0:break;
                                  case 1: break;
                                  case 2:
                                          ADIO.frequency=44100; // FIXME
                                          ADIO.channels=son.read32();
                                          printf("Channels            :%d\n",ADIO.channels); // Channels
                                          printf("Tak(7F000)          :%x\n",son.read32()); // Channels
                                          printf("Bits  per channel   :%d\n",son.read32());  // Vendor
                                          printf("Format specific     :%x\n",son.read32());  // Vendor
                                          printf("Byte per audio packe:%x\n",son.read32());  // Vendor
                                          printf("LPCM                :%x\n",son.read32());  // Vendor
                                          left-=(5*4+4+16);
                                          break;
                                }
                                printf("[STSD] chan:%u bpp:%u encoding:%u fq:%u (left %u)\n",channels,bpp,encoding,fq,left);
#define audioCodec(x) ADIO.encoding=WAV_##x;
                                switch(entryName)
                                {

                                    case MKFCCR('t','w','o','s'):
                                            audioCodec(LPCM);
                                            ADIO.byterate=ADIO.frequency*ADIO.bitspersample*ADIO.channels/8;
                                            break;

                                    case MKFCCR('u','l','a','w'):
                                            audioCodec(ULAW);
                                            ADIO.byterate=ADIO.frequency;
                                            break;
                                    case MKFCCR('s','o','w','t'):
                                            audioCodec(PCM);
                                            ADIO.byterate=ADIO.frequency*ADIO.bitspersample*ADIO.channels/8;
                                            break;
                                    case MKFCCR('.','m','p','3'): //.mp3
                                            audioCodec(MP3);
                                            ADIO.byterate=128000>>3;
                                            break;
                                    case MKFCCR('r','a','w',' '):
                                            audioCodec(8BITS_UNSIGNED);
                                            ADIO.byterate=ADIO.frequency*ADIO.channels;
                                            break;
                                    case MKFCCR('s','a','m','r'):
                                    {
                                            audioCodec(AMRNB);
                                            ADIO.frequency=8000;
                                            ADIO.channels=1;
                                            ADIO.bitspersample=16;
                                            ADIO.byterate=12000/8;
                                            if(left>10)
                                            {
                                               adm_atom amr(&son);
                                              printf("Reading wave, got %s\n",fourCC::tostringBE(amr.getFCC()));
                                              left=0;
                                            }
                                    }
                                            break;
                                    case MKFCCR('Q','D','M','2'):
                                        {
                                            int64_t sz;
                                              audioCodec(QDM2);
                                              sz=son.getRemainingSize();
                                              _tracks[1+nbAudioTrack].extraDataSize=sz;
                                              _tracks[1+nbAudioTrack].extraData=new uint8_t[sz];
                                              son.readPayload(_tracks[1+nbAudioTrack].extraData,sz);
                                              left=0;
                                        }
                                        break;
                                    case MKFCCR('m','s',0,0x55): // why 55 ???
                                    case MKFCCR('m','p','4','a'):
                                    {
                                              audioCodec(AAC);
                                            if(left>10)
                                            {
                                              adm_atom wave(&son);
                                              printf("Reading wave, got %s\n",fourCC::tostringBE(wave.getFCC()));
                                              if(MKFCCR('w','a','v','e')==wave.getFCC())
                                              {
                                                 // mp4a
                                                 //   wave
                                                 //     frma
                                                 //     mp4a
                                                 //     esds
                                                 while(!wave.isDone())
                                                 {
                                                     adm_atom item(&wave);
                                                     printf("parsing wave, got %s,0x%x\n",fourCC::tostringBE(item.getFCC()),
                                                                  item.getFCC());
                                                     switch(item.getFCC())
                                                     {
                                                       case MKFCCR('f','r','m','a'):
                                                          {
                                                          uint32_t codecid=item.read32();
                                                          printf("frma Codec Id :%s\n",fourCC::tostringBE(codecid));
                                                          }
                                                          break;
                                                       case MKFCCR('m','s',0,0x55):
                                                        {
                                                          // We have a waveformat here
                                                          printf("[STSD]Found MS audio header:\n");
                                                          ADIO.encoding=ADM_swap16(item.read16());
                                                          ADIO.channels=ADM_swap16(item.read16());
                                                          ADIO.frequency=ADM_swap32(item.read32());
                                                          ADIO.byterate=ADM_swap32(item.read32());
                                                          ADIO.blockalign=ADM_swap16(item.read16());
                                                          ADIO.bitspersample=ADM_swap16(item.read16());
                                                          printWavHeader(&(ADIO));

                                                        }
                                                       break;
                                                        case MKFCCR('m','p','4','a'):
                                                          break;
                                                        case MKFCCR('e','s','d','s'):
                                                          {
                                                               decodeEsds(&item,TRACK_AUDIO);
                                                          goto foundit; // FIXME!!!
                                                          }
                                                          break;
                                                       default:
                                                         break;
                                                     }

                                                     item.skipAtom();

                                                 }  // Wave iddone
                                                 left=0;
                                              }  // if ==wave
                                              else
                                              {
                                                if(wave.getFCC()==MKFCCR('e','s','d','s'))
                                                          {
                                                               decodeEsds(&wave,TRACK_AUDIO);
                                                               goto foundit; // FIXME!!!
                                                          }
                                                else
                                                {
                                                  printf("UNHANDLED ATOM : %s\n",fourCC::tostringBE(wave.getFCC()));
                                                }
                                              }
                                            } // if left > 10
foundit: // HACK FIXME
                                            left=0;
                                    }
                                            break; // mp4a

                                }
                     }
                          break;
                     default:
                          ADM_assert(0);
                   }
                   son.skipBytes(left);
                }
       }
              break;
       default:
          printf("[STBL]Skipping atom %s\n",fourCC::tostringBE(son.getFCC()));
     }
     son.skipAtom();
  }
  uint8_t r=0;
  uint32_t nbo=0;
  switch(trackType)
  {
    case TRACK_VIDEO:
        {
          if(_tracks[0].index)
          {
              printf("Already got a video track\n");
              return 1;
          }
          r=indexify(&(_tracks[0]),trackScale,&info,0,&nbo);

          _videostream.dwLength= _mainaviheader.dwTotalFrames=_tracks[0].nbIndex;
          // update fps
          float f=_videostream.dwLength;
          if(_movieDuration) f=1000000.*f/_movieDuration;
              else  f=25000;
          _videostream.dwRate=(uint32_t)floor(f+0.49);
           _mainaviheader.dwMicroSecPerFrame=ADM_UsecFromFps1000(_videostream.dwRate);
          // if we have a sync atom ???
          if(info.nbSync)
          {
            // Mark keyframes
            for(int i=0;i<info.nbSync;i++)
            {
              uint32_t sync=info.Sync[i];
              if(sync) sync--;
              _tracks[0].index[sync].intra=AVI_KEY_FRAME;
            }
          }
          else
          { // All frames are kf
            for(int i=0;i<_tracks[0].nbIndex;i++)
            {
              _tracks[0].index[i].intra=AVI_KEY_FRAME;
            }
          }
          // Now do the CTTS thing
          if(info.Ctts)
          {
            updateCtts(&info);
          }


           VDEO.index[0].intra=AVI_KEY_FRAME;
        }
          break;
    case TRACK_AUDIO:
          printf("Cur audio track :%u\n",nbAudioTrack);
          if(info.SzIndentical ==1 && (ADIO.encoding==WAV_LPCM || ADIO.encoding==WAV_PCM ))
            {
              printf("Overriding size %lu -> %lu\n", info.SzIndentical,info.SzIndentical*2*ADIO.channels);
              info.SzIndentical=info.SzIndentical*2*ADIO.channels;
            }
            r=indexify(&(_tracks[1+nbAudioTrack]),trackScale,&info,1,&nbo);
            printf("Indexed audio, nb blocks:%u\n",nbo);
            if(r)
            {
                nbo=_tracks[1+nbAudioTrack].nbIndex;
                if(nbo)
                    _tracks[1+nbAudioTrack].nbIndex=nbo;
                else
                    _tracks[1+nbAudioTrack].nbIndex=info.nbSz;
                printf("Indexed audio, nb blocks:%u (final)\n",_tracks[1+nbAudioTrack].nbIndex);
                _tracks[1+nbAudioTrack].scale=trackScale;
                nbAudioTrack++;
            }

            break;
    case TRACK_OTHER:
        r=1;
        break;
  }
  return r;
}
Ejemplo n.º 9
0
	Wave AudioFormat_WAVE::decode(IReader& reader) const
	{
		RiffHeader riffHeader;

		if (!reader.read(riffHeader))
		{
			return Wave();
		}

		if (!detail::MemEqual(riffHeader.riff, detail::RIFF_SIGN) || !detail::MemEqual(riffHeader.type, detail::WAVE_SIGN))
		{
			return Wave();
		}

		ChunkHeader chunkHeader;

		for (;;)
		{
			if (!reader.read(chunkHeader))
			{
				return Wave();
			}

			if (detail::MemEqual(chunkHeader.chunkID, detail::FMT_CHUNK))
			{
				break;
			}
			else
			{
				reader.setPos(reader.getPos() + chunkHeader.chunkSize);
			}
		}

		FormatHeader formatHeader;

		if (!reader.read(formatHeader))
		{
			return Wave();
		}

		if (chunkHeader.chunkSize > sizeof(formatHeader))
		{
			reader.skip(chunkHeader.chunkSize - sizeof(formatHeader));
		}

		for (;;)
		{
			if (!reader.read(chunkHeader))
			{
				return Wave();
			}

			if (detail::MemEqual(chunkHeader.chunkID, detail::DATA_CHUNK))
			{
				break;
			}
			else
			{
				reader.setPos(reader.getPos() + chunkHeader.chunkSize);
			}
		}

		const uint32 size_bytes = chunkHeader.chunkSize;
		const size_t num_samples = size_bytes / (formatHeader.channels * (formatHeader.bitsWidth / 8));

		Wave wave(num_samples, Arg::samplingRate = formatHeader.samplerate);

		if (formatHeader.bitsWidth == 8 && formatHeader.channels == 1)
		{
			// PCM 8bit 1ch
			Array<uint8> samples(num_samples);

			reader.read(samples.data(), size_bytes);

			for (size_t i = 0; i < num_samples; ++i)
			{
				wave[i].set(samples[i] / 127.5f - 1.0f);
			}
		}
		else if (formatHeader.bitsWidth == 8 && formatHeader.channels == 2)
		{
			// PCM 8bit 2ch
			Array<WS8bit> samples(num_samples);

			reader.read(samples.data(), size_bytes);

			for (uint32 i = 0; i < num_samples; ++i)
			{
				wave[i].set(samples[i].left / 127.5f - 1.0f, samples[i].right / 127.5f - 1.0f);
			}
		}
		else if (formatHeader.bitsWidth == 16 && formatHeader.channels == 1)
		{
			// PCM 16bit 1ch
			Array<int16> samples(num_samples);

			reader.read(samples.data(), size_bytes);

			for (uint32 i = 0; i < num_samples; ++i)
			{
				wave[i].set(samples[i] / 32768.0f);
			}
		}
		else if (formatHeader.bitsWidth == 16 && formatHeader.channels == 2)
		{
			// PCM 16bit 2ch
			Array<WaveSampleS16> samples(num_samples);

			reader.read(samples.data(), size_bytes);

			for (uint32 i = 0; i < num_samples; ++i)
			{
				wave[i].set(samples[i].left / 32768.0f, samples[i].right / 32768.0f);
			}
		}
		else if (formatHeader.bitsWidth == 24 && formatHeader.channels == 1)
		{
			// PCM 24bit 1ch
			size_t samplesToRead = size_bytes / sizeof(WaveSmaple24S_Mono);

			const uint32 bufferSize = 16384;

			Array<WaveSmaple24S_Mono> buffer(bufferSize);

			WaveSample* pDst = &wave[0];

			for (;;)
			{
				WaveSmaple24S_Mono* pSrc = buffer.data();

				if (samplesToRead > bufferSize)
				{
					reader.read(pSrc, bufferSize * sizeof(WaveSmaple24S_Mono));

					for (uint32 i = 0; i < bufferSize; ++i)
					{
						const int32 s = ((pSrc->mono[2] << 24) | (pSrc->mono[1] << 16) | (pSrc->mono[0] << 8)) / 65536;
						pDst->set(s / 32768.0f);
						++pDst;
						++pSrc;
					}

					samplesToRead -= bufferSize;
				}
				else
				{
					reader.read(pSrc, samplesToRead * sizeof(WaveSmaple24S_Mono));

					for (uint32 i = 0; i < samplesToRead; ++i)
					{
						const int32 s = ((pSrc->mono[2] << 24) | (pSrc->mono[1] << 16) | (pSrc->mono[0] << 8)) / 65536;
						pDst->set(s / 32768.0f);
						++pDst;
						++pSrc;
					}

					break;
				}
			}
		}
		else if (formatHeader.bitsWidth == 24 && formatHeader.channels == 2)
		{
			// PCM 24bit 2ch
			size_t samplesToRead = size_bytes / sizeof(WaveSmaple24S_Stereo);

			const uint32 bufferSize = 16384;

			Array<WaveSmaple24S_Stereo> buffer(bufferSize);

			WaveSample* pDst = &wave[0];

			for (;;)
			{
				WaveSmaple24S_Stereo* pSrc = buffer.data();

				if (samplesToRead > bufferSize)
				{
					reader.read(pSrc, bufferSize * sizeof(WaveSmaple24S_Stereo));

					for (uint32 i = 0; i < bufferSize; ++i)
					{
						const int32 sL = ((pSrc->left[2] << 24) | (pSrc->left[1] << 16) | (pSrc->left[0] << 8)) / 65536;
						const int32 sR = ((pSrc->right[2] << 24) | (pSrc->right[1] << 16) | (pSrc->right[0] << 8)) / 65536;
						pDst->left = sL / 32768.0f;
						pDst->right = sR / 32768.0f;
						++pDst;
						++pSrc;
					}

					samplesToRead -= bufferSize;
				}
				else
				{
					reader.read(pSrc, samplesToRead * sizeof(WaveSmaple24S_Stereo));

					for (uint32 i = 0; i < samplesToRead; ++i)
					{
						const int32 sL = ((pSrc->left[2] << 24) | (pSrc->left[1] << 16) | (pSrc->left[0] << 8)) / 65536;
						const int32 sR = ((pSrc->right[2] << 24) | (pSrc->right[1] << 16) | (pSrc->right[0] << 8)) / 65536;
						pDst->left = sL / 32768.0f;
						pDst->right = sR / 32768.0f;
						++pDst;
						++pSrc;
					}

					break;
				}
			}
		}
		else if (formatHeader.formatID == 0x0003 && formatHeader.bitsWidth == 32 && formatHeader.channels == 1)
		{
			// PCM 32bit float 1ch
			Array<float> samples(num_samples);

			reader.read(samples.data(), size_bytes);

			for (uint32 i = 0; i < num_samples; ++i)
			{
				wave[i].set(samples[i]);
			}
		}
		else if (formatHeader.formatID == 0x0003 && formatHeader.bitsWidth == 32 && formatHeader.channels == 2)
		{
			// PCM 32bit float 2ch
			reader.read(wave.data(), size_bytes);
		}
		else
		{
			return Wave();
		}

		return wave;
	}
Ejemplo n.º 10
0
bool brr2wav(const std::string & brr_filename, uint16_t pitch)
{
	char path_c[PATH_MAX];

	off_t brr_filesize = path_getfilesize(brr_filename.c_str());
	if (brr_filesize == -1) {
		fprintf(stderr, "Error: %s: Unable to open\n", brr_filename.c_str());
		return false;
	}
	if (brr_filesize == 0) {
		fprintf(stderr, "Error: %s: File is empty\n", brr_filename.c_str());
		return false;
	}
	if (brr_filesize > 0x800000) {
		fprintf(stderr, "Error: %s: File too large\n", brr_filename.c_str());
		return false;
	}

	uint8_t * data = readfile(brr_filename);
	if (data == NULL) {
		return false;
	}

	uint8_t * brr = data;
	size_t brr_size = brr_filesize;

	int32_t loop_sample = 0;
	bool has_header = false;
	switch (brr_size % 9) {
	case 0:
		break;

	case 2: {
		uint16_t loop_offset = data[0] | (data[1] << 8);
		loop_sample = loop_offset / 9 * 16;

		if (loop_offset % 9 == 0) {
			printf("%s: addmusicM header detected, loop offset = $%04x (sample #%d).\n", brr_filename.c_str(), loop_offset, loop_sample);
			has_header = true;
		}
		else {
			fprintf(stderr, "%s: warning: illegal length, skip first %d bytes.\n", brr_filename.c_str(), (int)(brr_filesize % 9));
		}

		brr += brr_filesize % 9;
		brr_size -= brr_filesize % 9;
		break;
	}

	default:
		fprintf(stderr, "%s: warning: illegal length, skip first %d bytes.\n", brr_filename.c_str(), (int)(brr_filesize % 9));
		brr += brr_filesize % 9;
		brr_size -= brr_filesize % 9;
		break;
	}

	strcpy(path_c, brr_filename.c_str());
	path_basename(path_c);
	path_stripext(path_c);
	strcat(path_c, ".wav");
	std::string wav_filename(path_c);

	bool looped = false;
	WavWriter wave(SPCSampDir::decode_brr(brr, brr_size, &looped));
	wave.samplerate = pitch * 32000 / 0x1000;
	wave.bitwidth = 16;
	wave.channels = 1;
	if (has_header && looped) {
		wave.SetLoopSample(loop_sample);
	}

	if (!wave.WriteFile(wav_filename)) {
		fprintf(stderr, "Error: %s: %s\n", wav_filename.c_str(), wave.message().c_str());
		delete[] data;
		return false;
	}

	delete[] data;
	return true;
}