Subversion Repositories Kolibri OS

Rev

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