Exemple #1
0
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;
}
Exemple #2
0
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 *)&notify, 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;
}
Exemple #3
0
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;
}
Exemple #4
0
/* 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;
}
Exemple #5
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;
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}