Subversion Repositories Kolibri OS

Rev

Rev 3248 | Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. #include <stdint.h>
  3. #include <libavcodec/avcodec.h>
  4. #include <libavformat/avformat.h>
  5. #include <libswscale/swscale.h>
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "../winlib/winlib.h"
  10. #include "sound.h"
  11. #include "fplay.h"
  12.  
  13.  
  14. astream_t astream;
  15.  
  16. extern uint8_t *decoder_buffer;
  17. int resampler_size;
  18. volatile int sound_level_0;
  19. volatile int sound_level_1;
  20.  
  21. volatile enum player_state player_state;
  22. volatile enum player_state decoder_state;
  23. volatile enum player_state sound_state;
  24.  
  25. extern volatile uint32_t driver_lock;
  26.  
  27. static SNDBUF hBuff;
  28.  
  29. static int snd_format;
  30. int sample_rate;
  31.  
  32. static uint32_t samples_written = 0;
  33. double audio_base = -1.0;
  34.  
  35. double get_audio_base();
  36.  
  37. int init_audio(int format)
  38. {
  39.     int    err;
  40.     int    version =-1;
  41.     char  *errstr;
  42.  
  43.     mutex_lock(&driver_lock);
  44.  
  45.     if((err = InitSound(&version)) !=0 )
  46.     {
  47.         mutex_unlock(&driver_lock);
  48.         errstr = "Sound service not installed\n\r";
  49.         goto exit_whith_error;
  50.     };
  51.  
  52.     mutex_unlock(&driver_lock);
  53.  
  54. //    printf("sound version 0x%x\n", version);
  55.  
  56.     if( (SOUND_VERSION>(version&0xFFFF)) ||
  57.         (SOUND_VERSION<(version >> 16)))
  58.     {
  59.         errstr = "Sound service version mismatch\n\r";
  60.         goto exit_whith_error;
  61.     }
  62.  
  63.     snd_format = format;
  64.  
  65.     create_thread(audio_thread, 0, 163840);
  66.  
  67.     return 1;
  68.  
  69. exit_whith_error:
  70.  
  71.     printf(errstr);
  72.     return 0;
  73. };
  74.  
  75. void set_audio_volume(int left, int right)
  76. {
  77.     SetVolume(hBuff, left, right);
  78. };
  79.  
  80. static uint64_t samples_lost;
  81. static double  audio_delta;
  82. static double  last_time_stamp;
  83.  
  84.  
  85. double get_master_clock(void)
  86. {
  87.     double tstamp;
  88.  
  89.     GetTimeStamp(hBuff, &tstamp);
  90.     return tstamp - audio_delta;
  91. };
  92.  
  93. int decode_audio(AVCodecContext  *ctx, queue_t *qa)
  94. {
  95.     AVPacket   pkt;
  96.     AVPacket    pkt_tmp;
  97.  
  98.     int         len;
  99.     int         data_size=0;
  100.  
  101.     if( astream.count > AVCODEC_MAX_AUDIO_FRAME_SIZE*7)
  102.         return -1;
  103.  
  104.     if( get_packet(qa, &pkt) == 0 )
  105.         return 0;
  106.  
  107.  //          __asm__("int3");
  108.  
  109.     pkt_tmp = pkt;
  110.  
  111.     while(pkt_tmp.size > 0)
  112.     {
  113.         data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
  114.  
  115.         len = avcodec_decode_audio3(ctx,(int16_t*)decoder_buffer,
  116.                                    &data_size, &pkt_tmp);
  117.  
  118.         if(len >= 0)
  119.         {
  120. //            if(audio_base == -1.0)
  121. //            {
  122. //                if (pkt.pts != AV_NOPTS_VALUE)
  123. //                    audio_base = get_audio_base() * pkt.pts;
  124. //                printf("audio base %f\n", audio_base);
  125. //            };
  126.  
  127.             pkt_tmp.data += len;
  128.             pkt_tmp.size -= len;
  129.  
  130.             mutex_lock(&astream.lock);
  131.             memcpy(astream.buffer+astream.count, decoder_buffer, data_size);
  132.             astream.count += data_size;
  133.             mutex_unlock(&astream.lock);
  134.        }
  135.        else pkt_tmp.size = 0;
  136.     }
  137.     av_free_packet(&pkt);
  138.     return 1;
  139. };
  140.  
  141.  
  142. static void sync_audio(SNDBUF hbuff, int buffsize)
  143. {
  144.     SND_EVENT   evnt;
  145.     uint32_t    offset;
  146.     double      time_stamp;
  147.  
  148. #ifdef BLACK_MAGIC_SOUND
  149.  
  150.     while( player_state != CLOSED)
  151.     {
  152.         GetNotify(&evnt);
  153.  
  154.         if(evnt.code != 0xFF000001)
  155.         {
  156.             printf("invalid event code %d\n\r", evnt.code);
  157.             continue;
  158.         }
  159.  
  160.         if(evnt.stream != hbuff)
  161.         {
  162.             printf("invalid stream %x hBuff= %x\n\r",
  163.                     evnt.stream, hbuff);
  164.             continue;
  165.         }
  166.  
  167.         GetTimeStamp(hbuff, &time_stamp);
  168.         audio_delta = time_stamp - last_time_stamp;
  169.  
  170.         offset = evnt.offset;
  171.  
  172.         mutex_lock(&astream.lock);
  173.         {
  174.             if(astream.count < buffsize)
  175.             {
  176.                 memset(astream.buffer+astream.count,
  177.                        0, buffsize-astream.count);
  178.                 astream.count = buffsize;
  179.             };
  180.  
  181.             SetBuffer(hbuff, astream.buffer, offset, buffsize);
  182.             samples_written+= buffsize/4;
  183.  
  184.             astream.count -= buffsize;
  185.             if(astream.count)
  186.                 memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
  187.             mutex_unlock(&astream.lock);
  188.         };
  189.         break;
  190.     };
  191. #endif
  192.  
  193. };
  194.  
  195. int audio_thread(void *param)
  196. {
  197.     SND_EVENT evnt;
  198.  
  199.     int       buffsize;
  200.     int      samples;
  201.     int       err;
  202.     char     *errstr;
  203.     int       active;
  204.  
  205.  
  206.     if((err = CreateBuffer(snd_format|PCM_RING,0, &hBuff)) != 0)
  207.     {
  208.         errstr = "Cannot create sound buffer\n\r";
  209.         goto exit_whith_error;
  210.     };
  211.  
  212.     SetVolume(hBuff,-1875,-1875);
  213.  
  214.     if((err = GetBufferSize(hBuff, &buffsize)) != 0)
  215.     {
  216.         errstr = "Cannot get buffer size\n\r";
  217.         goto exit_whith_error;
  218.     };
  219.  
  220.     resampler_size = buffsize = buffsize/2;
  221.  
  222.     samples = buffsize/4;
  223.  
  224.     while( player_state != CLOSED)
  225.     {
  226.         uint32_t  offset;
  227.         double    event_stamp, wait_stamp;
  228.         int       too_late = 0;
  229.  
  230.         switch(sound_state)
  231.         {
  232.             case PREPARE:
  233.  
  234.                 mutex_lock(&astream.lock);
  235.                     if(astream.count < buffsize*2)
  236.                     {
  237.                         memset(astream.buffer+astream.count,
  238.                                0, buffsize*2-astream.count);
  239.                         astream.count = buffsize*2;
  240.                     };
  241.  
  242.                     SetBuffer(hBuff, astream.buffer, 0, buffsize*2);
  243.                     astream.count -= buffsize*2;
  244.                     if(astream.count)
  245.                         memcpy(astream.buffer, astream.buffer+buffsize*2, astream.count);
  246.                 mutex_unlock(&astream.lock);
  247.  
  248.                 SetTimeBase(hBuff, audio_base);
  249.  
  250.             case PAUSE_2_PLAY:
  251.                 GetTimeStamp(hBuff, &last_time_stamp);
  252. //                printf("last audio time stamp %f\n", last_time_stamp);
  253.  
  254.                 if((err = PlayBuffer(hBuff, 0)) !=0 )
  255.                 {
  256.                     errstr = "Cannot play buffer\n\r";
  257.                     goto exit_whith_error;
  258.                 };
  259.                 active = 1;
  260.                 sync_audio(hBuff, buffsize);
  261.                 sound_state = PLAY;
  262. //                printf("render: set audio latency to %f\n", audio_delta);
  263.  
  264.                 /* breaktrough */
  265.  
  266.             case PLAY:
  267.                 GetNotify(&evnt);
  268.  
  269.                 if(evnt.code != 0xFF000001)
  270.                 {
  271.                     printf("invalid event code %d\n\r", evnt.code);
  272.                     continue;
  273.                 }
  274.  
  275.                 if(evnt.stream != hBuff)
  276.                 {
  277.                     printf("invalid stream %x hBuff= %x\n\r",
  278.                             evnt.stream, hBuff);
  279.                     continue;
  280.                 };
  281.  
  282.                 offset = evnt.offset;
  283.  
  284.                 mutex_lock(&astream.lock);
  285.                 if(astream.count < buffsize)
  286.                 {
  287.                     memset(astream.buffer+astream.count,
  288.                            0, buffsize-astream.count);
  289.                     astream.count = buffsize;
  290.                 };
  291.  
  292.                 SetBuffer(hBuff, astream.buffer, offset, buffsize);
  293.  
  294.                 {
  295.                     double  val = 0;
  296.                     int16_t *src = (int16_t*)astream.buffer;
  297.                     int samples = buffsize/2;
  298.                     int i;
  299.  
  300.                     for(i = 0, val = 0; i < samples/2; i++, src++)
  301.                         if(val < abs(*src))
  302.                             val= abs(*src); // * *src;
  303.  
  304.                     sound_level_0 = val; //sqrt(val / (samples/2));
  305.  
  306.                     for(i = 0, val = 0; i < samples/2; i++, src++)
  307.                         if(val < abs(*src))
  308.                             val= abs(*src); // * *src;
  309.  
  310.                     sound_level_1 = val; //sqrt(val / (samples/2));
  311.  
  312.  //                   printf("%d\n", sound_level);
  313.                 };
  314.  
  315.                 samples_written+= buffsize/4;
  316.  
  317.                 astream.count -= buffsize;
  318.                 if(astream.count)
  319.                     memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
  320.                 mutex_unlock(&astream.lock);
  321.                 break;
  322.  
  323.             case PLAY_2_STOP:
  324.                 if( active )
  325.                 {
  326.                     ResetBuffer(hBuff, SND_RESET_ALL);
  327.                     audio_base = -1.0;
  328.                     active = 0;
  329.                 }
  330.                 sound_state = STOP;
  331.                 break;
  332.  
  333.             case PLAY_2_PAUSE:
  334.                 if( active )
  335.                 {
  336.                     StopBuffer(hBuff);
  337.                 };
  338.                 sound_state = PAUSE;
  339.  
  340.             case PAUSE:
  341.             case STOP:
  342.                 delay(1);
  343.         };
  344.     }
  345.  
  346.     StopBuffer(hBuff);
  347.     DestroyBuffer(hBuff);
  348.  
  349.     return 0;
  350.  
  351. exit_whith_error:
  352.  
  353.     printf(errstr);
  354.     return -1;
  355.  
  356. };
  357.  
  358.