void bg_nle_audio_compositor_add_stream(bg_nle_audio_compositor_t * c, bg_nle_renderer_instream_audio_t * s, bg_nle_track_t * t) { if(c->num_streams+1 > c->streams_alloc) { c->streams_alloc += 10; c->streams = realloc(c->streams, c->streams_alloc * sizeof(*c->streams)); memset(c->streams + c->num_streams, 0, (c->streams_alloc - c->num_streams) * sizeof(*c->streams)); } c->streams[c->num_streams].t = t; c->streams[c->num_streams].s = s; c->streams[c->num_streams].id = bg_nle_renderer_instream_audio_connect_output(s, &c->streams[c->num_streams].in_format, &c->streams[c->num_streams].overlay_mode, c->format.samplerate); c->streams[c->num_streams].out_format = &c->format; c->streams[c->num_streams].cnv = gavl_audio_converter_create(); gavl_audio_options_copy(gavl_audio_converter_get_options(c->streams[c->num_streams].cnv), c->opt->opt); c->streams[c->num_streams].do_convert = gavl_audio_converter_init(c->streams[c->num_streams].cnv, &c->streams[c->num_streams].in_format, &c->format); c->streams[c->num_streams].frame = gavl_audio_frame_create(&c->streams[c->num_streams].in_format); if(c->streams[c->num_streams].do_convert) c->streams[c->num_streams].frame_cnv = gavl_audio_frame_create(&c->format); switch(c->streams[c->num_streams].overlay_mode) { case BG_NLE_OVERLAY_REPLACE: c->streams[c->num_streams].func = composite_replace; break; case BG_NLE_OVERLAY_ADD: break; } c->num_streams++; }
static int init_gavf_audio(bgav_stream_t * s) { gavf_audio_t * priv; priv = calloc(1, sizeof(*priv)); s->decoder_priv = priv; priv->frame = gavl_audio_frame_create(NULL); return 1; }
static void check_out_frame(gavl_audio_source_t * s) { if(!s->out_frame) { gavl_audio_format_t frame_format; gavl_audio_format_copy(&frame_format, &s->dst_format); frame_format.samples_per_frame = gavl_time_rescale(s->src_format.samplerate, s->dst_format.samplerate, s->src_format.samples_per_frame) + 10; s->out_frame = gavl_audio_frame_create(&frame_format); } }
static void alloc_frames(gavl_audio_converter_t* cnv, int in_samples, double new_ratio) { gavl_audio_convert_context_t * ctx; int out_samples_needed; if((cnv->input_format.samples_per_frame >= in_samples) && (new_ratio < 0.0)) return; cnv->input_format.samples_per_frame = in_samples; /* Set the samples_per_frame member of all intermediate formats */ ctx = cnv->contexts; out_samples_needed = in_samples; while(ctx->next) { ctx->input_format.samples_per_frame = out_samples_needed; if(ctx->samplerate_converter) { /* Varispeed */ if(new_ratio > 0.0) { out_samples_needed = (int)(0.5 * (ctx->samplerate_converter->ratio + new_ratio) * out_samples_needed) + 10; } /* Constant ratio */ else { out_samples_needed = (out_samples_needed * ctx->output_format.samplerate) / ctx->input_format.samplerate + 10; } } if(ctx->output_format.samples_per_frame < out_samples_needed) { ctx->output_format.samples_per_frame = out_samples_needed + 1024; if(ctx->output_frame) gavl_audio_frame_destroy(ctx->output_frame); ctx->output_frame = gavl_audio_frame_create(&ctx->output_format); ctx->next->input_frame = ctx->output_frame; } ctx = ctx->next; } }
static int init_gsm(bgav_stream_t * s) { int tmp; gsm_priv * priv; /* Allocate stuff */ priv = calloc(1, sizeof(*priv)); priv->gsm_state = gsm_create(); s->decoder_priv = priv; if(s->data.audio.format.num_channels > 1) { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Multichannel GSM not supported"); return 0; } if((s->fourcc == BGAV_WAVID_2_FOURCC(0x31)) || (s->fourcc == BGAV_WAVID_2_FOURCC(0x32))) { priv->ms = 1; tmp = 1; gsm_option(priv->gsm_state, GSM_OPT_WAV49, &tmp); } /* Set format */ s->data.audio.format.interleave_mode = GAVL_INTERLEAVE_NONE; s->data.audio.format.sample_format = GAVL_SAMPLE_S16; s->data.audio.format.samples_per_frame = priv->ms ? 2*GSM_FRAME_SAMPLES : GSM_FRAME_SAMPLES; gavl_set_channel_setup(&s->data.audio.format); priv->frame = gavl_audio_frame_create(&s->data.audio.format); if(priv->ms) gavl_metadata_set(&s->m, GAVL_META_FORMAT, "MSGM"); else gavl_metadata_set(&s->m, GAVL_META_FORMAT, "GSM 6.10"); return 1; }
static int get_format(bgav_stream_t * s) { mad_priv_t * priv; const char * version_string; struct mad_header h; priv = s->decoder_priv; mad_header_init(&h); mad_header_decode(&h, &priv->stream); /* Get audio format and create frame */ s->data.audio.format.samplerate = h.samplerate; if(h.mode == MAD_MODE_SINGLE_CHANNEL) s->data.audio.format.num_channels = 1; else s->data.audio.format.num_channels = 2; s->data.audio.format.samplerate = h.samplerate; s->data.audio.format.sample_format = GAVL_SAMPLE_FLOAT; s->data.audio.format.interleave_mode = GAVL_INTERLEAVE_NONE; s->data.audio.format.samples_per_frame = MAD_NSBSAMPLES(&h) * 32; if(!s->codec_bitrate) { if(s->container_bitrate == GAVL_BITRATE_VBR) s->codec_bitrate = GAVL_BITRATE_VBR; else s->codec_bitrate = h.bitrate; } gavl_set_channel_setup(&s->data.audio.format); if(h.flags & MAD_FLAG_MPEG_2_5_EXT) { if(h.layer == 3) s->data.audio.preroll = s->data.audio.format.samples_per_frame * 30; else s->data.audio.preroll = s->data.audio.format.samples_per_frame; version_string = "2.5"; } else if(h.flags & MAD_FLAG_LSF_EXT) { if(h.layer == 3) s->data.audio.preroll = s->data.audio.format.samples_per_frame * 30; else s->data.audio.preroll = s->data.audio.format.samples_per_frame; version_string = "2"; } else { if(h.layer == 3) s->data.audio.preroll = s->data.audio.format.samples_per_frame * 10; else s->data.audio.preroll = s->data.audio.format.samples_per_frame; version_string = "1"; } gavl_metadata_set_nocpy(&s->m, GAVL_META_FORMAT, bgav_sprintf("MPEG-%s layer %d", version_string, h.layer)); priv->audio_frame = gavl_audio_frame_create(&s->data.audio.format); return 1; }
static gavl_source_status_t read_frame_internal(void * sp, gavl_audio_frame_t ** frame, int num_samples) { gavl_audio_source_t * s = sp; int samples_read = s->incomplete_samples; int samples_copied; gavl_source_status_t ret = GAVL_SOURCE_OK; int eat_all = 0; s->incomplete_samples = 0; while(samples_read < num_samples) { /* Read new frame if neccesary */ if(!s->frame || !s->frame->valid_samples) { eat_all = 0; /* Check for passthrough */ if(s->flags & FLAG_PASSTHROUGH) { if((*frame && !(s->src_flags & GAVL_SOURCE_SRC_ALLOC)) || (!(*frame) && (s->src_flags & GAVL_SOURCE_SRC_ALLOC))) { ret = do_read(s, frame); if(ret == GAVL_SOURCE_OK) { process_input(s, *frame); process_output(s, *frame); } return ret; } } if(s->flags & FLAG_DO_CONVERT) { gavl_audio_frame_t * in_frame; if(s->src_flags & GAVL_SOURCE_SRC_ALLOC) in_frame = NULL; else { if(!s->in_frame) s->in_frame = gavl_audio_frame_create(&s->src_format); in_frame = s->in_frame; } ret = do_read(s, &in_frame); if(ret != GAVL_SOURCE_OK) break; if(!process_input(s, in_frame)) continue; /* Get out frame */ check_out_frame(s); gavl_audio_convert(s->cnv, in_frame, s->out_frame); s->frame = s->out_frame; #if 0 if(s->src_format.samplerate != s->dst_format.samplerate) fprintf(stderr, "Converted frame (resample) %d %d\n", in_frame->valid_samples, s->out_frame->valid_samples); #endif } else { if(s->src_flags & GAVL_SOURCE_SRC_ALLOC) { s->frame = NULL; ret = do_read(s, &s->frame); if(ret != GAVL_SOURCE_OK) break; if(!process_input(s, s->frame)) continue; eat_all = 1; } else { check_out_frame(s); ret = do_read(s, &s->out_frame); if(ret != GAVL_SOURCE_OK) break; s->frame = s->out_frame; if(!process_input(s, s->frame)) continue; } } s->frame_samples = s->frame->valid_samples; } /* Make sure we have a frame to write to */ if(!(*frame)) { if(!s->dst_frame) s->dst_frame = gavl_audio_frame_create(&s->dst_format); *frame = s->dst_frame; } /* Copy samples */ samples_copied = gavl_audio_frame_copy(&s->dst_format, *frame, // dst s->frame, // src samples_read, // dst_pos s->frame_samples - s->frame->valid_samples, // src_pos num_samples - samples_read, // dst_size s->frame->valid_samples); // src_size s->frame->valid_samples -= samples_copied; samples_read += samples_copied; } if(ret == GAVL_SOURCE_AGAIN) { s->incomplete_samples = samples_read; return GAVL_SOURCE_AGAIN; } if(samples_read) { ret = GAVL_SOURCE_OK; (*frame)->valid_samples = samples_read; process_output(s, *frame); /* Buffer samples for next time (we need to eat up all samples in this call) */ if(eat_all && s->frame->valid_samples) { if(!s->buffer_frame) s->buffer_frame = gavl_audio_frame_create(&s->src_format); s->buffer_frame->valid_samples = gavl_audio_frame_copy(&s->src_format, s->buffer_frame, // dst s->frame, // src 0, // dst_pos s->frame_samples - s->frame->valid_samples, // src_pos s->src_format.samples_per_frame, // dst_size s->frame->valid_samples); // src_size s->frame = s->buffer_frame; s->frame_samples = s->frame->valid_samples; } } else if(*frame) (*frame)->valid_samples = 0; return ret; }
static int open_esd(void * data, gavl_audio_format_t * format, gavl_video_format_t * video_format, gavl_metadata_t * m) { int esd_format; const char * esd_host; char * name; char hostname[128]; esd_t * e = data; e->samples_read = 0; /* Set up format */ memset(format, 0, sizeof(*format)); format->interleave_mode = GAVL_INTERLEAVE_ALL; format->samplerate = 44100; format->sample_format = GAVL_SAMPLE_S16; format->samples_per_frame = ESD_BUF_SIZE / 4; format->num_channels = 2; gavl_set_channel_setup(format); gavl_audio_format_copy(&e->format, format); e->f = gavl_audio_frame_create(format); if(!e->hostname || (*(e->hostname) == '\0')) { esd_host = NULL; } else esd_host = e->hostname; esd_format = ESD_STREAM | ESD_PLAY; if(e->do_monitor) esd_format |= ESD_MONITOR; else esd_format |= ESD_RECORD; esd_format |= (ESD_STEREO|ESD_BITS16); gethostname(hostname, 128); name = bg_sprintf("gmerlin@%s pid: %d", hostname, getpid()); if(e->do_monitor) e->esd_socket = esd_monitor_stream(esd_format, format->samplerate, e->hostname, name); else e->esd_socket = esd_record_stream(esd_format, format->samplerate, e->hostname, name); free(name); if(e->esd_socket < 0) { bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Cannot connect to daemon"); return 0; } e->bytes_per_frame = 4; e->src = gavl_audio_source_create(read_func_esd, e, GAVL_SOURCE_SRC_FRAMESIZE_MAX, format); return 1; }
static int init_real(bgav_stream_t * s) { ra_init_t init_data; char codec_filename[PATH_MAX]; real_priv_t * priv; int i; char * path; int len; void * prop; const codec_info_t * info = NULL; priv = calloc(1, sizeof(*priv)); s->decoder_priv = priv; for(i = 0; i < sizeof(real_codecs) / sizeof(real_codecs[0]); i++) { if(&real_codecs[i].decoder == s->data.audio.decoder) { info = &real_codecs[i]; break; } } if(!info) return 0; sprintf(codec_filename, "%s/%s", bgav_dll_path_real, info->dll_name); /* Try to dlopen it */ if(!(priv->module = dlopen(codec_filename, RTLD_NOW))) { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Could not open DLL %s %s", codec_filename, dlerror()); return 0; } /* Get the symbols */ priv->raCloseCodec = dlsym(priv->module, "RACloseCodec"); priv->raDecode = dlsym(priv->module, "RADecode"); priv->raFlush = dlsym(priv->module, "RAFlush"); priv->raFreeDecoder = dlsym(priv->module, "RAFreeDecoder"); priv->raGetFlavorProperty = dlsym(priv->module, "RAGetFlavorProperty"); priv->raOpenCodec = dlsym(priv->module, "RAOpenCodec"); priv->raOpenCodec2 = dlsym(priv->module, "RAOpenCodec2"); priv->raInitDecoder = dlsym(priv->module, "RAInitDecoder"); priv->raSetFlavor = dlsym(priv->module, "RASetFlavor"); priv->raSetDLLAccessPath = dlsym(priv->module, "SetDLLAccessPath"); priv->raSetPwd = dlsym(priv->module, "RASetPwd"); // optional, used by SIPR if(!(priv->raCloseCodec && priv->raDecode && priv->raFreeDecoder && priv->raGetFlavorProperty && (priv->raOpenCodec||priv->raOpenCodec2) && priv->raSetFlavor && priv->raInitDecoder)) return 0; path= bgav_sprintf("DT_Codecs=%s", bgav_dll_path_real); if(path[strlen(path)-1]!='/') path = gavl_strcat(path, "/"); /* Append one zero byte */ path = realloc(path, strlen(path)+2); path[strlen(path)+1] = '\0'; /* Set the codec path */ if(priv->raSetDLLAccessPath) { // used by 'SIPR' priv->raSetDLLAccessPath(path); } if(priv->raOpenCodec2) { if(priv->raOpenCodec2(&priv->real_handle,&path[10])) { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "raOpenCodec2 failed"); return 0; } } else if(priv->raOpenCodec(priv->real_handle)) { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "raOpenCodec2 failed"); return 0; } free(path); init_data.samplerate = s->data.audio.format.samplerate; init_data.bits = s->data.audio.bits_per_sample; init_data.channels = s->data.audio.format.num_channels; init_data.quality = 100; /* 2bytes padding here, by gcc */ init_data.bits_per_frame = s->data.audio.block_align; init_data.packetsize = s->data.audio.block_align; init_data.extradata_len = s->ext_size; init_data.extradata = s->ext_data; #ifdef DUMP_EXTRADATA bgav_dprintf("Extradata: %d bytes\n", s->ext_size); gavl_hexdump(s->ext_data, s->ext_size, 16); #endif // dump_init_data(&init_data); if(priv->raInitDecoder(priv->real_handle,&init_data)) { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "raInitDecoder failed"); return 0; } if(priv->raSetPwd) { priv->raSetPwd(priv->real_handle,"Ardubancel Quazanga"); } if(priv->raSetFlavor(priv->real_handle,s->subformat)) { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "raSetFlavor failed"); return 0; } prop = priv->raGetFlavorProperty(priv->real_handle, s->subformat, 0, &len); if(prop) gavl_metadata_set_nocpy(&s->m, GAVL_META_FORMAT, bgav_sprintf("%s (Flavor: %s)", info->format_name, (char*)prop)); else gavl_metadata_set_nocpy(&s->m, GAVL_META_FORMAT, bgav_sprintf("%s", info->format_name)); // prop = priv->raGetFlavorProperty(priv->real_handle, s->subformat, 1, &len); /* Allocate sample buffer and set audio format */ s->data.audio.format.interleave_mode = GAVL_INTERLEAVE_ALL; s->data.audio.format.sample_format = GAVL_SAMPLE_S16; gavl_set_channel_setup(&s->data.audio.format); s->data.audio.format.samples_per_frame = 10240; priv->frame = gavl_audio_frame_create(&s->data.audio.format); s->data.audio.format.samples_per_frame = 1024; return 1; }
bool ReadMedia::initFormat() { const gavl_audio_format_t * open_audio_format; const gavl_video_format_t * open_video_format; // we use the m_vfifosize to see if the user app wants video or not // then, we set m_video_stream_count to 0 if he doesn't want video if (m_video_stream_count > 0 && m_vfifosize > 0) { open_video_format = bgav_get_video_format(m_file, 0); if (open_video_format->pixelformat == GAVL_PIXELFORMAT_NONE) { printf("!!!sorry, pixelformat is not recognized.\n"); return false; } // let's check to see if the formats are the same, if they are the same // there is no reason to recreate the fifo or frames if ( gavl_video_formats_equal( &m_video_format, open_video_format) == 0 ) { // the formats are different gavl_video_format_copy (&m_video_format, open_video_format); if (m_video_frame != NULL) gavl_video_frame_destroy(m_video_frame); m_video_frame = gavl_video_frame_create(&m_video_format); gavl_video_frame_clear( m_video_frame, &m_video_format); if (m_fifovideo != NULL) delete m_fifovideo; m_fifovideo= new FifoVideoFrames( m_vfifosize , &m_video_format); } } else { m_video_stream_count = 0; m_veof = true; } // we use the m_afifosize to see if the user app wants audio or not // then, we set m_audio_stream_count to 0 if he doesn't want audio if (m_audio_stream_count > 0 && m_afifosize > 0) { open_audio_format = bgav_get_audio_format(m_file, 0); // we can get audio formats that are unkown if ( open_audio_format->sample_format == GAVL_SAMPLE_NONE) { printf("sorry, this file has unsupported audio.\n"); return false; } if ( gavl_audio_formats_equal(&m_audio_format, open_audio_format) == 0 ) { // audio formats are different // save the old spf int spf = m_audio_format.samples_per_frame; gavl_audio_format_copy(&m_audio_format, open_audio_format); if (m_audio_frame != NULL) { gavl_audio_frame_destroy(m_audio_frame); } // set it back to original m_audio_format.samples_per_frame = spf ; m_audio_frame = gavl_audio_frame_create(&m_audio_format); gavl_audio_frame_mute( m_audio_frame, &m_audio_format); if( m_fifoaudio != NULL ) delete m_fifoaudio; m_fifoaudio = new FifoAudioFrames( m_afifosize , &m_audio_format); } } else { // user doesn't want audio m_audio_stream_count = 0; m_aeof=true; } m_length_in_gavltime = bgav_get_duration ( m_file, 0);; m_length_in_seconds = gavl_time_to_seconds( m_length_in_gavltime ); m_num_samples = 0; m_num_frames = 0; if (m_audio_stream_count) { if ( bgav_can_seek_sample(m_file) == 1 ) { m_num_samples= bgav_audio_duration ( m_file, 0) ; } else { m_num_samples= gavl_time_to_samples( m_audio_format.samplerate , bgav_get_duration ( m_file, 0) ); } } // set frames WE NEED TO take care here for non-constant frame-rates if(m_video_stream_count) { if ( bgav_can_seek_sample(m_file) == 1 && m_video_format.framerate_mode == GAVL_FRAMERATE_CONSTANT) { m_num_frames = bgav_video_duration ( m_file, 0)/ m_video_format.frame_duration; } else if ( bgav_can_seek_sample(m_file) == 1 && m_video_format.framerate_mode == GAVL_FRAMERATE_VARIABLE ) { // FIXME what to do with non constant frame rates? m_num_frames=0; } else { m_num_frames = gavl_time_to_frames( m_video_format.timescale, m_video_format.frame_duration , bgav_get_duration ( m_file, 0) ); } } // printf("m_num_frames =%lld, duration = %lld , vid_duration=%lld\n", // m_num_frames, bgav_get_duration ( m_file, 0), bgav_video_duration ( m_file, 0) ); // set seconds if ( bgav_can_seek_sample(m_file) == 1) { gavl_time_t atime=0,vtime=0; if ( m_audio_stream_count ) atime = gavl_samples_to_time( m_audio_format.samplerate, m_num_samples ); if (m_video_stream_count && m_video_format.frame_duration > 0) { vtime = gavl_frames_to_time( m_video_format.timescale, m_video_format.frame_duration, m_num_frames ); } else if ( m_video_stream_count ) { // non constant framerate vtime = bgav_video_duration( m_file, 0); } // else rely on audio time m_length_in_gavltime = atime > vtime ? atime :vtime; m_length_in_seconds = gavl_time_to_seconds( m_length_in_gavltime ); //printf("atime=%ld, vtime=%ld, l_in_sec=%f\n", atime, vtime, m_length_in_seconds); } m_pcm_seek = SEEK_NOTHING; m_frame_seek = SEEK_NOTHING; return true; }
int main(int argc, char ** argv) { GtkWidget * window; bg_plugin_registry_t * plugin_reg; bg_cfg_registry_t * cfg_reg; bg_cfg_section_t * cfg_section; char * tmp_path; idle_data_t id; const bg_plugin_info_t * info; gavl_metadata_t m; bg_gtk_init(&argc, &argv, NULL, NULL, NULL); gavl_metadata_init(&m); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); id.meter = bg_gtk_vumeter_create(2, 1); gtk_container_add(GTK_CONTAINER(window), bg_gtk_vumeter_get_widget(id.meter)); /* Create plugin registry */ cfg_reg = bg_cfg_registry_create(); tmp_path = bg_search_file_read("generic", "config.xml"); bg_cfg_registry_load(cfg_reg, tmp_path); if(tmp_path) free(tmp_path); cfg_section = bg_cfg_registry_find_section(cfg_reg, "plugins"); plugin_reg = bg_plugin_registry_create(cfg_section); /* Load and open plugin */ info = bg_plugin_registry_get_default(plugin_reg, BG_PLUGIN_RECORDER_AUDIO, BG_PLUGIN_RECORDER); id.ra_handle = bg_plugin_load(plugin_reg, info); id.ra_plugin = (bg_recorder_plugin_t*)(id.ra_handle->plugin); /* The soundcard might be busy from last time, give the kernel some time to free the device */ if(!id.ra_plugin->open(id.ra_handle->priv, &id.format, NULL, &m)) { fprintf(stderr, "Couldn't open audio device"); return -1; } /* */ id.frame = gavl_audio_frame_create(&id.format); bg_gtk_vumeter_set_format(id.meter, &id.format); g_idle_add(idle_callback, &id); gtk_widget_show(window); gtk_main(); return 0; }
static void open_audio(visualizer_t * v) { int i; int was_open; gavl_time_t delay_time = GAVL_TIME_SCALE / 20; /* 50 ms */ memset(&v->audio_format, 0, sizeof(v->audio_format)); v->audio_format.num_channels = 2; v->audio_format.samplerate = 44100; v->audio_format.sample_format = GAVL_SAMPLE_S16; gavl_set_channel_setup(&v->audio_format); if(v->audio_frame) { gavl_audio_frame_destroy(v->audio_frame); v->ra_plugin->close(v->ra_handle->priv); v->audio_frame = NULL; bg_plugin_unref(v->ra_handle); was_open = 1; } else was_open = 0; v->audio_open = 0; v->ra_handle = bg_plugin_load(v->plugin_reg, v->ra_info); v->ra_plugin = (bg_recorder_plugin_t*)(v->ra_handle->plugin); /* The soundcard might be busy from last time, give the kernel some time to free the device */ if(!v->ra_plugin->open(v->ra_handle->priv, &v->audio_format, NULL, &v->m)) { if(!was_open) { bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Opening audio device failed, fix settings and click restart"); gtk_label_set_text(GTK_LABEL(v->fps), TR("No audio")); return; } for(i = 0; i < 20; i++) { gavl_time_delay(&delay_time); if(v->ra_plugin->open(v->ra_handle->priv, &v->audio_format, NULL, &v->m)) { v->audio_open = 1; break; } } } else v->audio_open = 1; if(v->audio_open) { v->audio_frame = gavl_audio_frame_create(&v->audio_format); bg_gtk_vumeter_set_format(v->vumeter, &v->audio_format); } else { bg_log(BG_LOG_ERROR, LOG_DOMAIN, "Opening audio device failed, fix settings and click restart"); gtk_label_set_text(GTK_LABEL(v->fps), TR("No audio")); } }