Subversion Repositories Kolibri OS

Rev

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