Subversion Repositories Kolibri OS

Rev

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