gboolean vol_set_filename_text(gpointer data) { volume_t * vol = (volume_t *)data; AQUALUNG_MUTEX_LOCK(vol->wait_mutex); if (vol->slot) { char * utf8; AQUALUNG_MUTEX_LOCK(vol->thread_mutex); utf8 = g_filename_display_name(vol->item->file); AQUALUNG_MUTEX_UNLOCK(vol->thread_mutex); gtk_entry_set_text(GTK_ENTRY(vol->file_entry), utf8); gtk_editable_set_position(GTK_EDITABLE(vol->file_entry), -1); g_free(utf8); } AQUALUNG_COND_SIGNAL(vol->thread_wait); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); return FALSE; }
gint cdda_timeout_callback(gpointer data) { cdda_notify_t notify; while (rb_read_space(cdda_notify_rb) >= sizeof(cdda_notify_t)) { rb_read(cdda_notify_rb, (char *)¬ify, sizeof(cdda_notify_t)); switch (notify.event_type) { case CDDA_EVENT_NEW_DRIVE: AQUALUNG_MUTEX_LOCK(cdda_mutex) insert_cdda_drive_node(notify.device_path); AQUALUNG_MUTEX_UNLOCK(cdda_mutex) free(notify.device_path); break; case CDDA_EVENT_CHANGED_DRIVE: AQUALUNG_MUTEX_LOCK(cdda_mutex) refresh_cdda_drive_node(notify.device_path); AQUALUNG_MUTEX_UNLOCK(cdda_mutex) free(notify.device_path); break; case CDDA_EVENT_REMOVED_DRIVE: AQUALUNG_MUTEX_LOCK(cdda_mutex) remove_cdda_drive_node(notify.device_path); AQUALUNG_MUTEX_UNLOCK(cdda_mutex) free(notify.device_path); break; } } return TRUE; }
void * cdda_scanner(void * arg) { int i = 0; cdio_log_set_handler(cdda_log_handler); AQUALUNG_MUTEX_LOCK(cdda_mutex) cdda_scan_all_drives(); AQUALUNG_MUTEX_UNLOCK(cdda_mutex) while (cdda_scanner_working) { g_usleep(100000); if (i == 50) { /* scan every 5 seconds */ AQUALUNG_MUTEX_LOCK(cdda_mutex) cdda_scan_all_drives(); AQUALUNG_MUTEX_UNLOCK(cdda_mutex) i = 0; } ++i; } AQUALUNG_MUTEX_LOCK(cdda_mutex) for (i = 0; i < CDDA_DRIVES_MAX; i++) { if (cdda_drives[i].cdio != NULL) { cdio_destroy(cdda_drives[i].cdio); memset(cdda_drives + i, 0, sizeof(cdda_drive_t)); } } AQUALUNG_MUTEX_UNLOCK(cdda_mutex) return NULL; }
/* if returns 1, file will be skipped */ int process_volume_setup(volume_t * vol) { if ((vol->fdec = file_decoder_new()) == NULL) { fprintf(stderr, "calculate_volume: error: file_decoder_new() returned NULL\n"); return 1; } if (file_decoder_open(vol->fdec, vol->item->file)) { fprintf(stderr, "file_decoder_open() failed on %s\n", vol->item->file); return 1; } if ((vol->rms = (rms_env_t *)calloc(1, sizeof(rms_env_t))) == NULL) { fprintf(stderr, "calculate_volume(): calloc error\n"); return 1; } vol->chunks_read = 0; vol->chunk_size = vol->fdec->fileinfo.sample_rate / 100; vol->n_chunks = vol->fdec->fileinfo.total_samples / vol->chunk_size + 1; AQUALUNG_MUTEX_LOCK(vol->wait_mutex); aqualung_idle_add(vol_set_filename_text, vol); AQUALUNG_COND_WAIT(vol->thread_wait, vol->wait_mutex); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); vol->result = 0.0f; return 0; }
gboolean vol_update_progress(gpointer data) { volume_t * vol = (volume_t *)data; if (vol->slot) { float fraction = 0.0f; char str_progress[10]; AQUALUNG_MUTEX_LOCK(vol->thread_mutex); if (vol->n_chunks != 0) { fraction = (float)vol->chunks_read / vol->n_chunks; } AQUALUNG_MUTEX_UNLOCK(vol->thread_mutex); if (fraction < 0 || fraction > 1.0f) { fraction = 0.0f; } gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(vol->progress), fraction); snprintf(str_progress, 10, "%.0f%%", fraction * 100.0f); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(vol->progress), str_progress); } return TRUE; }
gboolean vol_store_result_sep(gpointer data) { volume_t * vol = (volume_t *)data; AQUALUNG_MUTEX_LOCK(vol->wait_mutex); vol_store_voladj(vol->store, &vol->item->iter, (vol->store == music_store) ? vol->result : rva_from_volume(vol->result)); AQUALUNG_COND_SIGNAL(vol->thread_wait); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); return FALSE; }
gboolean vol_store_result_avg(gpointer data) { volume_t * vol = (volume_t *)data; GList * node = NULL; float voladj; AQUALUNG_MUTEX_LOCK(vol->wait_mutex); voladj = rva_from_multiple_volumes(vol->n_volumes, vol->volumes); for (node = vol->queue; node; node = node->next) { vol_item_t * item = (vol_item_t *)node->data; vol_store_voladj(vol->store, &item->iter, voladj); } AQUALUNG_COND_SIGNAL(vol->thread_wait); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); return FALSE; }
void * volume_thread(void * arg) { volume_t * vol = (volume_t *)arg; GList * node; float * samples = NULL; unsigned long numread; float chunk_power = 0.0f; float rms; unsigned long i; AQUALUNG_THREAD_DETACH(); for (node = vol->queue; node; node = node->next) { vol->item = (vol_item_t *)node->data; if (process_volume_setup(vol)) { continue; } if ((samples = (float *)malloc(vol->chunk_size * vol->fdec->fileinfo.channels * sizeof(float))) == NULL) { fprintf(stderr, "volume_thread(): malloc() error\n"); file_decoder_close(vol->fdec); file_decoder_delete(vol->fdec); free(vol->rms); break; } do { numread = file_decoder_read(vol->fdec, samples, vol->chunk_size); vol->chunks_read++; /* calculate signal power of chunk and feed it in the rms envelope */ if (numread > 0) { for (i = 0; i < numread * vol->fdec->fileinfo.channels; i++) { chunk_power += samples[i] * samples[i]; } chunk_power /= numread * vol->fdec->fileinfo.channels; rms = rms_env_process(vol->rms, chunk_power); if (rms > vol->result) { vol->result = rms; } } while (vol->paused && !vol->cancelled) { g_usleep(500000); } } while (numread == vol->chunk_size && !vol->cancelled); if (!vol->cancelled) { vol->result = 20.0f * log10f(vol->result); #ifdef HAVE_MPEG /* compensate for anti-clip vol.reduction in dec_mpeg.c/mpeg_output() */ if (vol->fdec->file_lib == MAD_LIB) { vol->result += 1.8f; } #endif /* HAVE_MPEG */ if (vol->type == VOLUME_SEPARATE) { AQUALUNG_MUTEX_LOCK(vol->wait_mutex); aqualung_idle_add(vol_store_result_sep, vol); AQUALUNG_COND_WAIT(vol->thread_wait, vol->wait_mutex); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); } else if (vol->type == VOLUME_AVERAGE) { vol->n_volumes++; if ((vol->volumes = realloc(vol->volumes, vol->n_volumes * sizeof(float))) == NULL) { fprintf(stderr, "volume_thread(): realloc error\n"); return NULL; } vol->volumes[vol->n_volumes - 1] = vol->result; } } file_decoder_close(vol->fdec); file_decoder_delete(vol->fdec); free(vol->rms); free(samples); if (vol->cancelled) { break; } } if (!vol->cancelled && vol->type == VOLUME_AVERAGE) { AQUALUNG_MUTEX_LOCK(vol->wait_mutex); aqualung_idle_add(vol_store_result_avg, vol); AQUALUNG_COND_WAIT(vol->thread_wait, vol->wait_mutex); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); } for (node = vol->queue; node; node = node->next) { vol_item_free((vol_item_t *)node->data); } aqualung_idle_add(volume_finalize, vol); return NULL; }