Subversion Repositories Kolibri OS

Rev

Rev 6106 | Rev 6144 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1.  
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <libavcodec/avcodec.h>
  6. #include <libavformat/avformat.h>
  7. #include <libswresample/swresample.h>
  8. #include <kos32sys.h>
  9.  
  10. #include "winlib/winlib.h"
  11. #include "sound.h"
  12. #include "fplay.h"
  13.  
  14.  
  15. astream_t astream;
  16.  
  17. extern uint8_t *decoder_buffer;
  18. int resampler_size;
  19. volatile int sound_level_0;
  20. volatile int sound_level_1;
  21.  
  22. volatile enum player_state player_state;
  23. volatile enum player_state decoder_state;
  24. volatile enum player_state sound_state;
  25.  
  26. static SNDBUF hBuff;
  27.  
  28. static int snd_format;
  29. int sample_rate;
  30.  
  31. static uint32_t samples_written = 0;
  32. double audio_base = -1.0;
  33.  
  34. double get_audio_base();
  35.  
  36. int init_audio(int format)
  37. {
  38.     int    err;
  39.     int    version =-1;
  40.     char  *errstr;
  41.  
  42.     if((err = InitSound(&version)) !=0 )
  43.     {
  44.         errstr = "Sound service not installed\n\r";
  45.         goto exit_whith_error;
  46.     };
  47.  
  48.     if( (SOUND_VERSION>(version&0xFFFF)) ||
  49.         (SOUND_VERSION<(version >> 16)))
  50.     {
  51.         errstr = "Sound service version mismatch\n\r";
  52.         goto exit_whith_error;
  53.     }
  54.  
  55.     snd_format = format;
  56.  
  57.     create_thread(audio_thread, 0, 163840);
  58.  
  59.     return 1;
  60.  
  61. exit_whith_error:
  62.  
  63.     printf(errstr);
  64.     return 0;
  65. };
  66.  
  67. void set_audio_volume(int left, int right)
  68. {
  69.     SetVolume(hBuff, left, right);
  70. };
  71.  
  72. static uint64_t samples_lost;
  73. static double  audio_delta;
  74. static double  last_time_stamp;
  75.  
  76.  
  77. double get_master_clock(void)
  78. {
  79.     double tstamp;
  80.  
  81.     GetTimeStamp(hBuff, &tstamp);
  82.     return tstamp - audio_delta;
  83. };
  84.  
  85. int decode_audio(AVCodecContext  *ctx, queue_t *qa)
  86. {
  87.     static struct SwrContext *swr_ctx;
  88.     static int64_t src_layout;
  89.     static int src_freq;
  90.     static int src_channels;
  91.     static enum AVSampleFormat src_fmt = -1;
  92.     static AVFrame *aFrame;
  93.  
  94.     AVPacket   pkt;
  95.     AVPacket    pkt_tmp;
  96.     int64_t dec_channel_layout;
  97.     int len, len2;
  98.     int got_frame;
  99.     int data_size;
  100.  
  101.     if( astream.count > 192000*2)
  102.         return -1;
  103.  
  104.     if( get_packet(qa, &pkt) == 0 )
  105.         return 0;
  106.  
  107.     if (!aFrame)
  108.     {
  109.         if (!(aFrame = av_frame_alloc()))
  110.             return -1;
  111.     } else
  112.         avcodec_get_frame_defaults(aFrame);
  113.  
  114.     pkt_tmp = pkt;
  115.  
  116.     while(pkt_tmp.size > 0)
  117.     {
  118.         data_size = 192000;
  119.  
  120.         got_frame = 0;
  121.         len = avcodec_decode_audio4(ctx, aFrame, &got_frame, &pkt_tmp);
  122.  
  123.         if(len >= 0 && got_frame)
  124.         {
  125.             char *samples;
  126.             int ch, plane_size;
  127.             int planar    = av_sample_fmt_is_planar(ctx->sample_fmt);
  128.             int data_size = av_samples_get_buffer_size(&plane_size, ctx->channels,
  129.                                                    aFrame->nb_samples,
  130.                                                    ctx->sample_fmt, 1);
  131.  
  132. //            if(audio_base == -1.0)
  133. //            {
  134. //                if (pkt.pts != AV_NOPTS_VALUE)
  135. //                    audio_base = get_audio_base() * pkt.pts;
  136. //                printf("audio base %f\n", audio_base);
  137. //            };
  138.  
  139.             pkt_tmp.data += len;
  140.             pkt_tmp.size -= len;
  141.  
  142.             dec_channel_layout =
  143.                 (aFrame->channel_layout && aFrame->channels == av_get_channel_layout_nb_channels(aFrame->channel_layout)) ?
  144.                 aFrame->channel_layout : av_get_default_channel_layout(aFrame->channels);
  145.  
  146.             if (aFrame->format          != src_fmt     ||
  147.                 dec_channel_layout      != src_layout  ||
  148.                 aFrame->sample_rate     != src_freq    ||
  149.                 !swr_ctx)
  150.             {
  151.                 swr_free(&swr_ctx);
  152.                 swr_ctx = swr_alloc_set_opts(NULL, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16,
  153.                                              aFrame->sample_rate, dec_channel_layout,aFrame->format,
  154.                                              aFrame->sample_rate, 0, NULL);
  155.                 if (!swr_ctx || swr_init(swr_ctx) < 0)
  156.                 {
  157.                     printf("Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
  158.                         aFrame->sample_rate,   av_get_sample_fmt_name(aFrame->format), (int)aFrame->channels,
  159.                         aFrame->sample_rate, av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), 2);
  160.                     break;
  161.                 }
  162.  
  163.                 src_layout   = dec_channel_layout;
  164.                 src_channels = aFrame->channels;
  165.                 src_freq     = aFrame->sample_rate;
  166.                 src_fmt      = aFrame->format;
  167.             };
  168.  
  169.             if (swr_ctx)
  170.             {
  171.                 const uint8_t **in = (const uint8_t **)aFrame->extended_data;
  172.                 uint8_t *out[] = {decoder_buffer};
  173.                 int out_count = 192000 * 3 / 2 / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
  174.                 len2 = swr_convert(swr_ctx, out, out_count, in, aFrame->nb_samples);
  175.                 if (len2 < 0) {
  176.                     printf("swr_convert() failed\n");
  177.                     break;
  178.                 }
  179.                 if (len2 == out_count) {
  180.                     printf("warning: audio buffer is probably too small\n");
  181.                     swr_init(swr_ctx);
  182.                 }
  183.                 data_size = len2 * 2 * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
  184.  
  185.                 mutex_lock(&astream.lock);
  186.  
  187.                 samples = astream.buffer+astream.count;
  188.  
  189.                 memcpy(samples, decoder_buffer, data_size);
  190.  
  191.                 astream.count += data_size;
  192.                 mutex_unlock(&astream.lock);
  193.             };
  194.        }
  195.        else pkt_tmp.size = 0;
  196.     }
  197.     av_free_packet(&pkt);
  198.     return 1;
  199. };
  200.  
  201.  
  202. static void sync_audio(SNDBUF hbuff, int buffsize)
  203. {
  204.     SND_EVENT   evnt;
  205.     uint32_t    offset;
  206.     double      time_stamp;
  207.  
  208. #ifdef BLACK_MAGIC_SOUND
  209.  
  210.     while( player_state != CLOSED)
  211.     {
  212.         GetNotify(&evnt);
  213.  
  214.         if(evnt.code != 0xFF000001)
  215.         {
  216.             printf("invalid event code %d\n\r", evnt.code);
  217.             continue;
  218.         }
  219.  
  220.         if(evnt.stream != hbuff)
  221.         {
  222.             printf("invalid stream %x hBuff= %x\n\r",
  223.                     evnt.stream, hbuff);
  224.             continue;
  225.         }
  226.  
  227.         GetTimeStamp(hbuff, &time_stamp);
  228.         audio_delta = time_stamp - last_time_stamp;
  229.  
  230.         offset = evnt.offset;
  231.  
  232.         mutex_lock(&astream.lock);
  233.         {
  234.             if(astream.count < buffsize)
  235.             {
  236.                 memset(astream.buffer+astream.count,
  237.                        0, buffsize-astream.count);
  238.                 astream.count = buffsize;
  239.             };
  240.  
  241.             SetBuffer(hbuff, astream.buffer, offset, buffsize);
  242.             samples_written+= buffsize/4;
  243.  
  244.             astream.count -= buffsize;
  245.             if(astream.count)
  246.                 memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
  247.             mutex_unlock(&astream.lock);
  248.         };
  249.         break;
  250.     };
  251. #endif
  252.  
  253. };
  254.  
  255. int audio_thread(void *param)
  256. {
  257.     SND_EVENT evnt;
  258.  
  259.     int       buffsize;
  260.     int      samples;
  261.     int       err;
  262.     char     *errstr;
  263.     int       active;
  264.  
  265.     if((err = CreateBuffer(snd_format|PCM_RING,0, &hBuff)) != 0)
  266.     {
  267.         errstr = "Cannot create sound buffer\n\r";
  268.         goto exit_whith_error;
  269.     };
  270.  
  271.     SetVolume(hBuff,-900,-900);
  272.  
  273.     if((err = GetBufferSize(hBuff, &buffsize)) != 0)
  274.     {
  275.         errstr = "Cannot get buffer size\n\r";
  276.         goto exit_whith_error;
  277.     };
  278.  
  279.     __sync_or_and_fetch(&threads_running,AUDIO_THREAD);
  280.  
  281.     resampler_size = buffsize = buffsize/2;
  282.  
  283.     samples = buffsize/4;
  284.  
  285.     while( player_state != CLOSED)
  286.     {
  287.         uint32_t  offset;
  288.         double    event_stamp, wait_stamp;
  289.         int       too_late = 0;
  290.  
  291.         switch(sound_state)
  292.         {
  293.             case PREPARE:
  294.  
  295.                 mutex_lock(&astream.lock);
  296.                     if(astream.count < buffsize*2)
  297.                     {
  298.                         memset(astream.buffer+astream.count,
  299.                                0, buffsize*2-astream.count);
  300.                         astream.count = buffsize*2;
  301.                     };
  302.  
  303.                     SetBuffer(hBuff, astream.buffer, 0, buffsize*2);
  304.                     astream.count -= buffsize*2;
  305.                     if(astream.count)
  306.                         memcpy(astream.buffer, astream.buffer+buffsize*2, astream.count);
  307.                 mutex_unlock(&astream.lock);
  308.  
  309.                 SetTimeBase(hBuff, audio_base);
  310.  
  311.             case PAUSE_2_PLAY:
  312.                 GetTimeStamp(hBuff, &last_time_stamp);
  313. //                printf("last audio time stamp %f\n", last_time_stamp);
  314.  
  315.                 if((err = PlayBuffer(hBuff, 0)) !=0 )
  316.                 {
  317.                     errstr = "Cannot play buffer\n\r";
  318.                     goto exit_whith_error;
  319.                 };
  320.                 active = 1;
  321.                 sync_audio(hBuff, buffsize);
  322.                 sound_state = PLAY;
  323. //                printf("render: set audio latency to %f\n", audio_delta);
  324.  
  325.                 /* breaktrough */
  326.  
  327.             case PLAY:
  328.                 GetNotify(&evnt);
  329.  
  330.                 if(evnt.code != 0xFF000001)
  331.                 {
  332.                     printf("invalid event code %d\n\r", evnt.code);
  333.                     continue;
  334.                 }
  335.  
  336.                 if(evnt.stream != hBuff)
  337.                 {
  338.                     printf("invalid stream %x hBuff= %x\n\r",
  339.                             evnt.stream, hBuff);
  340.                     continue;
  341.                 };
  342.  
  343.                 offset = evnt.offset;
  344.  
  345.                 mutex_lock(&astream.lock);
  346.                 if(astream.count < buffsize)
  347.                 {
  348.                     memset(astream.buffer+astream.count,
  349.                            0, buffsize-astream.count);
  350.                     astream.count = buffsize;
  351.                 };
  352.  
  353.                 SetBuffer(hBuff, astream.buffer, offset, buffsize);
  354.  
  355.                 {
  356.                     double  val = 0;
  357.                     int16_t *src = (int16_t*)astream.buffer;
  358.                     int samples = buffsize/2;
  359.                     int i;
  360.  
  361.                     for(i = 0, val = 0; i < samples/2; i++, src++)
  362.                         if(val < abs(*src))
  363.                             val= abs(*src); // * *src;
  364.  
  365.                     sound_level_0 = val; //sqrt(val / (samples/2));
  366.  
  367.                     for(i = 0, val = 0; i < samples/2; i++, src++)
  368.                         if(val < abs(*src))
  369.                             val= abs(*src); // * *src;
  370.  
  371.                     sound_level_1 = val; //sqrt(val / (samples/2));
  372.  
  373.  //                   printf("%d\n", sound_level);
  374.                 };
  375.  
  376.                 samples_written+= buffsize/4;
  377.  
  378.                 astream.count -= buffsize;
  379.                 if(astream.count)
  380.                     memcpy(astream.buffer, astream.buffer+buffsize, astream.count);
  381.                 mutex_unlock(&astream.lock);
  382.                 break;
  383.  
  384.             case PLAY_2_STOP:
  385.                 if( active )
  386.                 {
  387.                     ResetBuffer(hBuff, SND_RESET_ALL);
  388.                     audio_base = -1.0;
  389.                     active = 0;
  390.                 }
  391.                 sound_state = STOP;
  392.                 break;
  393.  
  394.             case PLAY_2_PAUSE:
  395.                 if( active )
  396.                 {
  397.                     StopBuffer(hBuff);
  398.                 };
  399.                 sound_state = PAUSE;
  400.  
  401.             case PAUSE:
  402.             case STOP:
  403.                 delay(1);
  404.         };
  405.     }
  406.  
  407.     __sync_and_and_fetch(&threads_running,~AUDIO_THREAD);
  408.  
  409.     StopBuffer(hBuff);
  410.     DestroyBuffer(hBuff);
  411.  
  412.     return 0;
  413.  
  414. exit_whith_error:
  415.  
  416.     printf(errstr);
  417.     return -1;
  418.  
  419. };
  420.  
  421.