static void setup ( int32_t *img_height, int32_t samplecount, int32_t *wav_rate, double *low_freq, double *high_freq, double *pix_per_sec, double *bpo, int32_t img_width, int32_t mode ) { double f, ma; int32_t unset = 0, set_min = 0, set_max = 0, set_bpo = 0, set_y = 0, set_pps = 0, set_x = 0, i; if (*low_freq != 0) set_min = 1; if (*high_freq != 0) set_max = 1; if (*bpo != 0) set_bpo = 1; if (*img_height != 0) set_y = 1; unset = set_min + set_max + set_bpo + set_y; if (unset == 4) { message("%s", warn_1); message("%s", warn_2); *high_freq = 0.0; set_max = 0; } if (*pix_per_sec != 0) set_pps = 1; if (img_width != 0) set_x = 1; if (set_x + set_pps == 2 && mode == MODE_ANAL) { message("%s", warn_3); message("%s", warn_4); *pix_per_sec = 0.0; set_pps = 0; } *low_freq /= *wav_rate; if (unset < 3 && set_min == 0) { message("%s", err_21); exit(EXIT_FAILURE); } if (unset < 3 && set_bpo == 0) { message("%s", err_22); exit(EXIT_FAILURE); } if (unset < 3 && set_max == 0) { if (mode == MODE_ANAL) { message("%s", err_23); exit(EXIT_FAILURE); } i = 0; do { i++; f = *low_freq * pow(logbase, (i / *bpo)); } while (f < 0.5); ma = *low_freq * pow(logbase, ((i - 2) / *bpo)) * (*wav_rate); if (*high_freq > ma) { if (fmod(ma, 1.0) == 0.0) *high_freq = ma; else *high_freq = ma - fmod(ma, 1.0); } unset++; set_max = 1; } if (set_min == 0) { *low_freq = pow(logbase, (*img_height - 1) / *bpo) * (*high_freq); message("Minimum frequency set to: %.3f Hz", *low_freq); *low_freq /= *wav_rate; } if (set_max == 0) { *high_freq = pow(logbase, (*img_height - 1) / *bpo) * (*low_freq * (*wav_rate)); message("Maximum frequency set to: %.3f Hz", *high_freq); } if (set_y == 0) { *img_height = 1 + roundoff(*bpo * (log_b(*high_freq) - log_b(*low_freq * *wav_rate))); message("Image height set to: %d", *img_height); } if (set_bpo == 0) { if (logbase == 1.0) *bpo = *high_freq / *wav_rate; else *bpo = (*img_height - 1) / (log_b(*high_freq) - log_b(*low_freq * (*wav_rate))); message("Bands per octave set to: %.3f", *bpo); } if (set_x == 1 && mode == MODE_ANAL) { *pix_per_sec = (double) img_width * (double) *wav_rate / (double) samplecount; set_pps = 1; message("Pixels per second set to: %.3f", *pix_per_sec); } if ( (mode == MODE_ANAL && set_x == 0 && set_pps == 0) || (mode == MODE_SINE_SYNTH && set_pps == 0) ) { message("%s", err_24); exit(EXIT_FAILURE); } *pix_per_sec /= *wav_rate; }
/*============================================================================*/ double ghmm_dpmodel_viterbi_logp(ghmm_dpmodel *mo, ghmm_dpseq * X, ghmm_dpseq * Y, int *state_seq, int state_seq_len) { #define CUR_PROC "ghmm_dpmodel_viterbi_logp" int s, t, i, j, u, v; double log_p = 0.0; double log_b_i = 1.0; double log_in_a = 1.0; plocal_store_t *pv; /* Allocate the matrices log_in_a, log_b,Vektor phi, phi_new, Matrix psi */ pv = pviterbi_alloc(mo, 0, 0); pviterbi_precompute(mo, pv); /* initial state */ t = 0; u = -1; v = -1; if (state_seq_len > t) { i = state_seq[t]; /* initial state probability */ /* log_p += log(mo->s[i].pi); */ log_p += mo->s[i].log_pi; if (log_p == 1.0) { pviterbi_free(&pv, mo->N, 0, 0, mo->max_offset_x, mo->max_offset_y); fprintf(stderr, "the initial probability of state %i is zero\n", i); return 1.0;/* the initial prob is zero */ } /* consume the first characters of the sequences */ u += mo->s[i].offset_x; v += mo->s[i].offset_y; /* get the emission probability */ log_b_i = log_b(pv, i, ghmm_dpmodel_pair(ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), mo->size_of_alphabet[mo->s[i].alphabet], mo->s[i].offset_x, mo->s[i].offset_y)); if (log_b_i == 1.0) { /* chars cant be emitted */ pviterbi_free(&pv, mo->N, 0, 0, mo->max_offset_x, mo->max_offset_y); fprintf(stderr, "characters (%i, %i) at position (%i, %i) cannot be emitted by state %i (t=%i)\n", ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), u, v, i, t); return 1.0; } log_p += log_b_i; } else { /* there is no path.. */ pviterbi_free(&pv, mo->N, 0, 0, mo->max_offset_x, mo->max_offset_y); fprintf(stderr, "No path given!\n"); return 1.0; } /* rest of the sequence */ for (t=1; t<state_seq_len; t++) { j = i; /* predecessor state */ i = state_seq[t]; /* current state */ /* consume the next characters */ u += mo->s[i].offset_x; v += mo->s[i].offset_y; if (u >= X->length || v >= Y->length) { /* path consumes too many chars */ pviterbi_free(&pv, mo->N, 0, 0, mo->max_offset_x, mo->max_offset_y); fprintf(stderr, "path consumes too many chars\n"); return 1.0; } /* transition prob state j -> i*/ log_in_a = 1.0; for (s=0; s<mo->s[i].in_states; s++) { if (mo->s[i].in_id[s] == j) { log_in_a = sget_log_in_a(pv, i, s, X, Y, u, v); break; } } if (log_in_a == 1.0) { pviterbi_free(&pv, mo->N, 0, 0, mo->max_offset_x, mo->max_offset_y); fprintf(stderr, "transition (%i -> %i) at t=%i not possible\n", j, i,t); return 1.0; /* transition not possible */ } /* emission probability */ log_b_i = log_b(pv, i, ghmm_dpmodel_pair(ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), mo->size_of_alphabet[mo->s[i].alphabet], mo->s[i].offset_x, mo->s[i].offset_y)); if (log_b_i == 1.0) { pviterbi_free(&pv, mo->N, 0, 0, mo->max_offset_x, mo->max_offset_y); fprintf(stderr, "characters (%i, %i) at position (%i, %i) cannot be emitted by state %i (t=%i)\n", ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), u, v, i, t); return 1.0; /* characters cant be emitted */ } log_p += log_in_a + log_b_i; } pviterbi_free(&pv, mo->N, 0, 0, mo->max_offset_x, mo->max_offset_y); /* check if all of the sequences has been consumed */ if (u != X->length - 1 && v != Y->length - 1) { fprintf(stderr, "path consumes not all characters (%i of %i, %i of %i)\n", u + 1, X->length, v + 1, Y->length); return 1.0; } return log_p; #undef CUR_PROC } /* ghmm_dpmodel_viterbi_logp */
/*============================================================================*/ static void init_phi(plocal_store_t * pv, ghmm_dpseq * X, ghmm_dpseq * Y) { #ifdef DEBUG int emission; #endif int u, v, j, i, off_x, y; double log_in_a_ij; double value, max_value, previous_prob, log_b_i; /* printf("ghmm_dpmodel_viterbi init\n"); */ ghmm_dpmodel * mo = pv->mo; double (*log_in_a)(plocal_store_t*, int, int, ghmm_dpseq*, ghmm_dpseq*, int, int); log_in_a = &sget_log_in_a; /* Initialize the lookback matrix (for positions [-offsetX,0], [0, len_y]*/ for (off_x=0; off_x<mo->max_offset_x + 1; off_x++) for (y=0; y<Y->length + mo->max_offset_y + 1; y++) for (j=0; j<mo->N; j++) { pv->phi[off_x][y][j] = +1; } if ( mo->model_type & GHMM_kSilentStates ) { /* could go into silent state at t=0 */ /*p__viterbi_silent( mo, t=0, v);*/ } /*for (j = 0; j < mo->N; j++) { printf("\npsi[%d],in:%d, phi=%f\n", t, v->psi[t][j], v->phi[j]); } for( i = 0; i < mo->N; i++){ printf("%d\t", former_matchcount[i]); } for (i = 0; i < mo->N; i++){ printf("%d\t", recent_matchcount[i]); }*/ /* initialize for offsets > 1 (u < max_offset_x, v < max_offset_y) */ /* this is in principle the same as the main recurrence but adds initial probabilities to states that cannot be inhabitated at u=0, v=0 because of greater offsets than one iteration start is u=-1 v=-1 to allow states with offset_x == 0 which corresponds to a series of gap states before reading the first character of x at position x=0, y=v or equally for offset_y == 0 */ /* u, v <= max offsets */ for (u = -1; u <= mo->max_offset_x; u++) { for (v = -mo->max_offset_y; v < Y->length; v++) { for (j = 0; j < mo->N; j++) { /** initialization of phi (lookback matrix), psi (traceback) **/ set_phi(pv, u, v, j, +1); set_psi(pv, u, v, j, -1); } /* for each state i */ for (i = 0; i < mo->N; i++) { /* Determine the maximum */ /* max_phi = phi[i] + log_in_a[j][i] ... */ if (!(mo->model_type & GHMM_kSilentStates) || !mo->silent[i] ) { max_value = -DBL_MAX; set_psi(pv, u, v, i, -1); for (j = 0; j < mo->s[i].in_states; j++) { /* look back in the phi matrix at the offsets */ previous_prob = get_phi(pv, u, v, mo->s[i].offset_x, mo->s[i].offset_y, mo->s[i].in_id[j]); log_in_a_ij = (*log_in_a)(pv, i, j, X, Y, u, v); if ( previous_prob != +1 && log_in_a_ij != +1) { value = previous_prob + log_in_a_ij; if (value > max_value) { max_value = value; set_psi(pv, u, v, i, mo->s[i].in_id[j]); } } else {;} /* fprintf(stderr, " %d --> %d = %f, \n", i,i,v->log_in_a[i][i]); */ } #ifdef DEBUG emission = ghmm_dpmodel_pair(ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), mo->size_of_alphabet[mo->s[i].alphabet], mo->s[i].offset_x, mo->s[i].offset_y); if (emission > ghmm_dpmodel_emission_table_size(mo, i)){ printf("State %i\n", i); ghmm_dpmodel_state_print(&(mo->s[i])); printf("charX: %i charY: %i alphabet size: %i emission table: %i emission index: %i\n", ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), mo->size_of_alphabet[mo->s[i].alphabet], ghmm_dpmodel_emission_table_size(mo, i), emission); } #endif log_b_i = log_b(pv, i, ghmm_dpmodel_pair(ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), mo->size_of_alphabet[mo->s[i].alphabet], mo->s[i].offset_x, mo->s[i].offset_y)); /* this is the difference from the main loop: check whether this state could be an initial state and add the initial probability */ if (log_b_i == +1 ) { set_phi(pv, u, v, i, +1); } else { if (max_value == -DBL_MAX) set_phi(pv, u, v, i, +1); else set_phi(pv, u, v, i, max_value); /* if (mo->s[i].pi != 0 && mo->s[i].offset_x - 1 == u && mo->s[i].offset_y - 1 == v) { */ if (mo->s[i].log_pi != 1 && mo->s[i].offset_x - 1 == u && mo->s[i].offset_y - 1 == v) { set_phi(pv, u, v, i, mo->s[i].log_pi); #ifdef DEBUG printf("Initial log prob state %i at (%i, %i) = %f\n", i, u, v, get_phi(pv, u, v, 0, 0, i)); printf("Characters emitted X: %i, Y: %i\n", ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v)); #endif } if (get_phi(pv, u, v, 0, 0, i) != 1) set_phi(pv, u, v, i, get_phi(pv, u, v, 0, 0, i) + log_b_i); } } /* if (v == 0) { printf"(%i, %i, %i) preceding %i\n", u, v, i, pv->psi[u][v][i]); } */ } /* complete time step for emitting states */ /* last_osc = osc; */ /* save last transition class */ /*if (mo->model_type & kSilentStates) { p__viterbi_silent( mo, t, v ); }*/ /* complete time step for silent states */ /************** for (j = 0; j < mo->N; j++) { printf("\npsi[%d],in:%d, phi=%f\n", t, v->psi[t][j], v->phi[j]); } for (i = 0; i < mo->N; i++){ printf("%d\t", former_matchcount[i]); } for (i = 0; i < mo->N; i++){ printf("%d\t", recent_matchcount[i]); } ****************/ } /* End for v in Y */ /* Next character in X */ /* push back the old phi values */ push_back_phi(pv, Y->length); } /* End for u in X */ }
/*============================================================================*/ int *ghmm_dpmodel_viterbi_variable_tb(ghmm_dpmodel *mo, ghmm_dpseq * X, ghmm_dpseq * Y, double *log_p, int *path_length, int start_traceback_with) { #define CUR_PROC "ghmm_dpmodel_viterbi" int u, v, j, i, off_x, off_y, current_state_index; double value, max_value, previous_prob; plocal_store_t *pv; int *state_seq = NULL; int emission; double log_b_i, log_in_a_ij; double (*log_in_a)(plocal_store_t*, int, int, ghmm_dpseq*, ghmm_dpseq*, int, int); /* printf("---- viterbi -----\n"); */ i_list * state_list; state_list = ighmm_list_init_list(); log_in_a = &sget_log_in_a; /* int len_path = mo->N*len; the length of the path is not known apriori */ /* if (mo->model_type & kSilentStates && */ /* mo->silent != NULL && */ /* mo->topo_order == NULL) { */ /* ghmm_dmodel_topo_order( mo ); */ /* } */ /* Allocate the matrices log_in_a, log_b,Vektor phi, phi_new, Matrix psi */ pv = pviterbi_alloc(mo, X->length, Y->length); if (!pv) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } /* Precomputing the log(a_ij) and log(bj(ot)) */ pviterbi_precompute(mo, pv); /* Initialize the lookback matrix (for positions [-offsetX,0], [-1, len_y]*/ init_phi(pv, X, Y); /* u > max_offset_x , v starts -1 to allow states with offset_x == 0 which corresponds to a series of gap states before reading the first character of x at position x=0, y=v */ /** THIS IS THE MAIN RECURRENCE **/ for (u = mo->max_offset_x + 1; u < X->length; u++) { for (v = -mo->max_offset_y; v < Y->length; v++) { for (j = 0; j < mo->N; j++) { /** initialization of phi (lookback matrix), psi (traceback) **/ set_phi(pv, u, v, j, +1); set_psi(pv, u, v, j, -1); } for (i = 0; i < mo->N; i++) { /* Determine the maximum */ /* max_phi = phi[i] + log_in_a[j][i] ... */ if (!(mo->model_type & GHMM_kSilentStates) || !mo->silent[i] ) { max_value = -DBL_MAX; set_psi(pv, u, v, i, -1); for (j = 0; j < mo->s[i].in_states; j++) { /* look back in the phi matrix at the offsets */ previous_prob = get_phi(pv, u, v, mo->s[i].offset_x, mo->s[i].offset_y, mo->s[i].in_id[j]); log_in_a_ij = (*log_in_a)(pv, i, j, X, Y, u, v); if ( previous_prob != +1 && log_in_a_ij != +1) { value = previous_prob + log_in_a_ij; if (value > max_value) { max_value = value; set_psi(pv, u, v, i, mo->s[i].in_id[j]); } } else {;} /* fprintf(stderr, " %d --> %d = %f, \n", i,i,v->log_in_a[i][i]); */ } emission = ghmm_dpmodel_pair(ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), mo->size_of_alphabet[mo->s[i].alphabet], mo->s[i].offset_x, mo->s[i].offset_y); #ifdef DEBUG if (emission > ghmm_dpmodel_emission_table_size(mo, i)){ printf("State %i\n", i); ghmm_dpmodel_state_print(&(mo->s[i])); printf("charX: %i charY: %i alphabet size: %i emission table: %i emission index: %i\n", ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), mo->size_of_alphabet[mo->s[i].alphabet], ghmm_dpmodel_emission_table_size(mo, i), emission); } #endif log_b_i = log_b(pv, i, ghmm_dpmodel_pair(ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), mo->size_of_alphabet[mo->s[i].alphabet], mo->s[i].offset_x, mo->s[i].offset_y)); /* No maximum found (that is, state never reached) or the output O[t] = 0.0: */ if (max_value == -DBL_MAX ||/* and then also: (v->psi[t][j] == -1) */ log_b_i == +1 ) { set_phi(pv, u, v, i, +1); } else set_phi(pv, u, v, i, max_value + log_b_i); } } /* complete time step for emitting states */ /* last_osc = osc; */ /* save last transition class */ /*if (mo->model_type & kSilentStates) { p__viterbi_silent( mo, t, v ); }*/ /* complete time step for silent states */ /************** for (j = 0; j < mo->N; j++) { printf("\npsi[%d],in:%d, phi=%f\n", t, v->psi[t][j], v->phi[j]); } for (i = 0; i < mo->N; i++){ printf("%d\t", former_matchcount[i]); } for (i = 0; i < mo->N; i++){ printf("%d\t", recent_matchcount[i]); } ****************/ } /* End for v in Y */ /* Next character in X */ push_back_phi(pv, Y->length); } /* End for u in X */ /* Termination */ max_value = -DBL_MAX; ighmm_list_append(state_list, -1); /* if start_traceback_with is -1 (it is by default) search for the most likely state at the end of both sequences */ if (start_traceback_with == -1) { for (j = 0; j < mo->N; j++){ #ifdef DEBUG printf("phi(len_x)(len_y)(%i)=%f\n", j, get_phi(pv, u, Y->length-1, 0, 0, j)); #endif if ( get_phi(pv, u, Y->length-1, 0, 0, j) != +1 && get_phi(pv, u, Y->length-1, 0, 0, j) > max_value) { max_value = get_phi(pv, X->length-1, Y->length-1, 0, 0, j); state_list->last->val = j; } } } /* this is the special traceback mode for the d & c algorithm that also connects the traceback to the first state of the rest of the path */ else { #ifdef DEBUG printf("D & C traceback from state %i!\n", start_traceback_with); printf("Last characters emitted X: %i, Y: %i\n", ghmm_dpseq_get_char(X, mo->s[start_traceback_with].alphabet, X->length-1), ghmm_dpseq_get_char(Y, mo->s[start_traceback_with].alphabet, Y->length-1)); for (j = 0; j < mo->N; j++){ printf("phi(len_x)(len_y)(%i)=%f\n", j, get_phi(pv, X->length-1, Y->length-1, 0, 0, j)); } #endif max_value = get_phi(pv, X->length-1, Y->length-1, 0, 0, start_traceback_with); if (max_value != 1 && max_value > -DBL_MAX) state_list->last->val = start_traceback_with; } if (max_value == -DBL_MAX) { /* Sequence can't be generated from the model! */ *log_p = +1; /* Backtracing doesn't work, because state_seq[*] allocated with -1 */ /* for (t = len - 2; t >= 0; t--) state_list->last->val = -1; */ } else { /* Backtracing, should put DEL path nicely */ *log_p = max_value; /* removed the handling of silent states here */ /* start trace back at the end of both sequences */ u = X->length - 1; v = Y->length - 1; current_state_index = state_list->first->val; off_x = mo->s[current_state_index].offset_x; off_y = mo->s[current_state_index].offset_y; while (u - off_x >= -1 && v - off_y >= -1 && current_state_index != -1) { /* while (u > 0 && v > 0) { */ /* look up the preceding state and save it in the first position of the state list */ /* printf("Current state %i at (%i,%i) -> preceding state %i\n", current_state_index, u, v, get_psi(pv, u, v, current_state_index)); */ /* update the current state */ current_state_index = get_psi(pv, u, v, current_state_index); if (current_state_index != -1) ighmm_list_insert(state_list, current_state_index); /* move in the alignment matrix */ u -= off_x; v -= off_y; /* get the next offsets */ off_x = mo->s[current_state_index].offset_x; off_y = mo->s[current_state_index].offset_y; } } /* Free the memory space */ pviterbi_free(&pv, mo->N, X->length, Y->length, mo->max_offset_x , mo->max_offset_y); /* printf("After traceback: last state = %i\n", state_list->last->val); */ state_seq = ighmm_list_to_array(state_list); *path_length = state_list->length; /* PRINT PATH */ /* fprintf(stderr, "Viterbi path: " ); */ /* int t; */ /* for(t=0; t < *path_length; t++) */ /* if (state_seq[t] >= 0) fprintf(stderr, " %d ", state_seq[t]); */ /* fprintf(stderr, "\n Freeing ... \n"); */ return (state_seq); STOP: /* Label STOP from ARRAY_[CM]ALLOC */ /* Free the memory space */ pviterbi_free(&pv, mo->N, X->length, Y->length, mo->max_offset_x, mo->max_offset_y); m_free(state_seq); ighmm_list_free(state_list); return NULL; #undef CUR_PROC } /* viterbi */
void settingsinput(int32_t *bands, int32_t samplecount, int32_t *samplerate, double *basefreq, double maxfreq, double *pixpersec, double *bandsperoctave, int32_t Xsize, int32_t mode) { /* mode : * 0 = Analysis mode * 1 = Synthesis mode */ int32_t i; double gf, f, trash; double ma; // maximum allowed frequency FILE *freqcfg; char byte; int32_t unset=0, set_min=0, set_max=0, set_bpo=0, set_y=0; // count of unset interdependant settings int32_t set_pps=0, set_x=0; size_t filesize; // boolean indicating if the configuration file's last expected byte is there (to verify the file's integrity) char conf_path[FILENAME_MAX]; // Path to the configuration file (only used on non-Windows platforms) #ifdef DEBUG printf("settingsinput...\n"); #endif #ifdef WIN32 freqcfg=fopen("arss.conf", "rb"); // open saved settings file #else sprintf(conf_path, "%s/%s", getenv("HOME"), ".arss.conf"); freqcfg=fopen(conf_path, "rb"); #endif if (*samplerate==0) // if we're in synthesis mode and that no samplerate has been defined yet { if (quiet==1) { fprintf(stderr, "Please provide a sample rate for your output sound.\nUse --sample-rate (-r).\nExiting with error.\n"); exit(EXIT_FAILURE); } //********Output settings querying******** printf("Sample rate [44100] : "); // Query for a samplerate *samplerate=getfloat(); if (*samplerate==0 || *samplerate<-2147483647) // The -2147483647 check is used for the sake of compatibility with C90 *samplerate = 44100; // Default value //--------Output settings querying-------- } if (*basefreq!=0) set_min=1; // count unset interdependant frequency-domain settings if (maxfreq!=0) set_max=1; if (*bandsperoctave!=0) set_bpo=1; if (*bands!=0) set_y=1; unset = set_min + set_max + set_bpo + set_y; if (unset==4) // if too many settings are set { if (mode==0) fprintf(stderr, "You have set one parameter too many.\nUnset either --min-freq (-min), --max-freq (-max), --bpo (-b)\nExiting with error.\n"); if (mode==1) fprintf(stderr, "You have set one parameter too many.\nUnset either --min-freq (-min), --max-freq (-max), --bpo (-b) or --height (-y)\nExiting with error.\n"); exit(EXIT_FAILURE); } if (*pixpersec!=0) set_pps=1; if (Xsize!=0) set_x=1; if (set_x+set_pps==2 && mode==0) { fprintf(stderr, "You cannot define both the image width and the horizontal resolution.\nUnset either --pps (-p) or --width (-x)\nExiting with error.\n"); exit(EXIT_FAILURE); } if (freqcfg) // load settings from file if it exists { for (i=0; i<(int32_t) (4*sizeof(double)); i++) filesize=fread(&byte, sizeof(char), 1, freqcfg); // verify the file's length rewind(freqcfg); } if (filesize==1) // if the file is at least as long as expected { if (*basefreq==0) fread(basefreq, sizeof(double), 1, freqcfg); // load values from it if they haven't been set yet else fread(&trash, sizeof(double), 1, freqcfg); if (maxfreq==0) fread(&maxfreq, sizeof(double), 1, freqcfg); // unless we have enough of them (unset==3) else fread(&trash, sizeof(double), 1, freqcfg); if (*bandsperoctave==0) fread(bandsperoctave, sizeof(double), 1, freqcfg); else fread(&trash, sizeof(double), 1, freqcfg); if (*pixpersec==0) fread(pixpersec, sizeof(double), 1, freqcfg); else fread(&trash, sizeof(double), 1, freqcfg); } else { if (*basefreq==0) *basefreq=27.5; // otherwise load default values if (maxfreq==0) maxfreq=20000; if (*bandsperoctave==0) *bandsperoctave=12; if (*pixpersec==0) *pixpersec=150; } if (freqcfg) fclose(freqcfg); if (unset<3 && set_min==0) { if (quiet==1) { fprintf(stderr, "Please define a minimum frequency.\nUse --min-freq (-min).\nExiting with error.\n"); exit(EXIT_FAILURE); } printf("Min. frequency (Hz) [%.3f]: ", *basefreq); gf=getfloat(); if (gf != 0) *basefreq=gf; unset++; set_min=1; } *basefreq /= *samplerate; // turn basefreq from Hz to fractions of samplerate if (unset<3 && set_bpo==0) { if (quiet==1) { fprintf(stderr, "Please define a bands per octave setting.\nUse --bpo (-b).\nExiting with error.\n"); exit(EXIT_FAILURE); } printf("Bands per octave [%.3f]: ", *bandsperoctave); gf=getfloat(); if (gf != 0) *bandsperoctave=gf; unset++; set_bpo=1; } if (unset<3 && set_max==0) { i=0; do { i++; f=*basefreq * pow(LOGBASE, (i / *bandsperoctave)); } while (f<0.5); ma=*basefreq * pow(LOGBASE, ((i-2) / *bandsperoctave)) * *samplerate; // max allowed frequency if (maxfreq > ma) if (myfmod(ma, 1.0) == 0.0) maxfreq = ma; // replaces the "Upper frequency limit above Nyquist frequency" warning else maxfreq = ma - myfmod(ma, 1.0); if (mode==0) // if we're in Analysis mode { if (quiet==1) { fprintf(stderr, "Please define a maximum frequency.\nUse --max-freq (-max).\nExiting with error.\n"); exit(EXIT_FAILURE); } printf("Max. frequency (Hz) (up to %.3f) [%.3f]: ", ma, maxfreq); gf=getfloat(); if (gf != 0) maxfreq=gf; if (maxfreq > ma) if (myfmod(ma, 1.0) == 0.0) maxfreq = ma; // replaces the "Upper frequency limit above Nyquist frequency" warning else maxfreq = ma - myfmod(ma, 1.0); } unset++; set_max=1; } if (set_min==0) { *basefreq = pow(LOGBASE, (*bands-1) / *bandsperoctave) * maxfreq; // calculate the lower frequency in Hz printf("Min. frequency : %.3f Hz\n", *basefreq); *basefreq /= *samplerate; } if (set_max==0) { maxfreq = pow(LOGBASE, (*bands-1) / *bandsperoctave) * (*basefreq * *samplerate); // calculate the upper frequency in Hz printf("Max. frequency : %.3f Hz\n", maxfreq); } if (set_y==0) { *bands = 1 + roundoff(*bandsperoctave * (log_b(maxfreq) - log_b(*basefreq * *samplerate))); printf("Bands : %d\n", *bands); } if (set_bpo==0) { if (LOGBASE==1.0) *bandsperoctave = maxfreq / *samplerate; else *bandsperoctave = (*bands-1) / (log_b(maxfreq) - log_b(*basefreq * *samplerate)); printf("Bands per octave : %.3f\n", *bandsperoctave); } if (set_x==1 && mode==0) // If we're in Analysis mode and that X is set (by the user) { *pixpersec = (double) Xsize * (double) *samplerate / (double) samplecount; // calculate pixpersec printf("Pixels per second : %.3f\n", *pixpersec); } if ((mode==0 && set_x==0 && set_pps==0) || (mode==1 && set_pps==0)) // If in Analysis mode none are set or pixpersec isn't set in Synthesis mode { if (quiet==1) { fprintf(stderr, "Please define a pixels per second setting.\nUse --pps (-p).\nExiting with error.\n"); exit(EXIT_FAILURE); } printf("Pixels per second [%.3f]: ", *pixpersec); gf=getfloat(); if (gf != 0) *pixpersec=gf; } *basefreq *= *samplerate; // turn back to Hz just for the sake of writing to the file #ifdef WIN32 freqcfg=fopen("arss.conf", "wb"); // saving settings to a file #else freqcfg=fopen(conf_path, "wb"); // saving settings to a file #endif if (freqcfg==NULL) { fprintf(stderr, "Cannot write to configuration file"); exit(EXIT_FAILURE); } fwrite(basefreq, sizeof(double), 1, freqcfg); fwrite(&maxfreq, sizeof(double), 1, freqcfg); fwrite(bandsperoctave, sizeof(double), 1, freqcfg); fwrite(pixpersec, sizeof(double), 1, freqcfg); fclose(freqcfg); *basefreq /= *samplerate; // basefreq is now in fraction of the sampling rate instead of Hz *pixpersec /= *samplerate; // pixpersec is now in fraction of the sampling rate instead of Hz }