Subversion Repositories Kolibri OS

Rev

Rev 228 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. //
  2. //   This file is part of the AC97 mp3 player.
  3. //   (C) copyright Serge 2006
  4. //   email: infinity_sound@mail.ru
  5. //
  6. //   This program is free software; you can redistribute it and/or modify
  7. //   it under the terms of the GNU General Public License as published by
  8. //   the Free Software Foundation; either version 2 of the License, or
  9. //   (at your option) any later version.
  10. //
  11. //   This program is distributed in the hope that it will be useful,
  12. //   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. //   GNU General Public License for more details.
  15.  
  16. #include "kolibri.h"
  17. //#include "stdio.h"
  18. #include "string.h"
  19. #include "ac97wav.h"
  20. #include "mpg/mpg123.h"
  21.  
  22. #define MP3_ERROR_OUT_OF_BUFFER                 5
  23. int m_last_error;
  24.  
  25. void thread_proc();
  26. void touch(char *buf, int size);
  27. int mp3FindSync(byte* buf, int size, int* sync);
  28. int stream_read_raw(struct reader *rd,unsigned char *buf, int size);
  29.  
  30. char *fname;
  31.  
  32. //extern char __path;
  33.  
  34. /*****      for debug output only
  35. char formats[37][12] =
  36. { "PCM_ALL",
  37.   "PCM_2_16_48","PCM_1_16_48","PCM_2_16_44","PCM_1_16_44",
  38.   "PCM_2_16_32","PCM_1_16_32","PCM_2_16_24","PCM_1_16_24",
  39.   "PCM_2_16_22","PCM_1_16_22","PCM_2_16_16","PCM_1_16_16",
  40.   "PCM_2_16_12","PCM_1_16_12","PCM_2_16_11","PCM_1_16_11",
  41.   "PCM_2_16_8","PCM_1_16_8","PCM_2_8_48","PCM_1_8_48",
  42.   "PCM_2_8_44","PCM_1_8_44","PCM_2_8_32","PCM_1_8_32",
  43.   "PCM_2_8_24","PCM_1_8_24","PCM_2_8_22","PCM_1_8_22",
  44.   "PCM_2_8_16","PCM_1_8_16","PCM_2_8_12","PCM_1_8_12",
  45.   "PCM_2_8_11","PCM_1_8_11","PCM_2_8_8","PCM_1_8_8"
  46. };
  47. *******/
  48. //int freqs[9] = {44100,48000,32000,22050,24000,16000 ,11025 ,12000 ,8000};
  49.  
  50. struct reader rd;
  51. struct frame fr;
  52.  
  53. DWORD hDrv;
  54. DWORD hSound;
  55. DWORD hBuff;
  56. DWORD event[2];
  57.  
  58. CTRL_INFO info;
  59.  
  60. FILEINFO   fileinfo;
  61.  
  62. int m_vol;
  63. DWORD status;
  64. DWORD offset;
  65. DWORD first_sync;
  66.  
  67. unsigned char *testbuff;
  68. unsigned char *outbuf;
  69. unsigned char *inpbuf;
  70. unsigned char *outPtr;
  71.  
  72. int inpsize;
  73. int outsize;
  74. int outremain;
  75. int totalout;
  76. int done;
  77.  
  78. char srv_name[] = "INFINITY";
  79. char srv_intel[] = "SOUND";
  80. char header[] = "AC97 MP3 player";
  81. char buttons_text[]=" Play    Stop     <<      >>     Vol-    Vol+";
  82.  
  83. void (*snd_play)();
  84.  
  85. void draw_window()
  86. {
  87.    BeginDraw();
  88.  
  89.    DrawWindow(100,100,299,72,0x404040,3,0,0,0);
  90.  
  91.    make_button(7,24,45,13, 0x10|BT_NORMAL,0x808080);
  92.    make_button(56,24,45,13, 0x11|BT_NORMAL,0x808080);
  93.    make_button(104,24,45,13, 0x12|BT_NORMAL,0x808080);
  94.    make_button(152,24,45,13, 0x13|BT_NORMAL,0x808080);
  95.    make_button(200,24,45,13, 0x14|BT_NORMAL,0x808080);
  96.    make_button(248,24,45,13, 0x15|BT_NORMAL,0x808080);
  97.  
  98.    make_button(7,41,286,11, 0x30|BT_HIDE|BT_NOFRAME,0x404040);
  99.    draw_bar(7,41,286,11,0x404040);
  100.  
  101.    draw_bar(7,55,286,11,0x404040);
  102.    write_text(12,58,0x004000|FONT0, fname, strlen(fname));
  103.    write_text(11,57,0x00FF20|FONT0, fname, strlen(fname));
  104.  
  105.    write_text(8,8,0xFFFFFF|FONT0, header, strlen(header));
  106.    write_text(12,28,0x404040|FONT0,buttons_text,strlen(buttons_text));
  107.    write_text(11,27,0xA0FFA0|FONT0,buttons_text,strlen(buttons_text));
  108.  
  109.    EndDraw();
  110. };
  111.  
  112. void draw_progress_bar()
  113. {  DWORD x;
  114.    x = 286.0f * (float)(rd.filepos-rd.strremain)/(float)fileinfo.size;
  115.    if(x==0) return;
  116.    draw_bar(7,41,x,11,0xA0A0A0);
  117.    draw_bar(x+7,41,286-x,11,0x404040);
  118. };
  119.  
  120. void debug_out_str(char* str)
  121. {
  122.   while (*str != 0)
  123.   {
  124.     debug_out(*str);
  125.     str++;
  126.   }
  127. }
  128.  
  129. int main(int argc, char *argv[])      //int argc, char *argv[])
  130. { DWORD fmt;
  131.    char *thread_stack;
  132.    DWORD r_bytes;
  133.    int retval;
  134.  
  135.    fname = argv[1];
  136.    //debug_out_str(fname);
  137.    
  138.    InitHeap(1024*1024);
  139.    if(get_fileinfo(fname, &fileinfo)==FILE_NOT_FOUND)
  140.       return 0;
  141.  
  142.    if((hDrv=GetService(srv_intel))==0)
  143.       return 0;
  144.  
  145.    if ((hSound=GetService(srv_name))==0)
  146.      return 0;
  147.  
  148.    GetDevInfo(hDrv, &info);
  149.  
  150.    m_vol = GetMasterVol(hDrv,&m_vol);
  151.    if (m_vol > 85)
  152.    { m_vol = 85;
  153.       SetMasterVol(hDrv,m_vol);
  154.    };
  155.  
  156.    testbuff = UserAlloc(4096);
  157.    get_fileinfo(fname, &fileinfo);
  158.    offset = 0;
  159.    retval=read_file (fname,testbuff,0,2048,&r_bytes);
  160.    if (retval) return 0;
  161.  
  162.    inpbuf = UserAlloc(0x10000);
  163.    touch(inpbuf, 0x10000);
  164.    
  165.    create_reader(&rd, inpbuf, 0x10000);
  166.    init_reader(&rd,fname);
  167.  
  168.    fmt = test_wav((WAVEHEADER*)testbuff);
  169.    if (fmt != 0)
  170.    {
  171.      snd_play = &play_wave;
  172.      set_reader(&rd, 44);
  173.      outbuf = UserAlloc(32*1024);
  174.      touch(outbuf, 32768);
  175.    }  
  176.    else  
  177.    {   fmt = test_mp3(testbuff);
  178.         if(fmt ==0) return 0;
  179.         snd_play = &play_mp3;
  180.        
  181.         outremain = 0x40000 ;
  182.         outbuf = UserAlloc(outremain);
  183.         touch(outbuf, outremain);
  184.         make_decode_tables(32767);
  185.         init_layer2();
  186.         init_layer3(32);
  187.         fr.single = -1;
  188.    };
  189.  
  190.    status = ST_PLAY;
  191.    
  192.    hBuff = CreateBuffer(hSound,fmt);
  193.    if (hBuff == 0) return 0;
  194.    thread_stack = UserAlloc(4096);
  195.    thread_stack+=4092;
  196.  
  197.    CreateThread(thread_proc, thread_stack);
  198.  
  199.    while(1)
  200.    {  delay(10);
  201.       switch(status)
  202.       {  case ST_PLAY:
  203.            snd_play();
  204.            continue;
  205.  
  206.          case ST_STOP:
  207.            StopBuffer(hSound, hBuff);
  208.            status = ST_DONE;
  209.            continue;
  210.  
  211.          case ST_EXIT:
  212.            StopBuffer(hSound, hBuff);
  213.            DestroyBuffer(hSound, hBuff);
  214.            return 0;
  215.       };
  216.    };
  217.    return 0;
  218. };
  219.  
  220. void touch(char *buf, int size)
  221. { int i;
  222.    char a;
  223.     for ( i = 0;i < size; i+=4096)
  224.       a = buf[i];
  225. };
  226.  
  227. DWORD test_mp3(char *buf)
  228. {  unsigned long hdr;
  229.     WAVEHEADER whdr;
  230.      
  231.     while (1)
  232.     {  if(rd.filepos > 102400)
  233.           return 0;
  234.         if(!rd.head_read(&rd,&hdr))
  235.                         return 0;
  236.         if(!decode_header(&fr,hdr))
  237.         {  rd.strpos-=3;
  238.             rd.stream-=3;
  239.             rd.strremain+=3;
  240.             continue;
  241.         };
  242.         break;
  243.           };
  244.          
  245.     first_sync = rd.filepos-rd.strremain-4;
  246.          
  247.     whdr.riff_id = 0x46464952;
  248.     whdr.riff_format = 0x45564157;
  249.     whdr.wFormatTag = 0x01;
  250.     whdr.nSamplesPerSec = freqs[fr.sampling_frequency];
  251.     whdr.nChannels = 2; //mpginfo.channels;
  252.     whdr.wBitsPerSample = 16;
  253.    
  254.     return test_wav(&whdr);
  255. };
  256.  
  257. void wave_out(char* buff)
  258. { DWORD ev[6];
  259.  
  260.    GetNotify(&ev[0]);
  261.    SetBuffer(hSound,hBuff,buff,ev[1],0x8000);
  262. }
  263.  
  264. void play_mp3()
  265. {  char *outPtr;
  266.     int totalout;
  267.     int outcount;
  268.  
  269.  //   memset(&fr,0,sizeof(fr));
  270.     fr.down_sample_sblimit = 32;
  271.     fr.single = -1;
  272.     reset_mpg();
  273.  
  274.     outPtr = outbuf;
  275.     totalout=0;
  276.     done = 0;
  277.     outremain=0x40000;
  278.  
  279.     memset(outbuf,0,0x40000);
  280.  
  281.     set_reader(&rd, 0);    //;first_sync);
  282.     SetBuffer(hSound,hBuff,outbuf,0,0x8000);
  283.     SetBuffer(hSound,hBuff,outbuf,0x8000,0x8000);
  284.     PlayBuffer(hSound, hBuff);
  285.  
  286.     while(1)
  287.     { if(status!=ST_PLAY)
  288.              break;
  289.  
  290.      for(;;)
  291.      {   outcount = 0;                          
  292.           if( !read_frame(&rd, &fr))
  293.           {  done = 1;
  294.               break;
  295.           };
  296.           fr.do_layer(&fr, outPtr,&outcount);
  297.           outPtr+= outcount;
  298.           totalout+=outcount;
  299.           outremain-=outcount;
  300.           if(outremain < outcount*2)
  301.             break;  
  302.     };
  303.  
  304.     if(done)
  305.     { if(totalout < 32768)
  306.             {  memset(outPtr,0,32768-totalout);
  307.                 totalout = 32768;
  308.       };
  309.     };
  310.     if(totalout < 32768)
  311.       continue;
  312. /*      
  313.      _asm
  314.   {  push edx
  315.       push eax
  316.       mov eax, 0xFF
  317.       mov edx, 0x400
  318.       out dx, al
  319.       pop eax
  320.       pop edx  
  321.   };  
  322. */      
  323.     outPtr = outbuf;      
  324.     while (totalout > 32768)
  325.     { wave_out(outPtr);
  326.              totalout-=0x8000;
  327.              outPtr+=0x8000;
  328.              outremain+=0x8000;
  329.     };
  330.     if(done) break;  
  331.     memmove(outbuf,outPtr, totalout);
  332.     outPtr = outbuf+totalout;
  333.    }
  334.  
  335.     if(status != ST_EXIT)
  336.     status =  ST_STOP;
  337. };
  338.  
  339. void play_wave()
  340. { DWORD ev[6];
  341.    int retval;
  342.    int remain;
  343.    int i;
  344.  
  345. //   offset = 44;
  346.  
  347. //   read_file (fname,outbuf,offset,32*1024,0);
  348. //   offset+=32*1024;
  349.    set_reader(&rd,44);
  350.    stream_read_raw(&rd,outbuf,32768);
  351.    SetBuffer(hSound,hBuff,outbuf,0,0x8000);
  352.    stream_read_raw(&rd,outbuf,32768);
  353.    SetBuffer(hSound,hBuff,outbuf,0x8000,0x8000);
  354.  
  355.    PlayBuffer(hSound, hBuff);
  356.  
  357.    retval = 0;
  358.    while(1)
  359.    {
  360.       if(status!=ST_PLAY)
  361.         break;
  362.  
  363.       if( !stream_read_raw(&rd,outbuf,32768))
  364.       {  done = 1;
  365.           break;
  366.       };
  367.       wave_out(outbuf);
  368.    };
  369.  
  370.    if(status != ST_EXIT)
  371.     status =  ST_STOP;
  372. };
  373.  
  374. void snd_stop()
  375. {
  376.   StopBuffer(hSound, hBuff);
  377. };
  378.  
  379. void thread_proc()
  380. {  int evnt;
  381.    int pos;
  382.    int key;
  383.  
  384.   _asm { fninit };
  385.  
  386.    
  387.   draw_window();
  388.  
  389.   while(1)
  390.   {  if(status==ST_PLAY)
  391.       {  draw_progress_bar();
  392.           evnt = wait_for_event(80);
  393.        //   debug_out_str("BIG ERROR...\x0D\x0A\x00");          
  394.       }
  395.      else
  396.         evnt = wait_for_event_infinite();
  397.  
  398.     switch(evnt)
  399.     {
  400.       case EV_REDRAW:
  401.         draw_window();
  402.         break;
  403.  
  404.       case EV_KEY:
  405.         key = get_key();
  406.         if(key==27)
  407.         {   status = ST_EXIT;
  408.             exit();
  409.         };
  410.         if((key==45)||key==54)
  411.         { if(m_vol > 0)
  412.           { m_vol--;
  413.             SetMasterVol(hDrv,m_vol);
  414.           };
  415.           break;
  416.         };
  417.         if((key==61)||key==56)
  418.         { if(m_vol < 90)
  419.           { m_vol++;
  420.             SetMasterVol(hDrv,m_vol);
  421.           };
  422.         };
  423.         break;
  424.  
  425.       case EV_BUTTON:
  426.         switch(get_button_id())
  427.         {  case 1:
  428.              status = ST_EXIT;
  429.              exit();
  430.              break;
  431.              
  432.            case 0x10:
  433.              status = ST_PLAY;
  434.              continue;
  435.  
  436.            case 0x11:
  437.              status = ST_STOP;
  438.              break;
  439. //           case 0x12:
  440. //           case 0x13:
  441.            case 0x14:
  442.              if(m_vol > 0)
  443.              { m_vol--;
  444.                SetMasterVol(hDrv,m_vol);
  445.              };
  446.              break;
  447.  
  448.            case 0x15:
  449.              if(m_vol < 90)
  450.              { m_vol++;
  451.                SetMasterVol(hDrv,m_vol);
  452.              };
  453.              break;
  454.  
  455.            case 0x30:
  456.             if(status==ST_DONE)
  457.               break;
  458. //            if(snd_play == play_mp3)
  459. //              continue;  
  460.             pos = (GetMousePos(REL_WINDOW)>>16)-7;
  461.             offset = ((fileinfo.size-44)/286*pos+44)&0xFFFFFFFC;
  462.             set_reader(&rd, offset);
  463.             draw_progress_bar();
  464.             break;
  465.         };
  466.     };
  467.   };
  468. };
  469.  
  470. DWORD test_wav(WAVEHEADER *hdr)
  471. {
  472.   if(hdr->riff_id != 0x46464952)
  473.     return 0;
  474.  
  475.   if(hdr->riff_format != 0x45564157)
  476.     return 0;
  477.  
  478.   if (hdr->wFormatTag != 0x01)
  479.     return 0;
  480.  
  481.   switch(hdr->nSamplesPerSec)
  482.   { case 48000:
  483.       switch (hdr->nChannels)
  484.       {  case 1:
  485.            if(hdr->wBitsPerSample == 16)
  486.              return PCM_1_16_48;
  487.            else
  488.              return PCM_1_8_48;
  489.  
  490.          case 2:
  491.            if(hdr->wBitsPerSample == 16)
  492.              return PCM_2_16_48;
  493.            else
  494.              return PCM_2_8_48;
  495.       };
  496.  
  497.     case 44100:
  498.       switch (hdr->nChannels)
  499.       {  case 1:
  500.            if(hdr->wBitsPerSample == 16)
  501.              return PCM_1_16_44;
  502.            else
  503.              return PCM_1_8_44;
  504.  
  505.          case 2:
  506.            if(hdr->wBitsPerSample == 16)
  507.              return PCM_2_16_44;
  508.            else
  509.              return PCM_2_8_44;
  510.       };
  511.  
  512.     case 32000:
  513.       switch (hdr->nChannels)
  514.       {  case 1:
  515.            if(hdr->wBitsPerSample == 16)
  516.              return PCM_1_16_32;
  517.            else
  518.              return PCM_1_8_32;
  519.  
  520.          case 2:
  521.            if(hdr->wBitsPerSample == 16)
  522.              return PCM_2_16_32;
  523.            else
  524.              return PCM_2_8_32;
  525.       };
  526.  
  527.     case 24000:
  528.       switch (hdr->nChannels)
  529.       {  case 1:
  530.            if(hdr->wBitsPerSample == 16)
  531.              return PCM_1_16_24;
  532.            else
  533.              return PCM_1_8_24;
  534.  
  535.          case 2:
  536.            if(hdr->wBitsPerSample == 16)
  537.              return PCM_2_16_24;
  538.            else
  539.              return PCM_2_8_24;
  540.       };
  541.  
  542.     case 22050:
  543.       switch (hdr->nChannels)
  544.       {  case 1:
  545.            if(hdr->wBitsPerSample == 16)
  546.              return PCM_1_16_22;
  547.            else
  548.              return PCM_1_8_22;
  549.  
  550.          case 2:
  551.            if(hdr->wBitsPerSample == 16)
  552.              return PCM_2_16_22;
  553.            else
  554.              return PCM_2_8_22;
  555.       };
  556.  
  557.     case 16000:
  558.       switch (hdr->nChannels)
  559.       {  case 1:
  560.            if(hdr->wBitsPerSample == 16)
  561.              return PCM_1_16_16;
  562.            else
  563.              return PCM_1_8_16;
  564.  
  565.          case 2:
  566.            if(hdr->wBitsPerSample == 16)
  567.              return PCM_2_16_16;
  568.            else
  569.              return PCM_2_8_16;
  570.       };
  571.  
  572.     case 12000:
  573.       switch (hdr->nChannels)
  574.       {  case 1:
  575.            if(hdr->wBitsPerSample == 16)
  576.              return PCM_1_16_12;
  577.            else
  578.              return PCM_1_8_12;
  579.  
  580.          case 2:
  581.            if(hdr->wBitsPerSample == 16)
  582.              return PCM_2_16_12;
  583.            else
  584.              return PCM_2_8_12;
  585.       };
  586.  
  587.     case 11025:
  588.       switch (hdr->nChannels)
  589.       {  case 1:
  590.            if(hdr->wBitsPerSample == 16)
  591.              return PCM_1_16_11;
  592.            else
  593.              return PCM_1_8_11;
  594.  
  595.          case 2:
  596.            if(hdr->wBitsPerSample == 16)
  597.              return PCM_2_16_11;
  598.            else
  599.              return PCM_2_8_11;
  600.       };
  601.  
  602.     case 8000:
  603.       switch (hdr->nChannels)
  604.       {  case 1:
  605.            if(hdr->wBitsPerSample == 16)
  606.              return PCM_1_16_8;
  607.            else
  608.              return PCM_1_8_8;
  609.  
  610.          case 2:
  611.            if(hdr->wBitsPerSample == 16)
  612.              return PCM_2_16_8;
  613.            else
  614.              return PCM_2_8_8;
  615.       };
  616.       default:
  617.         return 0;
  618.   };
  619. };
  620.  
  621. void delay (int val)
  622. {
  623.   _asm
  624.  {   mov   eax,5
  625.       mov   ebx, [val]
  626.       int   0x40
  627.   };  
  628. }
  629.  
  630. int wait_for_event(int time)
  631. { int retval;
  632.   _asm
  633.  {  mov  eax,23
  634.      mov  ebx,[time]
  635.      int  0x40
  636.      mov [retval], eax
  637.  };
  638.  return retval;
  639. };
  640.  
  641. int wait_for_event_infinite()
  642. {   void *a;
  643.      int retval;
  644.   _asm
  645.   {  mov  eax,10
  646.       int  0x40
  647.       mov [retval], eax
  648.   };
  649.   return retval;
  650. };
  651.  
  652. void BeginDraw()
  653. {_asm
  654.  { mov   eax,12
  655.     mov   ebx, 1
  656.     int   0x40
  657.   };  
  658. };
  659.  
  660. void EndDraw()
  661. { _asm
  662.  { mov   eax,12
  663.     mov   ebx, 2
  664.     int   0x40
  665.   };  
  666. };
  667.  
  668. ///*********
  669. void *memmove ( void * dst, void * src, int count)
  670. { void *ret;
  671.   ret = dst;
  672.  
  673.   if (dst <= src || (char *)dst >= ((char *)src + count))
  674.   {
  675.       while (count--)
  676.       { *(char *)dst = *(char *)src;
  677.           dst = (char *)dst + 1;
  678.           src = (char *)src + 1;
  679.       }
  680.    }
  681.    else
  682.     {
  683.         dst = (char *)dst + count - 1;
  684.         src = (char *)src + count - 1;
  685.          while (count--)
  686.           {  *(char *)dst = *(char *)src;
  687.               dst = (char *)dst - 1;
  688.               src = (char *)src - 1;
  689.           }
  690.     }
  691.     return ret;
  692. };
  693. //**********/
  694.  
  695. void * __cdecl mem_cpy(void * dst,const void * src,size_t count)
  696. {    void * ret = dst;
  697.       while (count--)
  698.       {  *(char *)dst = *(char *)src;
  699.           dst = (char *)dst + 1;
  700.           src = (char *)src + 1;
  701.       };
  702.       return(ret);
  703. }
  704.  
  705. //   debug_out_str(formats[fmt]);
  706. //   debug_out_str("\x0D\x0A\x00");
  707.  
  708. //   debug_out_str("pci cmd: ");
  709. //   debug_out_hex(info.pci_cmd);
  710. //   debug_out_str("\x0D\x0A\x00");
  711.  
  712. //   debug_out_str("irq line: ");
  713. //   debug_out_hex(info.irq);
  714. //   debug_out_str("\x0D\x0A\x00");
  715.  
  716. //   debug_out_str("global control: ");
  717. //   debug_out_hex(info.glob_cntrl);
  718. //   debug_out_str("\x0D\x0A\x00");
  719.  
  720. //   debug_out_str("global status:  ");
  721. //   debug_out_hex(info.glob_sta);
  722. //   debug_out_str("\x0D\x0A\x00");
  723.  
  724.  
  725.   // call _print_volume
  726.  
  727. //   debug_out_hex(whdr.nChannels);
  728. //   debug_out_str("\x0D\x0A\x00");
  729. //   debug_out_hex(whdr.nSamplesPerSec);
  730. //   debug_out_str("\x0D\x0A\x00");
  731.  
  732. //   debug_out_hex(fmt);
  733. //   debug_out_str("\x0D\x0A\x00");
  734.  
  735.  
  736.  
  737.