⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stream_radio.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 3 页
字号:
    while ((tmp = strrchr(priv->radio_param->adevice, '.')))        tmp[0] = ',';#endif    if(audio_in_init(&priv->audio_in, is_oss?AUDIO_IN_OSS:AUDIO_IN_ALSA)<0){        mp_msg(MSGT_RADIO, MSGL_ERR, MSGTR_RADIO_AudioInInitFailed);    }    audio_in_set_device(&priv->audio_in, priv->radio_param->adevice);    audio_in_set_channels(&priv->audio_in, priv->radio_param->achannels);    audio_in_set_samplerate(&priv->audio_in, priv->radio_param->arate);    if (audio_in_setup(&priv->audio_in) < 0) {        mp_msg(MSGT_RADIO, MSGL_ERR, MSGTR_RADIO_AudioInSetupFailed, strerror(errno));        return STREAM_ERROR;    }#ifdef USE_OSS_AUDIO    if(is_oss)        ioctl(priv->audio_in.oss.audio_fd, SNDCTL_DSP_NONBLOCK, 0);#endif#if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)    if(!is_oss)        snd_pcm_nonblock(priv->audio_in.alsa.handle,1);#endif    priv->audio_buffer_size = seconds*priv->audio_in.samplerate*priv->audio_in.channels*            priv->audio_in.bytes_per_sample+priv->audio_in.blocksize;    if (priv->audio_buffer_size < 256*priv->audio_in.blocksize)        priv->audio_buffer_size = 256*priv->audio_in.blocksize;    mp_msg(MSGT_RADIO, MSGL_V, MSGTR_RADIO_AudioBuffer,        priv->audio_buffer_size,priv->audio_in.blocksize);    /* start capture */    priv->audio_ringbuffer = calloc(1, priv->audio_buffer_size);    if (!priv->audio_ringbuffer) {        mp_msg(MSGT_RADIO, MSGL_ERR, MSGTR_RADIO_AllocateBufferFailed,priv->audio_in.blocksize, priv->audio_buffer_size, strerror(errno));        return STREAM_ERROR;    }    priv->audio_head = 0;    priv->audio_tail = 0;    priv->audio_cnt = 0;    priv->audio_drop = 0;    priv->audio_inited = 1;    return STREAM_OK;}#endif //USE_RADIO_CAPTURE/*------------------------------------------------------------------------- for call from mplayer.c--------------------------------------------------------------------------*//***************************************************************** * \brief public wrapper for get_frequency * \parameter frequency pointer to float, which will contain frequency in MHz * \return 1 if success,0 - otherwise */int radio_get_freq(struct stream_st *stream, float* frequency){    radio_priv_t* priv=(radio_priv_t*)stream->priv;    if (!frequency)	return 0;    if (get_frequency(priv,frequency)!=STREAM_OK){        return 0;    }    return 1;}/***************************************************************** * \brief public wrapper for set_frequency * \parameter frequency frequency in MHz * \return 1 if success,0 - otherwise */int radio_set_freq(struct stream_st *stream, float frequency){    radio_priv_t* priv=(radio_priv_t*)stream->priv;    if (set_frequency(priv,frequency)!=STREAM_OK){        return 0;    }    if (get_frequency(priv,&frequency)!=STREAM_OK){        return 0;    }    mp_msg(MSGT_RADIO, MSGL_INFO, MSGTR_RADIO_CurrentFreq,frequency);    return 1;}/***************************************************************** * \brief tune current frequency by step_interval value * \parameter step_interval increment value * \return 1 if success,0 - otherwise * */int radio_step_freq(struct stream_st *stream, float step_interval){    float frequency;    radio_priv_t* priv=(radio_priv_t*)stream->priv;        if (get_frequency(priv,&frequency)!=STREAM_OK)        return 0;        frequency+=step_interval;    if (frequency>priv->rangehigh)        frequency=priv->rangehigh;    if (frequency<priv->rangelow)        frequency=priv->rangelow;    return radio_set_freq(stream,frequency);}/***************************************************************** * \brief step channel up or down * \parameter direction RADIO_CHANNEL_LOWER - go to prev channel,RADIO_CHANNEL_HIGHER - to next * \return 1 if success,0 - otherwise * *  if channel parameter is NULL function prints error message and does nothing, otherwise *  changes channel to prev or next in list */int radio_step_channel(struct stream_st *stream, int direction) {    radio_priv_t* priv=(radio_priv_t*)stream->priv;    if (priv->radio_channel_list) {        switch (direction){            case  RADIO_CHANNEL_HIGHER:                if (priv->radio_channel_current->next)                    priv->radio_channel_current = priv->radio_channel_current->next;                else                    priv->radio_channel_current = priv->radio_channel_list;                if(!radio_set_freq(stream,priv->radio_channel_current->freq))                    return 0;                mp_msg(MSGT_RADIO, MSGL_V, MSGTR_RADIO_SelectedChannel,                    priv->radio_channel_current->index, priv->radio_channel_current->name,                    priv->radio_channel_current->freq);            break;            case RADIO_CHANNEL_LOWER:                if (priv->radio_channel_current->prev)                    priv->radio_channel_current = priv->radio_channel_current->prev;                else                    while (priv->radio_channel_current->next)                        priv->radio_channel_current = priv->radio_channel_current->next;                if(!radio_set_freq(stream,priv->radio_channel_current->freq))                    return 0;                mp_msg(MSGT_RADIO, MSGL_V, MSGTR_RADIO_SelectedChannel,                priv->radio_channel_current->index, priv->radio_channel_current->name,                priv->radio_channel_current->freq);            break;        }    }else        mp_msg(MSGT_RADIO, MSGL_ERR, MSGTR_RADIO_ChangeChannelNoChannelList);    return 1;}/***************************************************************** * \brief change channel to one with given index * \parameter channel string, containing channel number * \return 1 if success,0 - otherwise * *  if channel parameter is NULL function prints error message and does nothing, otherwise *  changes channel to given */int radio_set_channel(struct stream_st *stream, char *channel) {    radio_priv_t* priv=(radio_priv_t*)stream->priv;    int i, channel_int;    radio_channels_t* tmp;    char* endptr;    if (*channel=='\0')        mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_WrongChannelName,channel);        if (priv->radio_channel_list) {        channel_int = strtol(channel,&endptr,10);        tmp = priv->radio_channel_list;        if (*endptr!='\0'){            //channel is not a number, so it contains channel name            for ( ; tmp; tmp=tmp->next)                if (!strncmp(channel,tmp->name,sizeof(tmp->name)-1))                    break;                if (!tmp){                mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_WrongChannelName,channel);                return 0;            }        }else{        for (i = 1; i < channel_int; i++)            if (tmp->next)                tmp = tmp->next;            else                break;        if (tmp->index!=channel_int){            mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_WrongChannelNumberInt,channel_int);            return 0;        }        }        priv->radio_channel_current=tmp;        mp_msg(MSGT_RADIO, MSGL_V, MSGTR_RADIO_SelectedChannel, priv->radio_channel_current->index,            priv->radio_channel_current->name, priv->radio_channel_current->freq);        if(!radio_set_freq(stream, priv->radio_channel_current->freq))            return 0;    } else        mp_msg(MSGT_RADIO, MSGL_ERR, MSGTR_RADIO_ChangeChannelNoChannelList);    return 1;}/***************************************************************** * \brief get current channel's name * \return pointer to string, containing current channel's name * *  NOTE: return value may be NULL (e.g. when channel list not initialized) */char* radio_get_channel_name(struct stream_st *stream){    radio_priv_t* priv=(radio_priv_t*)stream->priv;    if (priv->radio_channel_current) {        return priv->radio_channel_current->name;    }    return NULL;}/***************************************************************** * \brief fills given buffer with audio data * \return number of bytes, written into buffer */static int fill_buffer_s(struct stream_st *s, char* buffer, int max_len){    int len=max_len;#ifdef USE_RADIO_CAPTURE    radio_priv_t* priv=(radio_priv_t*)s->priv;    if (priv->do_capture){        len=grab_audio_frame(priv, buffer,max_len);    }    else#endif    memset(buffer,0,len);    return len;}/* order if significant!  when no driver explicitly specified first available will be used */static const radio_driver_t* radio_drivers[]={#ifdef HAVE_RADIO_BSDBT848    &radio_driver_bsdbt848,#endif#ifdef HAVE_RADIO_V4L2    &radio_driver_v4l2,#endif#ifdef HAVE_RADIO_V4L    &radio_driver_v4l,#endif    0};/***************************************************************** * Stream initialization * \return STREAM_OK if success, STREAM_ERROR otherwise */static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {    radio_priv_t* priv;    float frequency=0;    int i;    if (strncmp("radio://",stream->url,8) != 0)        return STREAM_UNSUPPORTED;    if(mode != STREAM_READ)        return STREAM_UNSUPPORTED;    priv=calloc(1,sizeof(radio_priv_t));    if (!priv)        return STREAM_ERROR;    priv->radio_param=opts;#ifdef USE_RADIO_CAPTURE    if (priv->radio_param->capture && strncmp("capture",priv->radio_param->capture,7)==0)        priv->do_capture=1;    else        priv->do_capture=0;#endif    if (strncmp(priv->radio_param->driver,"default",7)==0)        priv->driver=radio_drivers[0];    else        priv->driver=NULL;    mp_msg(MSGT_RADIO,MSGL_V,MSGTR_RADIO_AvailableDrivers);    for(i=0;radio_drivers[i];i++){        mp_msg(MSGT_RADIO,MSGL_V,"%s, ",radio_drivers[i]->name);        if(strcmp(priv->radio_param->driver,radio_drivers[i]->name)==0)            priv->driver=radio_drivers[i];    }    mp_msg(MSGT_RADIO,MSGL_V,"\n");        if(priv->driver)        mp_msg(MSGT_RADIO, MSGL_INFO, priv->driver->info);    else{        mp_msg(MSGT_RADIO, MSGL_INFO, MSGTR_RADIO_DriverUnknownStr,priv->radio_param->driver);        close_s(stream);        return STREAM_ERROR;    }    stream->type = STREAMTYPE_RADIO;    /* using rawaudio demuxer */    *file_format =  DEMUXER_TYPE_RAWAUDIO;    stream->flags = STREAM_READ;    priv->radio_fd=-1;    stream->start_pos=0;    stream->end_pos=0;    stream->priv=priv;    stream->close=close_s;    stream->fill_buffer=fill_buffer_s;    priv->radio_fd = open(priv->radio_param->device, O_RDONLY);    if (priv->radio_fd < 0) {        mp_msg(MSGT_RADIO, MSGL_ERR, MSGTR_RADIO_UnableOpenDevice,            priv->radio_param->device, strerror(errno));        close_s(stream);        return STREAM_ERROR;    }    mp_msg(MSGT_RADIO, MSGL_V, MSGTR_RADIO_RadioDevice, priv->radio_fd,priv->radio_param->device);    fcntl(priv->radio_fd, F_SETFD, FD_CLOEXEC);    get_volume(priv, &priv->old_snd_volume);    set_volume(priv,0);    if (init_frac(priv)!=STREAM_OK){        close_s(stream);        return STREAM_ERROR;    };    if (parse_channels(priv,priv->radio_param->freq_channel,&frequency)!=STREAM_OK){        close_s(stream);        return STREAM_ERROR;    }    if ((frequency<priv->rangelow)||(frequency>priv->rangehigh)){        mp_msg(MSGT_RADIO, MSGL_ERR, MSGTR_RADIO_WrongFreq,frequency);        close_s(stream);        return STREAM_ERROR;    }else        mp_msg(MSGT_RADIO, MSGL_INFO, MSGTR_RADIO_UsingFreq,frequency);    if(set_frequency(priv,frequency)!=STREAM_OK){        close_s(stream);        return STREAM_ERROR;    }    if (init_audio(priv)!=STREAM_OK){        close_s(stream);        return STREAM_ERROR;    }#if defined(USE_RADIO_CAPTURE) && defined(USE_STREAM_CACHE)    if(priv->do_capture){        //5 second cache        if(!stream_enable_cache(stream,5*priv->audio_in.samplerate*priv->audio_in.channels*                priv->audio_in.bytes_per_sample,2*priv->audio_in.samplerate*priv->audio_in.channels*                priv->audio_in.bytes_per_sample,priv->audio_in.blocksize)) {            mp_msg(MSGT_RADIO, MSGL_ERR, MSGTR_RADIO_StreamEnableCacheFailed,strerror(errno));            close_s(stream);            return STREAM_ERROR;        }    }#endif    set_volume(priv,priv->radio_param->volume);    return STREAM_OK;}/***************************************************************** * Close stream. Clear structures. */static void close_s(struct stream_st * stream){    radio_priv_t* priv=(radio_priv_t*)stream->priv;    radio_channels_t * tmp;    if (!priv) return;#ifdef USE_RADIO_CAPTURE    if(priv->audio_ringbuffer){        free(priv->audio_ringbuffer);        priv->audio_ringbuffer=NULL;    }    priv->do_capture=0;#endif    while (priv->radio_channel_list) {        tmp=priv->radio_channel_list;        priv->radio_channel_list=priv->radio_channel_list->next;        free(tmp);    }    priv->radio_channel_current=NULL;    priv->radio_channel_list=NULL;    if (priv->radio_fd>0){        set_volume(priv, priv->old_snd_volume);        close(priv->radio_fd);    }    if(priv->radio_param)        m_struct_free(&stream_opts,priv->radio_param);    free(priv);    stream->priv=NULL;}stream_info_t stream_info_radio = {    "Radio stream",    "Radio",    "Vladimir Voroshilov",    "In development",    open_s,    { "radio", NULL },    &stream_opts,    1 // Urls are an option string};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -