X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=aft.c;h=1b23823e77dd34bcc7acd11dba6e6eca2d56d7db;hp=0ffacbe4f4b0a52ae6cfc73625d3cc5f29de8100;hb=79b1258cf12be5779ec9cc5b175ff58e39310123;hpb=49bd626084bf5f48e4d80075258b6da4703752cf diff --git a/aft.c b/aft.c index 0ffacbe4..1b23823e 100644 --- a/aft.c +++ b/aft.c @@ -98,6 +98,8 @@ struct ls_widths { unsigned short duration_width; /** size of the num played field. */ unsigned short num_played_width; + /** size of the amp field. */ + unsigned short amp_width; }; /** Data passed from the ls command handler to its callback function. */ @@ -142,8 +144,10 @@ enum afsi_offsets { AFSI_LYRICS_ID_OFFSET = 24, /** Storage position of the .audio_format_id field. */ AFSI_AUDIO_FORMAT_ID_OFFSET = 28, - /** 3 bytes reserved space for future usage. */ - AFSI_AUDIO_FORMAT_UNUSED_OFFSET = 29, + /** Storage position of the amplification field. */ + AFSI_AMP_OFFSET = 29, + /** 2 bytes reserved space for future usage. */ + AFSI_AUDIO_FORMAT_UNUSED_OFFSET = 30, /** On-disk storage space needed. */ AFSI_SIZE = 32 }; @@ -167,7 +171,8 @@ void save_afsi(struct afs_info *afsi, struct osl_object *obj) write_u32(buf + AFSI_LYRICS_ID_OFFSET, afsi->lyrics_id); write_u8(buf + AFSI_AUDIO_FORMAT_ID_OFFSET, afsi->audio_format_id); - memset(buf + AFSI_AUDIO_FORMAT_UNUSED_OFFSET, 0, 3); + write_u8(buf + AFSI_AMP_OFFSET, afsi->amp); + memset(buf + AFSI_AUDIO_FORMAT_UNUSED_OFFSET, 0, 2); } /** @@ -192,6 +197,7 @@ int load_afsi(struct afs_info *afsi, struct osl_object *obj) afsi->lyrics_id = read_u32(buf + AFSI_LYRICS_ID_OFFSET); afsi->audio_format_id = read_u8(buf + AFSI_AUDIO_FORMAT_ID_OFFSET); + afsi->amp = read_u8(buf + AFSI_AMP_OFFSET); return 1; } @@ -377,7 +383,7 @@ static void load_afhi(const char *buf, struct afh_info *afhi) afhi->chunk_tv.tv_sec = read_u32(buf + CHUNK_TV_TV_SEC_OFFSET); afhi->chunk_tv.tv_usec = read_u32(buf + CHUNK_TV_TV_USEC_OFFSET); ms2tv(read_u16(buf + AFHI_EOF_OFFSET), &afhi->eof_tv); - strcpy(afhi->info_string, buf + AFHI_INFO_STRING_OFFSET); + afhi->info_string = para_strdup(buf + AFHI_INFO_STRING_OFFSET); } static unsigned sizeof_chunk_table(struct afh_info *afhi) @@ -660,11 +666,11 @@ int open_and_update_audio_file(struct osl_row *aft_row, long score, ret = get_afhi_of_row(aft_row, &afd->afhi); if (ret < 0) return ret; + afd->afhi.chunk_table = NULL; ret = osl_open_disk_object(audio_file_table, aft_row, AFTCOL_CHUNKS, &chunk_table_obj); if (ret < 0) - return ret; - afd->afhi.chunk_table = NULL; + goto err; ret = mmap_full_file(path, O_RDONLY, &map.data, &map.size, &afd->fd); if (ret < 0) @@ -684,14 +690,15 @@ int open_and_update_audio_file(struct osl_row *aft_row, long score, load_chunk_table(&afd->afhi, chunk_table_obj.data); { struct ls_data d = { - .afhi = afd->afhi, + .afhi = afd->afhi, /* struct copy */ .afsi = old_afsi, .path = path, .score = score, .hash = file_hash }; struct para_buffer pb = {.max_size = VERBOSE_LS_OUTPUT_SIZE - 1}; - ret = make_status_items(&d, &pb); + ret = make_status_items(&d, &pb); /* frees info string */ + afd->afhi.info_string = NULL; if (ret < 0) goto err; strncpy(afd->verbose_ls_output, pb.buf, VERBOSE_LS_OUTPUT_SIZE); @@ -704,6 +711,7 @@ int open_and_update_audio_file(struct osl_row *aft_row, long score, ret = save_afd(afd); err: free(afd->afhi.chunk_table); + free(afd->afhi.info_string); osl_close_disk_object(&chunk_table_obj); return ret; } @@ -872,15 +880,19 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts, char asc_hash[2 * HASH_SIZE + 1]; char *att_lines, *lyrics_lines, *image_lines, *filename_lines; - if (opts->mode == LS_MODE_SHORT) - return para_printf(b, "%s\n", d->path); - if (opts->mode == LS_MODE_CHUNKS) - return print_chunk_table(d, b); + if (opts->mode == LS_MODE_SHORT) { + ret = para_printf(b, "%s\n", d->path); + goto out; + } + if (opts->mode == LS_MODE_CHUNKS) { + ret = print_chunk_table(d, b); + goto out; + } get_attribute_bitmap(&afsi->attributes, att_buf); ret = get_local_time(&afsi->last_played, last_played_time, sizeof(last_played_time), current_time, opts->mode); if (ret < 0) - return ret; + goto out; get_duration_buf(afhi->seconds_total, duration_buf, opts); if (have_score) { if (opts->mode == LS_MODE_LONG) @@ -890,9 +902,10 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts, } if (opts->mode == LS_MODE_LONG) { - return para_printf(b, + ret = para_printf(b, "%s" /* score */ "%s " /* attributes */ + "%*u " /* amp */ "%*d " /* image_id */ "%*d " /* lyrics_id */ "%*d " /* bitrate */ @@ -905,6 +918,7 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts, "%s\n", /* path */ score_buf, att_buf, + w->amp_width, afsi->amp, w->image_id_width, afsi->image_id, w->lyrics_id_width, afsi->lyrics_id, w->bitrate_width, afhi->bitrate, @@ -916,6 +930,7 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts, last_played_time, d->path ); + goto out; } hash_to_asc(d->hash, asc_hash); att_lines = make_attribute_lines(att_buf, afsi); @@ -931,7 +946,7 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts, last_played_time, bn? bn : "?"); if (ret < 0) - return ret; + goto out; } ret = para_printf(b, "%s" /* filename stuff */ @@ -948,6 +963,7 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts, "%s: %lu\n" /* seconds total */ "%s: %s\n" /* last played time */ "%s: %d\n" /* num_played */ + "%s: %u\n" /* ampplification */ "%s" /* tag info */ "%s: %lu\n" /* chunk time */ "%s: %lu\n", /* num chunks */ @@ -968,12 +984,13 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts, status_item_list[SI_SECONDS_TOTAL], afhi->seconds_total, status_item_list[SI_LAST_PLAYED], last_played_time, status_item_list[SI_NUM_PLAYED], afsi->num_played, + status_item_list[SI_AMPLIFICATION], afsi->amp, afhi->info_string, status_item_list[SI_CHUNK_TIME], tv2ms(&afhi->chunk_tv), status_item_list[SI_NUM_CHUNKS], afhi->chunks_total ); if (ret < 0) - return ret; + goto out; if (opts->mode == LS_MODE_MBOX) { struct osl_object lyrics_def; lyr_get_def_by_id(afsi->lyrics_id, &lyrics_def); @@ -987,6 +1004,8 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts, free(lyrics_lines); free(image_lines); free(filename_lines); +out: + free(afhi->info_string); return ret; } @@ -1012,6 +1031,10 @@ void make_empty_status_items(char *buf) "%s: \n" /* seconds total */ "%s: \n" /* num played */ "%s: \n" /* last played */ + "%s: \n" /* audio file info */ + "%s: \n" /* taginfo1 */ + "%s: \n" /* taginfo2 */ + "%s: \n" /* amplification */ , status_item_list[SI_PATH], status_item_list[SI_DIRECTORY], @@ -1031,7 +1054,11 @@ void make_empty_status_items(char *buf) status_item_list[SI_DURATION], status_item_list[SI_SECONDS_TOTAL], status_item_list[SI_NUM_PLAYED], - status_item_list[SI_LAST_PLAYED] + status_item_list[SI_LAST_PLAYED], + status_item_list[SI_AUDIO_FILE_INFO], + status_item_list[SI_TAGINFO1], + status_item_list[SI_TAGINFO2], + status_item_list[SI_AMPLIFICATION] ); } @@ -1221,7 +1248,7 @@ static int prepare_ls_row(struct osl_row *row, void *ls_opts) d->path = path; ret = get_hash_of_row(aft_row, &d->hash); if (ret < 0) - return ret; + goto err; w = &options->widths; GET_NUM_DIGITS(d->afsi.image_id, &num_digits); w->image_id_width = PARA_MAX(w->image_id_width, num_digits); @@ -1236,6 +1263,8 @@ static int prepare_ls_row(struct osl_row *row, void *ls_opts) /* get the number of chars to print this amount of time */ tmp = get_duration_width(d->afhi.seconds_total); w->duration_width = PARA_MAX(w->duration_width, tmp); + GET_NUM_DIGITS(d->afsi.amp, &num_digits); + w->amp_width = PARA_MAX(w->amp_width, num_digits); if (options->flags & LS_FLAG_ADMISSIBLE_ONLY) { GET_NUM_DIGITS(score, &num_digits); num_digits++; /* add one for the sign (space or "-") */ @@ -1243,6 +1272,9 @@ static int prepare_ls_row(struct osl_row *row, void *ls_opts) d->score = score; } return 1; +err: + free(d->afhi.info_string); + return ret; } static void com_ls_callback(int fd, const struct osl_object *query) @@ -1728,7 +1760,7 @@ static int get_row_pointer_from_result(struct osl_object *result, void *private) static int add_one_audio_file(const char *path, void *private_data) { - int ret, send_ret = 1; + int ret, send_ret = 1, fd; uint8_t format_num = -1; struct private_add_data *pad = private_data; struct afh_info afhi, *afhi_ptr = NULL; @@ -1752,7 +1784,7 @@ static int add_one_audio_file(const char *path, void *private_data) goto out_free; } /* We still want to add this file. Compute its hash. */ - ret = mmap_full_file(path, O_RDONLY, &map.data, &map.size, NULL); + ret = mmap_full_file(path, O_RDONLY, &map.data, &map.size, &fd); if (ret < 0) goto out_free; hash_function(map.data, map.size, hash); @@ -1777,7 +1809,7 @@ static int add_one_audio_file(const char *path, void *private_data) * there is a hash sister and FORCE was not given. */ if (!hs || (pad->flags & ADD_FLAG_FORCE)) { - ret = compute_afhi(path, map.data, map.size, &afhi); + ret = compute_afhi(path, map.data, map.size, fd, &afhi); if (ret < 0) goto out_unmap; format_num = ret; @@ -1795,14 +1827,17 @@ static int add_one_audio_file(const char *path, void *private_data) goto out_free; out_unmap: + close(fd); munmap(map.data, map.size); out_free: if (ret < 0 && send_ret >= 0) send_ret = send_va_buffer(pad->fd, "failed to add %s (%s)\n", path, para_strerror(-ret)); free(obj.data); - if (afhi_ptr) + if (afhi_ptr) { free(afhi_ptr->chunk_table); + free(afhi_ptr->info_string); + } /* Stop adding files only on send errors. */ return send_ret; } @@ -1893,11 +1928,13 @@ struct com_touch_options { int32_t num_played; /** New last played count. */ int64_t last_played; - /** new lyrics id. */ + /** New lyrics id. */ int32_t lyrics_id; - /** new image id. */ + /** New image id. */ int32_t image_id; - /** command line flags (see \ref touch_flags). */ + /** New amplification value. */ + int32_t amp; + /** Command line flags (see \ref touch_flags). */ unsigned flags; }; @@ -1918,7 +1955,7 @@ static int touch_audio_file(__a_unused struct osl_table *table, struct osl_object obj; struct afs_info old_afsi, new_afsi; int ret, no_options = tad->cto->num_played < 0 && tad->cto->last_played < 0 && - tad->cto->lyrics_id < 0 && tad->cto->image_id < 0; + tad->cto->lyrics_id < 0 && tad->cto->image_id < 0 && tad->cto->amp < 0; struct afsi_change_event_data aced; ret = get_afsi_object_of_row(row, &obj); @@ -1952,6 +1989,8 @@ static int touch_audio_file(__a_unused struct osl_table *table, new_afsi.num_played = tad->cto->num_played; if (tad->cto->last_played >= 0) new_afsi.last_played = tad->cto->last_played; + if (tad->cto->amp >= 0) + new_afsi.amp = tad->cto->amp; } tad->num_matches++; save_afsi(&new_afsi, &obj); /* in-place update */ @@ -1999,7 +2038,8 @@ int com_touch(int fd, int argc, char * const * const argv) .num_played = -1, .last_played = -1, .lyrics_id = -1, - .image_id = -1 + .image_id = -1, + .amp = -1, }; struct osl_object query = {.data = &cto, .size = sizeof(cto)}; int i, ret; @@ -2037,6 +2077,16 @@ int com_touch(int fd, int argc, char * const * const argv) return ret; continue; } + if (!strncmp(arg, "-a", 2)) { + int32_t val; + ret = para_atoi32(arg + 2, &val); + if (ret < 0) + return ret; + if (val < 0 || val > 255) + return -ERRNO_TO_PARA_ERROR(EINVAL); + cto.amp = val; + continue; + } if (!strcmp(arg, "-p")) { cto.flags |= TOUCH_FLAG_FNM_PATHNAME; continue; @@ -2378,8 +2428,8 @@ static int check_audio_file(struct osl_row *row, void *data) /** * Check the audio file table for inconsistencies. * + * \param fd The afs socket. * \param query Unused. - * \param result Contains message string upon return. * * This function always succeeds. *