static unsigned long opt_k(const double fp) { return lrint(-log(fp) / LOG2); }
void Rest::layout() { rxpos() = 0.0; if (staff() && staff()->isTabStaff()) { StaffTypeTablature* tab = (StaffTypeTablature*)staff()->staffType(); // if rests are shown and note values are shown as duration symbols if(tab->showRests() &&tab->genDurations()) { // symbol needed; if not exist, create, if exists, update duration if (!_tabDur) _tabDur = new TabDurationSymbol(score(), tab, durationType().type(), dots()); else _tabDur->setDuration(durationType().type(), dots(), tab); _tabDur->setParent(this); // needed? _tabDur->setTrack(track()); _tabDur->layout(); setbbox(_tabDur->bbox()); setPos(0.0, 0.0); // no rest is drawn: reset any position might be set for it _space.setLw(0.0); _space.setRw(width()); return; } // if no rests or no duration symbols, delete any dur. symbol and chain into standard staff mngmt // this is to ensure horiz space is reserved for rest, even if they are not diplayed // Rest::draw() will skip their drawing, if not needed if(_tabDur) { delete _tabDur; _tabDur = 0; } } switch(durationType().type()) { case TDuration::V_64TH: case TDuration::V_32ND: dotline = -3; break; case TDuration::V_256TH: case TDuration::V_128TH: dotline = -5; break; default: dotline = -1; break; } qreal _spatium = spatium(); int stepOffset = 0; if (staff()) stepOffset = staff()->staffType()->stepOffset(); int line = lrint(userOff().y() / _spatium); // + ((staff()->lines()-1) * 2); qreal lineDist = staff() ? staff()->staffType()->lineDistance().val() : 1.0; int lineOffset = 0; int lines = staff() ? staff()->lines() : 5; if (segment() && measure() && measure()->mstaff(staffIdx())->hasVoices) { // move rests in a multi voice context bool up = (voice() == 0) || (voice() == 2); // TODO: use style values switch(durationType().type()) { case TDuration::V_LONG: lineOffset = up ? -3 : 5; break; case TDuration::V_BREVE: lineOffset = up ? -3 : 5; break; case TDuration::V_MEASURE: if (duration() >= Fraction(2, 1)) // breve symbol lineOffset = up ? -3 : 5; // fall through case TDuration::V_WHOLE: lineOffset = up ? -4 : 6; break; case TDuration::V_HALF: lineOffset = up ? -4 : 4; break; case TDuration::V_QUARTER: lineOffset = up ? -4 : 4; break; case TDuration::V_EIGHT: lineOffset = up ? -4 : 4; break; case TDuration::V_16TH: lineOffset = up ? -6 : 4; break; case TDuration::V_32ND: lineOffset = up ? -6 : 6; break; case TDuration::V_64TH: lineOffset = up ? -8 : 6; break; case TDuration::V_128TH: lineOffset = up ? -8 : 8; break; case TDuration::V_256TH: // not available lineOffset = up ? -10 : 6; break; default: break; } } else { switch(durationType().type()) { case TDuration::V_LONG: case TDuration::V_BREVE: case TDuration::V_MEASURE: case TDuration::V_WHOLE: if (lines == 1) lineOffset = -2; break; case TDuration::V_HALF: case TDuration::V_QUARTER: case TDuration::V_EIGHT: case TDuration::V_16TH: case TDuration::V_32ND: case TDuration::V_64TH: case TDuration::V_128TH: case TDuration::V_256TH: // not available if (lines == 1) lineOffset = -4; break; default: break; } } int yo; _sym = getSymbol(durationType().type(), line + lineOffset/2, lines, &yo); layoutArticulations(); rypos() = (qreal(yo) + qreal(lineOffset + stepOffset) * .5) * lineDist * _spatium; Spatium rs; if (dots()) { rs = Spatium(score()->styleS(ST_dotNoteDistance) + dots() * score()->styleS(ST_dotDotDistance)); } Segment* s = segment(); if (s && s->measure() && s->measure()->multiMeasure()) { qreal _spatium = spatium(); qreal h = _spatium * 6.5; qreal w = point(score()->styleS(ST_minMMRestWidth)); bbox().setRect(-w * .5, -h + 2 * _spatium, w, h); } else { if (dots()) { rs = Spatium(score()->styleS(ST_dotNoteDistance) + dots() * score()->styleS(ST_dotDotDistance)); } setbbox(symbols[score()->symIdx()][_sym].bbox(magS())); } _space.setLw(0.0); _space.setRw(width() + point(rs)); }
int y2pitch(qreal y, ClefType clef, qreal _spatium) { int l = lrint(y / _spatium * 2.0); return line2pitch(l, clef, Key::C); }
static int rate_from_speed(int rate, double speed) { return lrint(rate * speed); }
int blitPreviews(experiment *experiments, unsigned int runs) { // Viewport variables const unsigned int viewport_w = 340; const unsigned int viewport_h = 255; const float sequence_length = 58.0f + (2.0f / 11.0f); // Viewport data typedef struct viewport_data_t { SDL_Rect viewport; unsigned int tile; unsigned int tiles; unsigned int seg; float cumulative_error; float tile_error; unsigned int field; unsigned int base_fields; unsigned int cur_fields; } viewport_data; viewport_data *viewports; viewports = malloc(runs * sizeof(viewport_data) ); if (!viewports) { fprintf(stderr, "Error allocating memory for viewport data.\n"); return 1; } if (runs > 6) { fprintf(stderr, "Non-fatal: Cannot display more than six runs! Truncating output to six screens.\n"); runs = 5; // starting from zero } for (int i = 0; i < runs; i++) { // Viewport dimensions viewports[i].viewport.w = viewport_w; viewports[i].viewport.h = viewport_h; switch (i) { case 0: viewports[i].viewport.x = 1; viewports[i].viewport.y = 1; break; case 1: viewports[i].viewport.x = 342; viewports[i].viewport.y = 1; break; case 2: viewports[i].viewport.x = 683; viewports[i].viewport.y = 1; break; case 3: viewports[i].viewport.x = 1; viewports[i].viewport.y = 512; break; case 4: viewports[i].viewport.x = 342; viewports[i].viewport.y = 512; break; case 5: viewports[i].viewport.x = 683; viewports[i].viewport.y = 512; break; } // Viewport tiles and scaling viewports[i].tile = 0; // start at the beginning viewports[i].tiles = experiments[i].seg * experiments[i].seg * 15; viewports[i].seg = experiments[i].seg; // Viewport tile jitter viewports[i].cumulative_error = 0.0f; viewports[i].tile_error = fmod((60.0f * sequence_length) / viewports[i].tiles, 1.0f); viewports[i].field = 0; // beginning again viewports[i].base_fields = (unsigned int) lrint(floor( ((60.0f * sequence_length) / viewports[i].tiles) ) ); viewports[i].cur_fields = viewports[i].base_fields; } // Display variables SDL_Surface *display; display = SDL_GetVideoSurface(); const SDL_Rect preview_size = { 0, 0, viewport_w, viewport_h }; const int target_fps = 60; SDL_Event event_handler; int terminate = 0; int ticks_then = -1; int ticks_now = 0; int field = 0; int delay = 1000 / target_fps; // Create previews SDL_Thread *create_previews; int create_previews_return; float progress = 0; create_previews_args create_previews_arg = { experiments, runs, preview_size, &progress }; create_previews = SDL_CreateThread((int (*)(void *))createPreviews, &create_previews_arg); if (create_previews == NULL) { fprintf(stderr, "SDL: Unable to create preview tile creation thread: %s\n", SDL_GetError() ); return 1; } displayCountdownScreen(&progress); SDL_WaitThread(create_previews, &create_previews_return); if (create_previews_return != 0) { fprintf(stderr, "SDL: Preview tile creation thread failed.\n"); return 1; } // Questions display const char *question_1_image_filename = "../Resources/question1.png"; const char *question_2_image_filename = "../Resources/question2.png"; SDL_Surface *question_1_image, *question_2_image; question_1_image = loadImage(question_1_image_filename); question_2_image = loadImage(question_2_image_filename); SDL_Rect question_image_location; question_image_location.w = 1022; question_image_location.h = 254; question_image_location.x = 1; question_image_location.y = 257; int question_image_fade = 0; const Uint8 question_image_fade_increment = 8; enum question_state_machine { q1_fadein, q1_static, q1_fadeout, q2_fadein, q2_static, q2_fadeout } question_state = q1_fadein; int question_keypress = 0; // Display routine while (!terminate) { // Handle events while (SDL_PollEvent(&event_handler) ) { switch (event_handler.type) { case SDL_KEYDOWN: question_keypress = 1; break; case SDL_QUIT: // should probably clean-up... exit(0); break; default: break; } // switch event_handler } // while SDL_PollEvent // State machine switch (question_state) { case q1_fadein: question_image_fade += question_image_fade_increment; if (question_image_fade >= 255) { question_image_fade = 255; question_state = q1_static; } break; case q1_static: if (question_keypress) { question_keypress = 0; question_state = q1_fadeout; } break; case q1_fadeout: question_image_fade -= question_image_fade_increment; if (question_image_fade <= 0) { question_image_fade = 0; question_state = q2_fadein; } break; case q2_fadein: question_image_fade += question_image_fade_increment; if (question_image_fade >= 255) { question_image_fade = 255; question_state = q2_static; } break; case q2_static: if (question_keypress) { question_keypress = 0; question_state = q2_fadeout; } break; case q2_fadeout: question_image_fade -= question_image_fade_increment; if (question_image_fade <= 0) { question_image_fade = 0; terminate = 1; } break; default: printf("Invalid state for blitPreviews.\n"); break; } // switch question_state // Calculations for (int i = 0; i < runs; i++) { // Field updating viewports[i].field++; if (viewports[i].field == viewports[i].cur_fields) { // Reset tile viewports[i].field = 0; viewports[i].tile++; // Check we haven't gone beyond our bounds if (viewports[i].tile == viewports[i].tiles) { viewports[i].tile = 0; } // Calculate tile display duration viewports[i].cumulative_error += viewports[i].tile_error; if (viewports[i].cumulative_error >= 1.0f) { // Standard duration frame viewports[i].cur_fields = viewports[i].base_fields; viewports[i].cumulative_error -= 1.0f; } else { // Extended duration frame viewports[i].cur_fields = viewports[i].base_fields + 1; } } } // Rendering SDL_FillRect(display, NULL, SDL_MapRGB(display->format, 0, 0, 0) ); // clear with black for (int i = 0; i < runs; i++) { SDL_BlitSurface(previews[i][viewports[i].tile], NULL, display, &viewports[i].viewport); } // Question display switch (question_state) { case q1_fadein: case q1_static: case q1_fadeout: SDL_SetAlpha(question_1_image, SDL_RLEACCEL | SDL_SRCALPHA, question_image_fade); SDL_BlitSurface(question_1_image, NULL, display, &question_image_location); break; case q2_fadein: case q2_static: case q2_fadeout: SDL_SetAlpha(question_2_image, SDL_RLEACCEL | SDL_SRCALPHA, question_image_fade); SDL_BlitSurface(question_2_image, NULL, display, &question_image_location); break; } // switch question_state // Flipping SDL_Flip(display); // Delay calculation if (ticks_then > 0) { ticks_now = SDL_GetTicks(); delay += (1000 / target_fps - (ticks_now - ticks_then) ); // adjust delay ticks_then = ticks_now; if (delay < 0) delay = 1000 / target_fps; // reset delay } else { ticks_then = SDL_GetTicks(); } field++; SDL_Delay(delay); } // while !terminate // Clean-up destroyImage(question_1_image); destroyImage(question_2_image); free(viewports); return 0; }
storage_number pack_storage_number(calculated_number value, uint32_t flags) { // bit 32 = sign 0:positive, 1:negative // bit 31 = 0:divide, 1:multiply // bit 30, 29, 28 = (multiplier or divider) 0-6 (7 total) // bit 27, 26, 25 flags // bit 24 to bit 1 = the value storage_number r = get_storage_number_flags(flags); if(!value) return r; int m = 0; calculated_number n = value; // if the value is negative // add the sign bit and make it positive if(n < 0) { r += (1 << 31); // the sign bit 32 n = -n; } // make its integer part fit in 0x00ffffff // by dividing it by 10 up to 7 times // and increasing the multiplier while(m < 7 && n > (calculated_number)0x00ffffff) { n /= 10; m++; } if(m) { // the value was too big and we divided it // so we add a multiplier to unpack it r += (1 << 30) + (m << 27); // the multiplier m if(n > (calculated_number)0x00ffffff) { error("Number " CALCULATED_NUMBER_FORMAT " is too big.", value); r += 0x00ffffff; return r; } } else { // 0x0019999e is the number that can be multiplied // by 10 to give 0x00ffffff // while the value is below 0x0019999e we can // multiply it by 10, up to 7 times, increasing // the multiplier while(m < 7 && n < (calculated_number)0x0019999e) { n *= 10; m++; } // the value was small enough and we multiplied it // so we add a divider to unpack it r += (0 << 30) + (m << 27); // the divider m } #ifdef STORAGE_WITH_MATH // without this there are rounding problems // example: 0.9 becomes 0.89 r += lrint((double) n); #else r += (storage_number)n; #endif return r; }
void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { //fill ringbuffer for (int i = 0; i < p_frame_count; i++) { audio_buffer.write[(buffer_pos + i) & buffer_mask] = p_src_frames[i]; p_dst_frames[i] = p_src_frames[i] * base->dry; } float mix_rate = AudioServer::get_singleton()->get_mix_rate(); /* process voices */ for (int vc = 0; vc < base->voice_count; vc++) { AudioEffectChorus::Voice &v = base->voice[vc]; double time_to_mix = (float)p_frame_count / mix_rate; double cycles_to_mix = time_to_mix * v.rate; unsigned int local_rb_pos = buffer_pos; AudioFrame *dst_buff = p_dst_frames; AudioFrame *rb_buff = audio_buffer.ptrw(); double delay_msec = v.delay; unsigned int delay_frames = Math::fast_ftoi((delay_msec / 1000.0) * mix_rate); float max_depth_frames = (v.depth / 1000.0) * mix_rate; uint64_t local_cycles = cycles[vc]; uint64_t increment = llrint(cycles_to_mix / (double)p_frame_count * (double)(1 << AudioEffectChorus::CYCLES_FRAC)); //check the LFO doesn't read ahead of the write pos if ((((unsigned int)max_depth_frames) + 10) > delay_frames) { //10 as some threshold to avoid precision stuff delay_frames += (int)max_depth_frames - delay_frames; delay_frames += 10; //threshold to avoid precision stuff } //low pass filter if (v.cutoff == 0) continue; float auxlp = expf(-2.0 * Math_PI * v.cutoff / mix_rate); float c1 = 1.0 - auxlp; float c2 = auxlp; AudioFrame h = filter_h[vc]; if (v.cutoff >= AudioEffectChorus::MS_CUTOFF_MAX) { c1 = 1.0; c2 = 0.0; } //vol modifier AudioFrame vol_modifier = AudioFrame(base->wet, base->wet) * Math::db2linear(v.level); vol_modifier.l *= CLAMP(1.0 - v.pan, 0, 1); vol_modifier.r *= CLAMP(1.0 + v.pan, 0, 1); for (int i = 0; i < p_frame_count; i++) { /** COMPUTE WAVEFORM **/ float phase = (float)(local_cycles & AudioEffectChorus::CYCLES_MASK) / (float)(1 << AudioEffectChorus::CYCLES_FRAC); float wave_delay = sinf(phase * 2.0 * Math_PI) * max_depth_frames; int wave_delay_frames = lrint(floor(wave_delay)); float wave_delay_frac = wave_delay - (float)wave_delay_frames; /** COMPUTE RINGBUFFER POS**/ unsigned int rb_source = local_rb_pos; rb_source -= delay_frames; rb_source -= wave_delay_frames; /** READ FROM RINGBUFFER, LINEARLY INTERPOLATE */ AudioFrame val = rb_buff[rb_source & buffer_mask]; AudioFrame val_next = rb_buff[(rb_source - 1) & buffer_mask]; val += (val_next - val) * wave_delay_frac; val = val * c1 + h * c2; h = val; /** MIX VALUE TO OUTPUT **/ dst_buff[i] += val * vol_modifier; local_cycles += increment; local_rb_pos++; } filter_h[vc] = h; cycles[vc] += Math::fast_ftoi(cycles_to_mix * (double)(1 << AudioEffectChorus::CYCLES_FRAC)); } buffer_pos += p_frame_count; }
void Rest::layout() { if (staff() && staff()->isTabStaff()) { // no rests for tablature _space.setLw(0.0); _space.setRw(0.0); return; } switch(durationType().type()) { case TDuration::V_64TH: case TDuration::V_32ND: dotline = -3; break; case TDuration::V_256TH: case TDuration::V_128TH: dotline = -5; break; default: dotline = -1; break; } qreal _spatium = spatium(); int stepOffset = 0; if (staff()) stepOffset = staff()->staffType()->stepOffset(); int line = lrint(userOff().y() / _spatium); // + ((staff()->lines()-1) * 2); int lineOffset = 0; int lines = staff() ? staff()->lines() : 5; if (segment() && measure() && measure()->mstaff(staffIdx())->hasVoices) { // move rests in a multi voice context bool up = (voice() == 0) || (voice() == 2); // TODO: use style values switch(durationType().type()) { case TDuration::V_LONG: lineOffset = up ? -3 : 5; break; case TDuration::V_BREVE: lineOffset = up ? -3 : 5; break; case TDuration::V_MEASURE: if (duration() >= Fraction(2, 1)) // breve symbol lineOffset = up ? -3 : 5; // fall through case TDuration::V_WHOLE: lineOffset = up ? -4 : 6; break; case TDuration::V_HALF: lineOffset = up ? -4 : 4; break; case TDuration::V_QUARTER: lineOffset = up ? -4 : 4; break; case TDuration::V_EIGHT: lineOffset = up ? -4 : 4; break; case TDuration::V_16TH: lineOffset = up ? -6 : 4; break; case TDuration::V_32ND: lineOffset = up ? -6 : 6; break; case TDuration::V_64TH: lineOffset = up ? -8 : 6; break; case TDuration::V_128TH: lineOffset = up ? -8 : 8; break; case TDuration::V_256TH: // not available lineOffset = up ? -10 : 6; break; default: break; } } else { switch(durationType().type()) { case TDuration::V_LONG: case TDuration::V_BREVE: case TDuration::V_MEASURE: case TDuration::V_WHOLE: if (lines == 1) lineOffset = -2; break; case TDuration::V_HALF: case TDuration::V_QUARTER: case TDuration::V_EIGHT: case TDuration::V_16TH: case TDuration::V_32ND: case TDuration::V_64TH: case TDuration::V_128TH: case TDuration::V_256TH: // not available if (lines == 1) lineOffset = -4; break; default: break; } } int yo; _sym = getSymbol(durationType().type(), line + lineOffset/2, lines, &yo); layoutArticulations(); rypos() = (qreal(yo) + qreal(lineOffset + stepOffset) * .5) * _spatium; Spatium rs; if (dots()) { rs = Spatium(score()->styleS(ST_dotNoteDistance) + dots() * score()->styleS(ST_dotDotDistance)); } Segment* s = segment(); if (s && s->measure() && s->measure()->multiMeasure()) { qreal _spatium = spatium(); qreal h = _spatium * 6.5; qreal w = point(score()->styleS(ST_minMMRestWidth)); setbbox(QRectF(-w * .5, -h + 2 * _spatium, w, h)); } else { if (dots()) { rs = Spatium(score()->styleS(ST_dotNoteDistance) + dots() * score()->styleS(ST_dotDotDistance)); } setbbox(symbols[score()->symIdx()][_sym].bbox(magS())); } _space.setLw(0.0); _space.setRw(width() + point(rs)); }
static int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], int total_gain) { int v, bsize, ch, coef_nb_bits, parse_exponents; float mdct_norm; int nb_coefs[MAX_CHANNELS]; static const int fixed_exp[25] = { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 }; // FIXME remove duplication relative to decoder if (s->use_variable_block_len) { av_assert0(0); // FIXME not implemented } else { /* fixed block len */ s->next_block_len_bits = s->frame_len_bits; s->prev_block_len_bits = s->frame_len_bits; s->block_len_bits = s->frame_len_bits; } s->block_len = 1 << s->block_len_bits; // av_assert0((s->block_pos + s->block_len) <= s->frame_len); bsize = s->frame_len_bits - s->block_len_bits; // FIXME factor v = s->coefs_end[bsize] - s->coefs_start; for (ch = 0; ch < s->avctx->channels; ch++) nb_coefs[ch] = v; { int n4 = s->block_len / 2; mdct_norm = 1.0 / (float) n4; if (s->version == 1) mdct_norm *= sqrt(n4); } if (s->avctx->channels == 2) put_bits(&s->pb, 1, !!s->ms_stereo); for (ch = 0; ch < s->avctx->channels; ch++) { // FIXME only set channel_coded when needed, instead of always s->channel_coded[ch] = 1; if (s->channel_coded[ch]) init_exp(s, ch, fixed_exp); } for (ch = 0; ch < s->avctx->channels; ch++) { if (s->channel_coded[ch]) { WMACoef *coefs1; float *coefs, *exponents, mult; int i, n; coefs1 = s->coefs1[ch]; exponents = s->exponents[ch]; mult = ff_exp10(total_gain * 0.05) / s->max_exponent[ch]; mult *= mdct_norm; coefs = src_coefs[ch]; if (s->use_noise_coding && 0) { av_assert0(0); // FIXME not implemented } else { coefs += s->coefs_start; n = nb_coefs[ch]; for (i = 0; i < n; i++) { double t = *coefs++ / (exponents[i] * mult); if (t < -32768 || t > 32767) return -1; coefs1[i] = lrint(t); } } } } v = 0; for (ch = 0; ch < s->avctx->channels; ch++) { int a = s->channel_coded[ch]; put_bits(&s->pb, 1, a); v |= a; } if (!v) return 1; for (v = total_gain - 1; v >= 127; v -= 127) put_bits(&s->pb, 7, 127); put_bits(&s->pb, 7, v); coef_nb_bits = ff_wma_total_gain_to_bits(total_gain); if (s->use_noise_coding) { for (ch = 0; ch < s->avctx->channels; ch++) { if (s->channel_coded[ch]) { int i, n; n = s->exponent_high_sizes[bsize]; for (i = 0; i < n; i++) { put_bits(&s->pb, 1, s->high_band_coded[ch][i] = 0); if (0) nb_coefs[ch] -= s->exponent_high_bands[bsize][i]; } } } } parse_exponents = 1; if (s->block_len_bits != s->frame_len_bits) put_bits(&s->pb, 1, parse_exponents); if (parse_exponents) { for (ch = 0; ch < s->avctx->channels; ch++) { if (s->channel_coded[ch]) { if (s->use_exp_vlc) { encode_exp_vlc(s, ch, fixed_exp); } else { av_assert0(0); // FIXME not implemented // encode_exp_lsp(s, ch); } } } } else av_assert0(0); // FIXME not implemented for (ch = 0; ch < s->avctx->channels; ch++) { if (s->channel_coded[ch]) { int run, tindex; WMACoef *ptr, *eptr; tindex = (ch == 1 && s->ms_stereo); ptr = &s->coefs1[ch][0]; eptr = ptr + nb_coefs[ch]; run = 0; for (; ptr < eptr; ptr++) { if (*ptr) { int level = *ptr; int abs_level = FFABS(level); int code = 0; if (abs_level <= s->coef_vlcs[tindex]->max_level) if (run < s->coef_vlcs[tindex]->levels[abs_level - 1]) code = run + s->int_table[tindex][abs_level - 1]; av_assert2(code < s->coef_vlcs[tindex]->n); put_bits(&s->pb, s->coef_vlcs[tindex]->huffbits[code], s->coef_vlcs[tindex]->huffcodes[code]); if (code == 0) { if (1 << coef_nb_bits <= abs_level) return -1; put_bits(&s->pb, coef_nb_bits, abs_level); put_bits(&s->pb, s->frame_len_bits, run); } // FIXME the sign is flipped somewhere put_bits(&s->pb, 1, level < 0); run = 0; } else run++; } if (run) put_bits(&s->pb, s->coef_vlcs[tindex]->huffbits[1], s->coef_vlcs[tindex]->huffcodes[1]); } if (s->version == 1 && s->avctx->channels >= 2) avpriv_align_put_bits(&s->pb); } return 0; }
// Generate log-likelihood metrics for 8-bit soft quantized channel assuming AWGN and BPSK void gen_met( int mettab[2][256], // Metric table, [sent sym][rx symbol] double signal, // Signal amplitude, units double noise, // Noise amplitude, units (absolute, no longer relative!) double bias, // Metric bias; 0 for viterbi, rate for sequential double scale // Metric scale factor */ ){ int s; double metrics0,metrics1,p0,p1; double left0,left1,right0,right1; double inv_noise; if(Verbose) printf("gen_met(%p, signal = %lg, noise = %lg, bias = %lg, scale = %lg\n", mettab,signal,noise,bias,scale); inv_noise = 1./noise; // Compute the channel transition probabilities, i.e., the probability of receiving each of the // 256 possible values when 0s and 1s were sent. // The bins are assumed to be centered on their nominal values: // Bin 0; -infinity < v < -127.5 // Bin 1: -127.5 < v < -126.5 // Bin 128: -0.5 < v < +0.5 // Bin 255: +126.5 < v < +infinity left0 = left1 = 0.0; // area below bin 0 is zero for(s=0;s<256;s++){ // Find the area below and in this bin, subtract the area below and in the previous bin, // leaving just the area of this bin. // The area above bin 255 is zero. right0 = (s != 255) ? normal((s - 128 + 0.5 + signal) * inv_noise) : 1.0; right1 = (s != 255) ? normal((s - 128 + 0.5 - signal) * inv_noise) : 1.0; p0 = right0 - left0; // p0 = P(s|0), prob of receiving s given that a 0 was sent p1 = right1 - left1; // p1 = P(s|1), prob of recieving s given that a 1 was sent left1 = right1; left0 = right0; // Compute log-likelihood ratios assuming even balance of 0's and 1's on channel if(p0 == p1){ // At high SNR, extremal sample values may underflow to p0 == p1 == 0, giving // infinitely bad metrics for what might actually be very good samples if // actually encountered. Not sure what's right here, so I punt and treat both as erasures metrics0 = metrics1 = -bias; } else { // The smallest value from log2() is about -32, so approximate log2(0) as -33. // Alternatively I could represent it as -INT_MAX, the worst possible metric, but that seems excessive metrics0 = (p0 == 0) ? -33.0 : log2(2*p0/(p1+p0)) - bias; metrics1 = (p1 == 0) ? -33.0 : log2(2*p1/(p1+p0)) - bias; // Equivalent: metrics0 = (p0 == 0) ? -33.0 : 1 + log2(p0) - log2(p1+p0) - bias; metrics1 = (p1 == 0) ? -33.0 : 1 + log2(p1) - log2(p1+p0) - bias; } // Scale and round for table mettab[0][s] = lrint(metrics0 * scale); mettab[1][s] = lrint(metrics1 * scale); if(Verbose){ printf("s=%3d P(s|0) = %-12lg P(s|1) = %-12lg P(s) = %-12lg", s,p0,p1,(p1+p0)/2.); printf(" metrics0 = %-12lg [%4d]",metrics0,mettab[0][s]); printf(" metrics1 = %-12lg [%4d]\n",metrics1,mettab[1][s]); } } }
/* for now just 16bit signed values, mono channels FIXME * maybe use SDL_AudioConvert() for this */ int mm_decode_audio(mm_file *mf, void *buf, int buflen) { const int max_val = 32767; const int min_val = -32768; const int bytes_per_sample = 2; int rv = 0, samples = 0, left = 0, total = 0; unsigned channels = 0; assert(mf); if (-1 == mm_audio_info(mf, &channels, NULL)) { return -1; } if (mf->drop_packets & MEDIA_AUDIO) { WARNING1("requested decode but MEDIA_AUDIO is set to ignore"); return -1; } /* convert buflen [bytes] to left [samples] */ left = buflen; left = left / channels / bytes_per_sample; while (left > 0) { float **pcm; ogg_packet pkt; /* also outputs any samples left from last decoding */ while (left > 0 && (samples = vorbis_synthesis_pcmout(mf->audio_ctx, &pcm)) > 0) { int i = 0; unsigned ch = 0; samples = MIN(samples, left); for (i = 0; i < samples; ++i) { for (ch = 0; ch < channels; ++ch) { // lrint is not available on MSVC #ifdef HAVE_LRINT int val = lrint(pcm[ch][i] * max_val); #else int val = (int)floor(pcm[ch][i] * max_val); #endif if (val > max_val) { val = max_val; } if (val < min_val) { val = min_val; } *((int16_t *) buf + (total + i) * channels + ch) = val; } } total += samples; left -= samples; vorbis_synthesis_read(mf->audio_ctx, samples); } /* grab new packets if we need more */ for (;;) { rv = get_packet(mf, &pkt, MEDIA_AUDIO); if (rv < 0) { return rv; } else if (rv == 0) { return total * channels * bytes_per_sample; } /* have packet, synthesize */ if (vorbis_synthesis(mf->audio_blk, &pkt) == 0) { vorbis_synthesis_blockin(mf->audio_ctx, mf->audio_blk); break; } else { WARNING1("packet does not contain a valid vorbis frame"); /* get next packet */ } } } return total * channels * bytes_per_sample; }
static __inline increment_t double_to_fp (double x) { return (lrint ((x) * FP_ONE)) ; } /* double_to_fp */
static int sinc_hex_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) { SINC_FILTER *filter ; double input_index, src_ratio, count, float_increment, terminate, rem ; increment_t increment, start_filter_index ; int half_filter_chan_len, samples_in_hand ; if (psrc->private_data == NULL) return SRC_ERR_NO_PRIVATE ; filter = (SINC_FILTER*) psrc->private_data ; /* If there is not a problem, this will be optimised out. */ if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0])) return SRC_ERR_SIZE_INCOMPATIBILITY ; filter->in_count = data->input_frames * filter->channels ; filter->out_count = data->output_frames * filter->channels ; filter->in_used = filter->out_gen = 0 ; src_ratio = psrc->last_ratio ; /* Check the sample rate ratio wrt the buffer len. */ count = (filter->coeff_half_len + 2.0) / filter->index_inc ; if (MIN (psrc->last_ratio, data->src_ratio) < 1.0) count /= MIN (psrc->last_ratio, data->src_ratio) ; /* Maximum coefficientson either side of center point. */ half_filter_chan_len = filter->channels * (lrint (count) + 1) ; input_index = psrc->last_position ; float_increment = filter->index_inc ; rem = fmod_one (input_index) ; filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ; input_index = rem ; terminate = 1.0 / src_ratio + 1e-20 ; /* Main processing loop. */ while (filter->out_gen < filter->out_count) { /* Need to reload buffer? */ samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; if (samples_in_hand <= half_filter_chan_len) { if ((psrc->error = prepare_data (filter, data, half_filter_chan_len)) != 0) return psrc->error ; samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ; if (samples_in_hand <= half_filter_chan_len) break ; } ; /* This is the termination condition. */ if (filter->b_real_end >= 0) { if (filter->b_current + input_index + terminate >= filter->b_real_end) break ; } ; if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10) src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ; float_increment = filter->index_inc * 1.0 ; if (src_ratio < 1.0) float_increment = filter->index_inc * src_ratio ; increment = double_to_fp (float_increment) ; start_filter_index = double_to_fp (input_index * float_increment) ; calc_output_hex (filter, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ; filter->out_gen += 6 ; /* Figure out the next index. */ input_index += 1.0 / src_ratio ; rem = fmod_one (input_index) ; filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ; input_index = rem ; } ; psrc->last_position = input_index ; /* Save current ratio rather then target ratio. */ psrc->last_ratio = src_ratio ; data->input_frames_used = filter->in_used / filter->channels ; data->output_frames_gen = filter->out_gen / filter->channels ; return SRC_ERR_NO_ERROR ; } /* sinc_hex_vari_process */
int sinc_set_converter (SRC_PRIVATE *psrc, int src_enum) { SINC_FILTER *filter, temp_filter ; increment_t count ; int bits ; /* Quick sanity check. */ if (SHIFT_BITS >= sizeof (increment_t) * 8 - 1) return SRC_ERR_SHIFT_BITS ; if (psrc->private_data != NULL) { free (psrc->private_data) ; psrc->private_data = NULL ; } ; memset (&temp_filter, 0, sizeof (temp_filter)) ; temp_filter.sinc_magic_marker = SINC_MAGIC_MARKER ; temp_filter.channels = psrc->channels ; if (psrc->channels > ARRAY_LEN (temp_filter.left_calc)) return SRC_ERR_BAD_CHANNEL_COUNT ; else if (psrc->channels == 1) { psrc->const_process = sinc_mono_vari_process ; psrc->vari_process = sinc_mono_vari_process ; } else if (psrc->channels == 2) { psrc->const_process = sinc_stereo_vari_process ; psrc->vari_process = sinc_stereo_vari_process ; } else if (psrc->channels == 4) { psrc->const_process = sinc_quad_vari_process ; psrc->vari_process = sinc_quad_vari_process ; } else if (psrc->channels == 6) { psrc->const_process = sinc_hex_vari_process ; psrc->vari_process = sinc_hex_vari_process ; } else { psrc->const_process = sinc_multichan_vari_process ; psrc->vari_process = sinc_multichan_vari_process ; } ; psrc->reset = sinc_reset ; switch (src_enum) { case SRC_SINC_FASTEST : temp_filter.coeffs = fastest_coeffs.coeffs ; temp_filter.coeff_half_len = ARRAY_LEN (fastest_coeffs.coeffs) - 1 ; temp_filter.index_inc = fastest_coeffs.increment ; break ; case SRC_SINC_MEDIUM_QUALITY : temp_filter.coeffs = slow_mid_qual_coeffs.coeffs ; temp_filter.coeff_half_len = ARRAY_LEN (slow_mid_qual_coeffs.coeffs) - 1 ; temp_filter.index_inc = slow_mid_qual_coeffs.increment ; break ; case SRC_SINC_BEST_QUALITY : temp_filter.coeffs = slow_high_qual_coeffs.coeffs ; temp_filter.coeff_half_len = ARRAY_LEN (slow_high_qual_coeffs.coeffs) - 1 ; temp_filter.index_inc = slow_high_qual_coeffs.increment ; break ; default : return SRC_ERR_BAD_CONVERTER ; } ; /* ** FIXME : This needs to be looked at more closely to see if there is ** a better way. Need to look at prepare_data () at the same time. */ temp_filter.b_len = lrint (2.5 * temp_filter.coeff_half_len / (temp_filter.index_inc * 1.0) * SRC_MAX_RATIO) ; temp_filter.b_len = MAX (temp_filter.b_len, 4096) ; temp_filter.b_len *= temp_filter.channels ; if ((filter = calloc (1, sizeof (SINC_FILTER) + sizeof (filter->buffer [0]) * (temp_filter.b_len + temp_filter.channels))) == NULL) return SRC_ERR_MALLOC_FAILED ; *filter = temp_filter ; memset (&temp_filter, 0xEE, sizeof (temp_filter)) ; psrc->private_data = filter ; sinc_reset (psrc) ; count = filter->coeff_half_len ; for (bits = 0 ; (MAKE_INCREMENT_T (1) << bits) < count ; bits++) count |= (MAKE_INCREMENT_T (1) << bits) ; if (bits + SHIFT_BITS - 1 >= (int) (sizeof (increment_t) * 8)) return SRC_ERR_FILTER_LEN ; return SRC_ERR_NO_ERROR ; } /* sinc_set_converter */
long lrintl(long double a1) { return lrint(a1); }
int main(int c, char *v[]) { if (c != 5 && c != 6 && c != 7) { fprintf(stderr, "usage:\n\t" "%s Axyz.tiff Bxyx.tiff homA homB [pairs2d [pairs3d]]\n",*v); //0 1 2 3 4 5 6 return 1; } char *filename_a = v[1]; char *filename_b = v[2]; char *homstring_a = v[3]; char *homstring_b = v[4]; char *filename_in = c > 5 ? v[5] : "-"; char *filename_out = c > 6 ? v[6] : "-"; double Ha[9], Hb[9], iHa[3][3], iHb[3][3]; int nHa = read_n_doubles_from_string(Ha, homstring_a, 9); int nHb = read_n_doubles_from_string(Hb, homstring_b, 9); if (nHa != 9) set_identity(Ha); if (nHb != 9) set_identity(Hb); invert_homography(iHa, (void*)Ha); invert_homography(iHb, (void*)Hb); int wa, ha, pda, wb, hb, pdb; float *a = iio_read_image_float_vec(filename_a, &wa, &ha, &pda); float *b = iio_read_image_float_vec(filename_b, &wb, &hb, &pdb); FILE *fi = xfopen(filename_in, "r"); FILE *fo = xfopen(filename_out, "w"); if (pda != pdb) return fprintf(stderr, "input images dimension mismatch\n"); if (pda != 1 && pda != 3) return fprintf(stderr, "input images should be h or xyz\n"); int n, lmax = 10000; char line[lmax]; while (n = getlinen(line, lmax, fi)) { double m[4], p[2], q[2]; int r = sscanf(line, "%lf %lf %lf %lf", m, m + 1, m + 2, m + 3); if (r != 4) continue; apply_homography(p, iHa, m); apply_homography(q, iHb, m + 2); int ia = lrint(p[0]); int ja = lrint(p[1]); int ib = lrint(q[0]); int jb = lrint(q[1]); if (!insideP(wa, ha, ia, ja)) continue; if (!insideP(wb, hb, ib, jb)) continue; float *va = a + pda * (wa * ja + ia); float *vb = b + pda * (wb * jb + ib); if (!isfinite(*va)) continue; if (!isfinite(*vb)) continue; if (pda == 1) // heights fprintf(fo, "%lf %lf %lf %lf %lf %lf\n", p[0], p[1], *va, q[0], q[1], *vb); else // xyz fprintf(fo, "%lf %lf %lf %lf %lf %lf\n", va[0], va[1], va[2], vb[0], vb[1], vb[2]); } free(a); free(b); xfclose(fo); xfclose(fi); return 0; }
void padsynth_oscillator(unsigned long sample_count, y_sosc_t *sosc, y_voice_t *voice, struct vosc *vosc, int index, float w0) { unsigned long sample; float w, w_delta, level_a, level_a_delta, level_b, level_b_delta; float f; int i, ready; i = y_voice_mod_index(sosc->pitch_mod_src); f = *(sosc->pitch_mod_amt); w = 1.0f + f * voice->mod[i].value; w_delta = w + f * voice->mod[i].delta * (float)sample_count; w_delta *= w0; w *= w0; w_delta = (w_delta - w) / (float)sample_count; /* -FIX- condition to [0, 0.5)? */ i = y_voice_mod_index(sosc->amp_mod_src); f = *(sosc->amp_mod_amt); if (f > 0.0f) level_a = 1.0f - f + f * voice->mod[i].value; else level_a = 1.0f + f * voice->mod[i].value; level_a_delta = volume_cv_to_amplitude(level_a + f * voice->mod[i].delta * (float)sample_count); level_a = volume_cv_to_amplitude(level_a); level_a /= 32767.0f; level_a_delta /= 32767.0f; level_b = level_a * *(sosc->level_b); level_b_delta = level_a_delta * *(sosc->level_b); level_a *= *(sosc->level_a); level_a_delta *= *(sosc->level_a); level_a_delta = (level_a_delta - level_a) / (float)sample_count; level_b_delta = (level_b_delta - level_b) / (float)sample_count; /* -FIX- condition to [0, 1]? */ if (sosc->sampleset && sosc->sampleset->set_up) { i = voice->key + lrintf(*(sosc->pitch)); if (vosc->mode != vosc->last_mode || vosc->waveform != vosc->last_waveform || i != vosc->wave_select_key) { /* get sample indices and crossfade from sampleset */ sample_select(sosc, vosc, i); vosc->last_waveform = vosc->waveform; /* try to avoid reseting pos0 except when necessary to avoid causing clocks in mono * mode with portamento -- but basically it's going to click if it's not the same * sample.... */ if (vosc->mode != vosc->last_mode) { vosc->last_mode = vosc->mode; if (sosc->sampleset->sample[vosc->i0]) vosc->pos0 = vosc->pos1 = (double)random_float(0.0f, (float)sosc->sampleset->sample[vosc->i0]->length); else vosc->pos0 = vosc->pos1 = 0.0; } } if (sosc->sampleset->sample[vosc->i0] && sosc->sampleset->sample[vosc->i1]) ready = 1; else ready = 0; } else { if (vosc->mode != vosc->last_mode) { vosc->last_mode = vosc->mode; vosc->pos0 = vosc->pos1 = 0.0; } vosc->last_waveform = -1; ready = 0; } if (!ready) { /* sampleset not ready, render a sine instead */ float pos = (float)vosc->pos0; if (pos > 1.0f) pos = 0.0f; level_a *= 16383.5f; /* scale for sine_wave (float) instead of sample->data (16-bit fixed) */ level_a_delta *= 16383.5f; level_b *= 16383.5f; level_b_delta *= 16383.5f; for (sample = 0; sample < sample_count; sample++) { pos += w; if (pos >= 1.0f) pos -= 1.0f; f = pos * (float)SINETABLE_POINTS; i = lrintf(f - 0.5f); f -= (float)i; f = sine_wave[i + 4] + (sine_wave[i + 5] - sine_wave[i + 4]) * f; voice->osc_bus_a[index] += level_a * f; voice->osc_bus_b[index++] += level_b * f; w += w_delta; level_a += level_a_delta; level_b += level_b_delta; } vosc->pos0 = (double)pos; return; } if (sosc->sampleset->param3 & 1) { /* mono */ if (vosc->i0 == vosc->i1) { /* no crossfade */ /* mono without crossfade */ y_sample_t *s = (y_sample_t *)sosc->sampleset->sample[vosc->i0]; signed short *data = s->data; double pos = vosc->pos0; double length = (double)s->length; float period = s->period; if (pos >= length) pos = 0.0; for (sample = 0; sample < sample_count; sample++) { i = lrint(pos - 0.5); f = (float)(pos - (double)i); f = bspline_interp(f, (float)data[i - 1], (float)data[i], (float)data[i + 1], (float)data[i + 2]); voice->osc_bus_a[index] += level_a * f; voice->osc_bus_b[index++] += level_b * f; w += w_delta; level_a += level_a_delta; level_b += level_b_delta; pos += w * period; if (pos >= length) pos -= length; /* sampleset oscillators do not export sync */ } vosc->pos0 = pos; } else { /* mono with crossfade */ y_sample_t *s0 = (y_sample_t *)sosc->sampleset->sample[vosc->i0], *s1 = (y_sample_t *)sosc->sampleset->sample[vosc->i1]; signed short *data0 = s0->data, *data1 = s1->data; double pos0 = vosc->pos0, pos1 = vosc->pos1; double length0 = (double)s0->length, length1 = (double)s1->length; float period0 = s0->period, period1 = s1->period; float a, wavemix0 = vosc->wavemix0, wavemix1 = vosc->wavemix1; if (pos0 >= length0) pos0 = 0.0; if (pos1 >= length1) pos1 = 0.0; for (sample = 0; sample < sample_count; sample++) { i = lrint(pos0 - 0.5); f = (float)(pos0 - (double)i); a = bspline_interp(f, (float)data0[i - 1], (float)data0[i], (float)data0[i + 1], (float)data0[i + 2]) * wavemix0; i = lrint(pos1 - 0.5); f = (float)(pos1 - (double)i); a += bspline_interp(f, (float)data1[i - 1], (float)data1[i], (float)data1[i + 1], (float)data1[i + 2]) * wavemix1; voice->osc_bus_a[index] += level_a * a; voice->osc_bus_b[index++] += level_b * a; w += w_delta; level_a += level_a_delta; level_b += level_b_delta; pos0 += w * period0; pos1 += w * period1; if (pos0 >= length0) pos0 -= length0; if (pos1 >= length1) pos1 -= length1; /* sampleset oscillators do not export sync */ } vosc->pos0 = pos0; vosc->pos1 = pos1; } } else { if (vosc->i0 == vosc->i1) { /* stereo without crossfade */ y_sample_t *s = (y_sample_t *)sosc->sampleset->sample[vosc->i0]; signed short *data = s->data; double posl = vosc->pos0, posr, length = (double)s->length; float period = s->period; if (posl >= length) posl = 0.0; /* delay the right channel by about one-half the table length, but make * it an multiple of the period length to minimize phase cancellation * when summed to mono */ posr = posl + rint(length / 2.0 / (double)period) * (double)period; if (posr >= length) posr -= length; for (sample = 0; sample < sample_count; sample++) { i = lrint(posl - 0.5); f = (float)(posl - (double)i); f = bspline_interp(f, (float)data[i - 1], (float)data[i], (float)data[i + 1], (float)data[i + 2]); voice->osc_bus_a[index] += level_a * f; i = lrint(posr - 0.5); f = (float)(posr - (double)i); f = bspline_interp(f, (float)data[i - 1], (float)data[i], (float)data[i + 1], (float)data[i + 2]); voice->osc_bus_b[index++] += level_b * f; w += w_delta; level_a += level_a_delta; level_b += level_b_delta; posl += w * period; if (posl >= length) posl -= length; posr += w * period; if (posr >= length) posr -= length; /* sampleset oscillators do not export sync */ } vosc->pos0 = posl; } else { /* stereo with crossfade */ y_sample_t *s0 = (y_sample_t *)sosc->sampleset->sample[vosc->i0], *s1 = (y_sample_t *)sosc->sampleset->sample[vosc->i1]; signed short *data0 = s0->data, *data1 = s1->data; double posl0 = vosc->pos0, posl1 = vosc->pos1, posr0, posr1; double length0 = (double)s0->length, length1 = (double)s1->length; float period0 = s0->period, period1 = s1->period; float a, wavemix0 = vosc->wavemix0, wavemix1 = vosc->wavemix1; if (posl0 >= length0) posl0 = 0.0; if (posl1 >= length1) posl1 = 0.0; posr0 = posl0 + rint(length0 / 2.0 / (double)period0) * (double)period0; posr1 = posl1 + rint(length1 / 2.0 / (double)period1) * (double)period1; if (posr0 >= length0) posr0 -= length0; if (posr1 >= length1) posr1 -= length1; for (sample = 0; sample < sample_count; sample++) { i = lrint(posl0 - 0.5); f = (float)(posl0 - (double)i); a = bspline_interp(f, (float)data0[i - 1], (float)data0[i], (float)data0[i + 1], (float)data0[i + 2]) * wavemix0; i = lrint(posl1 - 0.5); f = (float)(posl1 - (double)i); a += bspline_interp(f, (float)data1[i - 1], (float)data1[i], (float)data1[i + 1], (float)data1[i + 2]) * wavemix1; voice->osc_bus_a[index] += level_a * a; i = lrint(posr0 - 0.5); f = (float)(posr0 - (double)i); a = bspline_interp(f, (float)data0[i - 1], (float)data0[i], (float)data0[i + 1], (float)data0[i + 2]) * wavemix0; i = lrint(posr1 - 0.5); f = (float)(posr1 - (double)i); a += bspline_interp(f, (float)data1[i - 1], (float)data1[i], (float)data1[i + 1], (float)data1[i + 2]) * wavemix1; voice->osc_bus_b[index++] += level_b * a; w += w_delta; level_a += level_a_delta; level_b += level_b_delta; posl0 += w * period0; posr0 += w * period0; posl1 += w * period1; posr1 += w * period1; if (posl0 >= length0) posl0 -= length0; if (posr0 >= length0) posr0 -= length0; if (posl1 >= length1) posl1 -= length1; if (posr1 >= length1) posr1 -= length1; /* sampleset oscillators do not export sync */ } vosc->pos0 = posl0; vosc->pos1 = posl1; } } }
void Printer::render(int Pages = 0) { // keep original preferences QPointer<ProfileWidget2> profile = MainWindow::instance()->graphics; int profileFrameStyle = profile->frameStyle(); int animationOriginal = qPrefDisplay::animation_speed(); double fontScale = profile->getFontPrintScale(); double printFontScale = 1.0; // apply printing settings to profile profile->setFrameStyle(QFrame::NoFrame); profile->setPrintMode(true, !printOptions->color_selected); profile->setToolTipVisibile(false); qPrefDisplay::set_animation_speed(0); // render the Qwebview QPainter painter; QRect viewPort(0, 0, pageSize.width(), pageSize.height()); painter.begin(paintDevice); painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::SmoothPixmapTransform); // get all refereces to diveprofile class in the Html template QWebElementCollection collection = webView->page()->mainFrame()->findAllElements(".diveprofile"); QSize originalSize = profile->size(); if (collection.count() > 0) { printFontScale = (double)collection.at(0).geometry().size().height() / (double)profile->size().height(); profile->resize(collection.at(0).geometry().size()); } profile->setFontPrintScale(printFontScale); int elemNo = 0; for (int i = 0; i < Pages; i++) { // render the base Html template webView->page()->mainFrame()->render(&painter, QWebFrame::ContentsLayer); // render all the dive profiles in the current page while (elemNo < collection.count() && collection.at(elemNo).geometry().y() < viewPort.y() + viewPort.height()) { // dive id field should be dive_{{dive_no}} se we remove the first 5 characters QString diveIdString = collection.at(elemNo).attribute("id"); int diveId = diveIdString.remove(0, 5).toInt(0, 10); putProfileImage(collection.at(elemNo).geometry(), viewPort, &painter, get_dive_by_uniq_id(diveId), profile); elemNo++; } // scroll the webview to the next page webView->page()->mainFrame()->scroll(0, pageSize.height()); viewPort.adjust(0, pageSize.height(), 0, pageSize.height()); // rendering progress is 4/5 of total work emit(progessUpdated(lrint((i * 80.0 / Pages) + done))); if (i < Pages - 1 && printMode == Printer::PRINT) static_cast<QPrinter*>(paintDevice)->newPage(); } painter.end(); // return profle settings profile->setFrameStyle(profileFrameStyle); profile->setPrintMode(false); profile->setFontPrintScale(fontScale); profile->setToolTipVisibile(true); profile->resize(originalSize); qPrefDisplay::set_animation_speed(animationOriginal); //replot the dive after returning the settings profile->plotDive(0, true, true); }
static int zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) { ZOH_DATA *priv ; double src_ratio, input_index, rem ; int ch ; if (data->input_frames <= 0) return SRC_ERR_NO_ERROR ; if (psrc->private_data == NULL) return SRC_ERR_NO_PRIVATE ; priv = (ZOH_DATA*) psrc->private_data ; if (priv->reset) { /* If we have just been reset, set the last_value data. */ for (ch = 0 ; ch < priv->channels ; ch++) priv->last_value [ch] = data->data_in [ch] ; priv->reset = 0 ; } ; priv->in_count = data->input_frames * priv->channels ; priv->out_count = data->output_frames * priv->channels ; priv->in_used = priv->out_gen = 0 ; src_ratio = psrc->last_ratio ; input_index = psrc->last_position ; /* Calculate samples before first sample in input array. */ while (input_index < 1.0 && priv->out_gen < priv->out_count) { if (priv->in_used + priv->channels * input_index >= priv->in_count) break ; if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF) src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ; for (ch = 0 ; ch < priv->channels ; ch++) { data->data_out [priv->out_gen] = priv->last_value [ch] ; priv->out_gen ++ ; } ; /* Figure out the next index. */ input_index += 1.0 / src_ratio ; } ; rem = fmod_one (input_index) ; priv->in_used += priv->channels * lrint (input_index - rem) ; input_index = rem ; /* Main processing loop. */ while (priv->out_gen < priv->out_count && priv->in_used + priv->channels * input_index <= priv->in_count) { if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF) src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ; for (ch = 0 ; ch < priv->channels ; ch++) { data->data_out [priv->out_gen] = data->data_in [priv->in_used - priv->channels + ch] ; priv->out_gen ++ ; } ; /* Figure out the next index. */ input_index += 1.0 / src_ratio ; rem = fmod_one (input_index) ; priv->in_used += priv->channels * lrint (input_index - rem) ; input_index = rem ; } ; if (priv->in_used > priv->in_count) { input_index += (priv->in_used - priv->in_count) / priv->channels ; priv->in_used = priv->in_count ; } ; psrc->last_position = input_index ; if (priv->in_used > 0) for (ch = 0 ; ch < priv->channels ; ch++) priv->last_value [ch] = data->data_in [priv->in_used - priv->channels + ch] ; /* Save current ratio rather then target ratio. */ psrc->last_ratio = src_ratio ; data->input_frames_used = priv->in_used / priv->channels ; data->output_frames_gen = priv->out_gen / priv->channels ; return SRC_ERR_NO_ERROR ; } /* zoh_vari_process */
void VideoEncoder::PrepareStream(AVStream* stream, AVCodec* codec, AVDictionary** options, const std::vector<std::pair<QString, QString> >& codec_options, unsigned int bit_rate, unsigned int width, unsigned int height, unsigned int frame_rate) { if(width == 0 || height == 0) { Logger::LogError("[VideoEncoder::PrepareStream] " + Logger::tr("Error: Width or height is zero!")); throw LibavException(); } if(width > 10000 || height > 10000) { Logger::LogError("[VideoEncoder::PrepareStream] " + Logger::tr("Error: Width or height is too large, the maximum width and height is %1!").arg(10000)); throw LibavException(); } if(width % 2 != 0 || height % 2 != 0) { Logger::LogError("[VideoEncoder::PrepareStream] " + Logger::tr("Error: Width or height is not an even number!")); throw LibavException(); } if(frame_rate == 0) { Logger::LogError("[VideoEncoder::PrepareStream] " + Logger::tr("Error: Frame rate is zero!")); throw LibavException(); } stream->codec->bit_rate = bit_rate; stream->codec->width = width; stream->codec->height = height; stream->codec->time_base.num = 1; stream->codec->time_base.den = frame_rate; #if SSR_USE_AVSTREAM_TIME_BASE stream->time_base = stream->codec->time_base; #endif stream->codec->pix_fmt = AV_PIX_FMT_NONE; for(unsigned int i = 0; i < SUPPORTED_PIXEL_FORMATS.size(); ++i) { if(AVCodecSupportsPixelFormat(codec, SUPPORTED_PIXEL_FORMATS[i].m_format)) { stream->codec->pix_fmt = SUPPORTED_PIXEL_FORMATS[i].m_format; if(SUPPORTED_PIXEL_FORMATS[i].m_is_yuv) { stream->codec->color_primaries = AVCOL_PRI_BT709; stream->codec->color_trc = AVCOL_TRC_BT709; stream->codec->colorspace = AVCOL_SPC_BT709; stream->codec->color_range = AVCOL_RANGE_MPEG; stream->codec->chroma_sample_location = AVCHROMA_LOC_CENTER; } else { stream->codec->colorspace = AVCOL_SPC_RGB; } break; } } if(stream->codec->pix_fmt == AV_PIX_FMT_NONE) { Logger::LogError("[VideoEncoder::PrepareStream] " + Logger::tr("Error: Encoder requires an unsupported pixel format!")); throw LibavException(); } stream->codec->sample_aspect_ratio.num = 1; stream->codec->sample_aspect_ratio.den = 1; stream->sample_aspect_ratio = stream->codec->sample_aspect_ratio; stream->codec->thread_count = std::max(1, (int) std::thread::hardware_concurrency()); for(unsigned int i = 0; i < codec_options.size(); ++i) { const QString &key = codec_options[i].first, &value = codec_options[i].second; if(key == "threads") { stream->codec->thread_count = ParseCodecOptionInt(key, value, 1, 100); } else if(key == "qscale") { stream->codec->flags |= CODEC_FLAG_QSCALE; stream->codec->global_quality = lrint(ParseCodecOptionDouble(key, value, -1.0e6, 1.0e6, FF_QP2LAMBDA)); } else if(key == "minrate") { stream->codec->rc_min_rate = ParseCodecOptionInt(key, value, 1, 1000000, 1024); // kbps } else if(key == "maxrate") { stream->codec->rc_max_rate = ParseCodecOptionInt(key, value, 1, 1000000, 1024); // kbps } else if(key == "bufsize") { stream->codec->rc_buffer_size = ParseCodecOptionInt(key, value, 1, 1000000, 1024); // kbps } else if(key == "keyint") { stream->codec->gop_size = ParseCodecOptionInt(key, value, 1, 1000000); #if !SSR_USE_AVCODEC_PRIVATE_PRESET } else if(key == "crf") { stream->codec->crf = ParseCodecOptionInt(key, value, 0, 51); #endif #if !SSR_USE_AVCODEC_PRIVATE_PRESET } else if(key == "preset") { X264Preset(stream->codec, value.toUtf8().constData()); #endif } else { av_dict_set(options, key.toUtf8().constData(), value.toUtf8().constData(), 0); } } }
void PlayPanel::setTempo(double val) { int tempo = lrint(val * 60.0); tempoLabel->setText(QString("%1 BPM").arg(tempo, 3, 10, QLatin1Char(' '))); }
double nsl_stats_quantile_sorted(const double d[], size_t stride, size_t n, double p, nsl_stats_quantile_type type) { switch(type) { case nsl_stats_quantile_type1: if (p == 0.0) return d[0]; else return d[((int)ceil(n*p)-1)*stride]; case nsl_stats_quantile_type2: if (p == 0.0) return d[0]; else if (p == 1.0) return d[(n-1)*stride]; else return (d[((int)ceil(n*p)-1)*stride]+d[((int)ceil(n*p+1)-1)*stride])/2.; case nsl_stats_quantile_type3: if(p <= 0.5/n) return d[0]; else return d[(lrint(n*p)-1)*stride]; case nsl_stats_quantile_type4: if(p < 1./n) return d[0]; else if (p == 1.0) return d[(n-1)*stride]; else { int i = floor(n*p); return d[(i-1)*stride]+(n*p-i)*(d[i*stride]-d[(i-1)*stride]); } case nsl_stats_quantile_type5: if(p < 0.5/n) return d[0]; else if (p >= (n-0.5)/n) return d[(n-1)*stride]; else { int i = floor(n*p+0.5); return d[(i-1)*stride]+(n*p+0.5-i)*(d[i*stride]-d[(i-1)*stride]); } case nsl_stats_quantile_type6: if(p < 1./(n+1.)) return d[0]; else if (p > n/(n+1.)) return d[(n-1)*stride]; else { int i = floor((n+1)*p); return d[(i-1)*stride]+((n+1)*p-i)*(d[i*stride]-d[(i-1)*stride]); } case nsl_stats_quantile_type7: if (p == 1.0) return d[(n-1)*stride]; else { int i = floor((n-1)*p+1); return d[(i-1)*stride]+((n-1)*p+1-i)*(d[i*stride]-d[(i-1)*stride]); } case nsl_stats_quantile_type8: if (p < 2./3./(n+1./3.)) return d[0]; else if (p >= (n-1./3.)/(n+1./3.)) return d[(n-1)*stride]; else { int i = floor((n+1./3.)*p+1./3.); return d[(i-1)*stride]+((n+1./3.)*p+1./3.-i)*(d[i*stride]-d[(i-1)*stride]); } case nsl_stats_quantile_type9: if (p < 5./8./(n+1./4.)) return d[0]; else if (p >= (n-3./8.)/(n+1./4.)) return d[(n-1)*stride]; else { int i = floor((n+1./4.)*p+3./8.); return d[(i-1)*stride]+((n+1./4.)*p+3./8.-i)*(d[i*stride]-d[(i-1)*stride]); } } return 0; }
void tray_update(HWND hWnd, struct th_data *data) { struct tray_status *status = &data->status; NOTIFYICONDATA *niData = &data->niData; HICON oldIcon; unsigned int fg, bg, p, d; BOOL ret; DWORD err; if (!data->tray_ok) { tray_add(hWnd, data); if (!data->tray_ok) return; } odprintf("tray[update]: conn=%d msg=\"%s\" temperature_celsius=%f relative_humidity=%f dew_point=%f", status->conn, status->msg, status->temperature_celsius, status->relative_humidity, status->dew_point); fg = icon_syscolour(COLOR_BTNTEXT); bg = icon_syscolour(COLOR_3DFACE); switch (status->conn) { case NOT_CONNECTED: if (not_connected_width < ICON_WIDTH || not_connected_height < ICON_HEIGHT) icon_wipe(bg); icon_blit(0, 0, 0, fg, bg, 0, 0, not_connected_width, not_connected_height, not_connected_bits); if (status->msg[0] != 0) ret = snprintf(niData->szTip, sizeof(niData->szTip), "Not Connected: %s", status->msg); else ret = snprintf(niData->szTip, sizeof(niData->szTip), "Not Connected"); if (ret < 0) niData->szTip[0] = 0; break; case CONNECTING: if (connecting_width < ICON_WIDTH || connecting_height < ICON_HEIGHT) icon_wipe(bg); icon_blit(0, 0, 0, fg, bg, 0, 0, connecting_width, connecting_height, connecting_bits); if (status->msg[0] != 0) ret = snprintf(niData->szTip, sizeof(niData->szTip), "Connecting to %s", status->msg); else ret = snprintf(niData->szTip, sizeof(niData->szTip), "Connecting"); if (ret < 0) niData->szTip[0] = 0; break; case CONNECTED: if (isnan(status->temperature_celsius)) { icon_clear(0, 0, bg, 0, 0, ICON_WIDTH, digits_base_height); p = 0; icon_blit(0, 0, 0, fg, bg, p, 0, digit_dash_width, digit_dash_height, digit_dash_bits); p += digit_dash_width + 1; icon_blit(0, 0, 0, fg, bg, p, 0, digit_dash_width, digit_dash_height, digit_dash_bits); p += digit_dash_width + 1; icon_blit(0, 0, 0, fg, bg, p, 0, digit_dot_width, digit_dot_height, digit_dot_bits); p += digit_dot_width + 1; icon_blit(0, 0, 0, fg, bg, p, 0, digit_dash_width, digit_dash_height, digit_dash_bits); } else { unsigned int h_fg, h_bg, h_end, hue; int tc = lrint(status->temperature_celsius * 100.0); if (tc > 99999) tc = 99999; if (tc < -9999) tc = -9999; hue = tray_range_to_hue(MIN_TEMPC, MIN_TEMPC_WARN, status->temperature_celsius, MAX_TEMPC_WARN, MAX_TEMPC); h_end = tray_hue_to_width(hue); h_fg = tray_hue_to_fg_colour(hue); h_bg = tray_hue_to_bg_colour(hue); icon_clear(h_bg, h_end, bg, 0, 0, ICON_WIDTH, digits_base_height); if (tc >= 9995) { /* _NNN 100 to 999 */ if (tc % 100 >= 50) tc += 100 - (tc % 100); p = digit_dot_width + 1; d = (tc/10000) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); p += digits_width[d] + 1; d = (tc/1000) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); p += digits_width[d] + 1; d = (tc/100) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); } else if (tc > 999) { /* NN.N 10.0 to 99.9 */ if (tc % 10 >= 5) tc += 10 - (tc % 10); p = 0; d = (tc/1000) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); p += digits_width[d] + 1; d = (tc/100) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); p += digits_width[d] + 1; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digit_dot_width, digit_dot_height, digit_dot_bits); p += digit_dot_width + 1; d = (tc/10) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); } else if (tc >= 0) { /* N.NN 0.00 to 9.99 */ p = 0; d = (tc/100) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); p += digits_width[d] + 1; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digit_dot_width, digit_dot_height, digit_dot_bits); p += digit_dot_width + 1; d = (tc/10) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); p += digits_width[d] + 1; d = tc % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); } else if (tc > -995) { /* -N.N -0.1 to -9.9 */ if (abs(tc) % 10 >= 5) tc -= 10 - (abs(tc) % 10); p = 0; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digit_dash_width, digit_dash_height, digit_dash_bits); p += digit_dash_width + 1; d = abs(tc/100) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); p += digits_width[d] + 1; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digit_dot_width, digit_dot_height, digit_dot_bits); p += digit_dot_width + 1; d = abs(tc/10) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); } else /* if (tc >= -9999) */ { /* _-NN -10 to -99 */ if (abs(tc) % 100 >= 50) tc -= 100 - (abs(tc) % 100); p = digit_dot_width + 1; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digit_dash_width, digit_dash_height, digit_dash_bits); p += digit_dash_width + 1; d = abs(tc/1000) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); p += digits_width[d] + 1; d = abs(tc/100) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, 0, digits_width[d], digits_height[d], digits_bits[d]); } } icon_clear(0, 0, bg, 0, ICON_HEIGHT/2 - (ICON_HEIGHT/2 - digits_base_height), ICON_WIDTH, (ICON_HEIGHT/2 - digits_base_height) * 2); if (isnan(status->relative_humidity)) { icon_clear(0, 0, bg, 0, ICON_HEIGHT - digits_base_height, ICON_WIDTH, digit_dash_height); p = 0; icon_blit(0, 0, 0, fg, bg, p, ICON_HEIGHT - digits_base_height, digit_dash_width, digit_dash_height, digit_dash_bits); p += digit_dash_width + 1; icon_blit(0, 0, 0, fg, bg, p, ICON_HEIGHT - digits_base_height, digit_dash_width, digit_dash_height, digit_dash_bits); p += digit_dash_width + 1; icon_blit(0, 0, 0, fg, bg, p, ICON_HEIGHT - digits_base_height, digit_dot_width, digit_dot_height, digit_dot_bits); p += digit_dot_width + 1; icon_blit(0, 0, 0, fg, bg, p, ICON_HEIGHT - digits_base_height, digit_dash_width, digit_dash_height, digit_dash_bits); } else { unsigned int h_fg, h_bg, h_end, hue; int rh = lrint(status->relative_humidity * 10.0); if (rh > 999) rh = 999; if (rh < 0) rh = 0; hue = tray_range_to_hue(MIN_DEWPC, MIN_DEWPC_WARN, status->dew_point, MAX_DEWPC_WARN, MAX_DEWPC); h_end = tray_hue_to_width(hue); h_fg = tray_hue_to_fg_colour(hue); h_bg = tray_hue_to_bg_colour(hue); icon_clear(h_bg, h_end, bg, 0, ICON_HEIGHT - digits_base_height, ICON_WIDTH, digits_base_height); /* NN.N 00.0 to 99.9 */ p = 0; d = (rh/100) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, ICON_HEIGHT - digits_base_height, digits_width[d], digits_height[d], digits_bits[d]); p += digits_width[d] + 1; d = (rh/10) % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, ICON_HEIGHT - digits_base_height, digits_width[d], digits_height[d], digits_bits[d]); p += digits_width[d] + 1; icon_blit(h_fg, h_bg, h_end, fg, bg, p, ICON_HEIGHT - digits_base_height, digit_dot_width, digit_dot_height, digit_dot_bits); p += digit_dot_width + 1; d = rh % 10; icon_blit(h_fg, h_bg, h_end, fg, bg, p, ICON_HEIGHT - digits_base_height, digits_width[d], digits_height[d], digits_bits[d]); } snprintf(niData->szTip, sizeof(niData->szTip), "Temperature: %.2fC, Relative Humidity: %.2f%%, Dew Point: %.2fC", status->temperature_celsius, status->relative_humidity, status->dew_point); break; default: return; } oldIcon = niData->hIcon; niData->uFlags &= ~NIF_ICON; niData->hIcon = icon_create(); if (niData->hIcon != NULL) niData->uFlags |= NIF_ICON; SetLastError(0); ret = Shell_NotifyIcon(NIM_MODIFY, niData); err = GetLastError(); odprintf("Shell_NotifyIcon[MODIFY]: %s (%ld)", ret == TRUE ? "TRUE" : "FALSE", err); if (ret != TRUE) tray_remove(hWnd, data); if (oldIcon != NULL) icon_destroy(niData->hIcon); }
void Stem::draw(QPainter* painter) const { // hide if second chord of a cross-measure pair if (chord() && chord()->crossMeasure() == CrossMeasure::SECOND) return; Staff* st = staff(); bool useTab = st && st->isTabStaff(chord()->tick()); painter->setPen(QPen(curColor(), _lineWidth, Qt::SolidLine, Qt::RoundCap)); painter->drawLine(line); if (!(useTab && chord())) return; // TODO: adjust bounding rectangle in layout() for dots and for slash StaffType* stt = st->staffType(chord()->tick()); qreal sp = spatium(); bool _up = up(); // slashed half note stem if (chord()->durationType().type() == TDuration::DurationType::V_HALF && stt->minimStyle() == TablatureMinimStyle::SLASHED) { // position slashes onto stem qreal y = _up ? -(_len+_userLen) + STAFFTYPE_TAB_SLASH_2STARTY_UP*sp : (_len+_userLen) - STAFFTYPE_TAB_SLASH_2STARTY_DN*sp; // if stems through, try to align slashes within or across lines if (stt->stemThrough()) { qreal halfLineDist = stt->lineDistance().val() * sp * 0.5; qreal halfSlashHgt = STAFFTYPE_TAB_SLASH_2TOTHEIGHT * sp * 0.5; y = lrint( (y + halfSlashHgt) / halfLineDist) * halfLineDist - halfSlashHgt; } // draw slashes qreal hlfWdt= sp * STAFFTYPE_TAB_SLASH_WIDTH * 0.5; qreal sln = sp * STAFFTYPE_TAB_SLASH_SLANTY; qreal thk = sp * STAFFTYPE_TAB_SLASH_THICK; qreal displ = sp * STAFFTYPE_TAB_SLASH_DISPL; QPainterPath path; for (int i = 0; i < 2; ++i) { path.moveTo( hlfWdt, y); // top-right corner path.lineTo( hlfWdt, y+thk); // bottom-right corner path.lineTo(-hlfWdt, y+thk+sln); // bottom-left corner path.lineTo(-hlfWdt, y+sln); // top-left corner path.closeSubpath(); y += displ; } painter->setBrush(QBrush(curColor())); painter->setPen(Qt::NoPen); painter->drawPath(path); } // dots // NOT THE BEST PLACE FOR THIS? // with tablatures and stems beside staves, dots are not drawn near 'notes', but near stems int nDots = chord()->dots(); if (nDots > 0 && !stt->stemThrough()) { qreal x = chord()->dotPosX(); qreal y = ( (STAFFTYPE_TAB_DEFAULTSTEMLEN_DN * 0.2) * sp) * (_up ? -1.0 : 1.0); qreal step = score()->styleS(StyleIdx::dotDotDistance).val() * sp; for (int dot = 0; dot < nDots; dot++, x += step) drawSymbol(SymId::augmentationDot, painter, QPointF(x, y)); } }
EXTERN_C int sopen_SCP_write(HDRTYPE* hdr) { /* this function is a stub or placeholder and need to be defined in order to be useful. It will be called by the function SOPEN in "biosig.c" Input: char* Header // contains the file content Output: HDRTYPE *hdr // defines the HDR structure accoring to "biosig.h" */ uint8_t* ptr; // pointer to memory mapping of the file layout uint8_t* PtrCurSect; // point to current section int curSect; uint32_t len; uint16_t crc; uint32_t i; uint32_t sectionStart; struct tm* T0_tm; double AVM, avm; aECG_TYPE* aECG; if ((fabs(hdr->VERSION - 1.3)<0.01) && (fabs(hdr->VERSION-2.0)<0.01)) fprintf(stderr,"Warning SOPEN (SCP-WRITE): Version %f not supported\n",hdr->VERSION); uint8_t VERSION = 20; // (uint8_t)round(hdr->VERSION*10); // implemented version number if (hdr->aECG==NULL) { fprintf(stderr,"Warning SOPEN_SCP_WRITE: No aECG info defined\n"); hdr->aECG = malloc(sizeof(aECG_TYPE)); aECG = (aECG_TYPE*)hdr->aECG; aECG->diastolicBloodPressure=0.0; aECG->systolicBloodPressure=0.0; aECG->MedicationDrugs="/0"; aECG->ReferringPhysician="/0"; aECG->LatestConfirmingPhysician="/0"; aECG->Diagnosis="/0"; aECG->EmergencyLevel=0; aECG->Section8.NumberOfStatements = 0; aECG->Section8.Statements = NULL; aECG->Section11.NumberOfStatements = 0; aECG->Section11.Statements = NULL; } else aECG = (aECG_TYPE*)hdr->aECG; //fprintf(stdout,"SCP-Write: IIb %s\n",hdr->aECG->ReferringPhysician); /* predefined values */ aECG->Section1.Tag14.INST_NUMBER = 0; // tag 14, byte 1-2 aECG->Section1.Tag14.DEPT_NUMBER = 0; // tag 14, byte 3-4 aECG->Section1.Tag14.DEVICE_ID = 0; // tag 14, byte 5-6 aECG->Section1.Tag14.DeviceType = 0; // tag 14, byte 7: 0: Cart, 1: System (or Host) aECG->Section1.Tag14.MANUF_CODE = 255; // tag 14, byte 8 (MANUF_CODE has to be 255) aECG->Section1.Tag14.MOD_DESC = "Cart1"; // tag 14, byte 9 (MOD_DESC has to be "Cart1") aECG->Section1.Tag14.VERSION = VERSION; // tag 14, byte 15 (VERSION * 10) aECG->Section1.Tag14.PROT_COMP_LEVEL = 0xA0; // tag 14, byte 16 (PROT_COMP_LEVEL has to be 0xA0 => level II) aECG->Section1.Tag14.LANG_SUPP_CODE = 0x00; // tag 14, byte 17 (LANG_SUPP_CODE has to be 0x00 => Ascii only, latin and 1-byte code) aECG->Section1.Tag14.ECG_CAP_DEV = 0xD0; // tag 14, byte 18 (ECG_CAP_DEV has to be 0xD0 => Acquire, (No Analysis), Print and Store) aECG->Section1.Tag14.MAINS_FREQ = 0; // tag 14, byte 19 (MAINS_FREQ has to be 0: unspecified, 1: 50 Hz, 2: 60Hz) aECG->Section1.Tag14.ANAL_PROG_REV_NUM = ""; aECG->Section1.Tag14.SERIAL_NUMBER_ACQ_DEV = ""; aECG->Section1.Tag14.ACQ_DEV_SYS_SW_ID = ""; aECG->Section1.Tag14.ACQ_DEV_SCP_SW = "OpenECG XML-SCP 1.00"; // tag 14, byte 38 (SCP_IMPL_SW has to be "OpenECG XML-SCP 1.00") aECG->Section1.Tag14.ACQ_DEV_MANUF = "Manufacturer"; // tag 14, byte 38 (ACQ_DEV_MANUF has to be "Manufacturer") aECG->Section5.Length = 0; aECG->Section6.Length = 0; /* */ aECG->FLAG.HUFFMAN = 0; aECG->FLAG.REF_BEAT= 0; aECG->FLAG.DIFF = 0; aECG->FLAG.BIMODAL = 0; ptr = (uint8_t*)hdr->AS.Header; int NSections = 12; // initialize section 0 sectionStart = 6+16+NSections*10; ptr = (uint8_t*)realloc(ptr,sectionStart); memset(ptr,0,sectionStart); uint32_t curSectLen = 0; // current section length for (curSect=NSections-1; curSect>=0; curSect--) { curSectLen = 0; // current section length //ptr = (uint8_t*)realloc(ptr,sectionStart+curSectLen); // fprintf(stdout,"Section %i %x\n",curSect,ptr); if (curSect==0) // SECTION 0 { hdr->HeadLen = sectionStart; // length of all other blocks together ptr = (uint8_t*)realloc(ptr,hdr->HeadLen); // total file length curSectLen = 16; // current section length sectionStart = 6; memcpy(ptr+16,"SCPECG",6); // reserved curSectLen += NSections*10; } else if (curSect==1) // SECTION 1 { ptr = (uint8_t*)realloc(ptr,sectionStart+10000); PtrCurSect = ptr+sectionStart; curSectLen = 16; // current section length // Tag 0 (max len = 64) if (!hdr->FLAG.ANONYMOUS && (hdr->Patient.Name != NULL)) { *(ptr+sectionStart+curSectLen) = 0; // tag len = strlen(hdr->Patient.Name) + 1; *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)ptr+sectionStart+curSectLen+3,hdr->Patient.Name,len); // field curSectLen += len+3; } // Tag 1 (max len = 64) Firstname /* *(ptr+sectionStart+curSectLen) = 1; // tag len = strlen(hdr->Patient.Name) + 1; *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)ptr+sectionStart+curSectLen+3,hdr->Patient.Name,len); // field curSectLen += len+3; */ // Tag 2 (max len = 64) Patient ID // if (hdr->Patient.Id != NULL) { if (strlen(hdr->Patient.Id)>0) { *(ptr+sectionStart+curSectLen) = 2; // tag len = strlen(hdr->Patient.Id) + 1; *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)ptr+sectionStart+curSectLen+3,hdr->Patient.Id,len); // field curSectLen += len+3; } // fprintf(stdout,"Section %i Len %i %x\n",curSect,curSectLen,sectionStart); // Tag 3 (max len = 64) Second Last Name /* *(ptr+sectionStart+curSectLen) = 3; // tag len = strlen(hdr->Patient.Name) + 1; *(uint16_t)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy(ptr+sectionStart+curSectLen+3,hdr->Patient.Name,len); // field curSectLen += len+3; */ // Tag 5 (len = 4) if ((hdr->Patient.Birthday) > 0) { T0_tm = gdf_time2tm_time(hdr->Patient.Birthday); *(ptr+sectionStart+curSectLen) = 5; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(4); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16(T0_tm->tm_year+1900);// year *(ptr+sectionStart+curSectLen+5) = (uint8_t)(T0_tm->tm_mon + 1); // month *(ptr+sectionStart+curSectLen+6) = (uint8_t)(T0_tm->tm_mday); // day curSectLen += 7; } // Tag 6 (len = 3) Height if (hdr->Patient.Height>0.0) { *(ptr+sectionStart+curSectLen) = 6; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(3); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16(hdr->Patient.Height); // value *(ptr+sectionStart+curSectLen+5) = 1; // cm curSectLen += 6; } // Tag 7 (len = 3) Weight if (hdr->Patient.Weight>0.0) { *(ptr+sectionStart+curSectLen) = 7; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(3); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16(hdr->Patient.Weight); // value *(ptr+sectionStart+curSectLen+5) = 1; // kg curSectLen += 6; } // Tag 8 (len = 1) if (hdr->Patient.Sex != 0) { *(ptr+sectionStart+curSectLen) = 8; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(1); // length *(ptr+sectionStart+curSectLen+3) = hdr->Patient.Sex; // value curSectLen += 4; } // Tag 11 (len = 2) if (aECG->systolicBloodPressure>0.0) { *(ptr+sectionStart+curSectLen) = 11; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(2); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16((uint16_t)aECG->systolicBloodPressure); // value curSectLen += 5; }; // Tag 12 (len = 2) if (aECG->diastolicBloodPressure>0.0) { *(ptr+sectionStart+curSectLen) = 12; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(2); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16((uint16_t)aECG->diastolicBloodPressure); // value curSectLen += 5; }; // Tag 13 (max len = 80) aECG->Diagnosis=""; len = strlen(aECG->Diagnosis); if (len>0) { *(ptr+sectionStart+curSectLen) = 13; // tag len = min(64,len+1); *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),aECG->Diagnosis,len); curSectLen += 3+len; }; // Tag 14 (max len = 2 + 2 + 2 + 1 + 1 + 6 + 1 + 1 + 1 + 1 + 1 + 16 + 1 + 25 + 25 + 25 + 25 + 25) // Total = 161 (max value) *(ptr+sectionStart+curSectLen) = 14; // tag //len = 41; // minimum length // *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length memset(ptr+sectionStart+curSectLen+3,0,41); // dummy value curSectLen += 3; *(uint16_t*)(ptr+sectionStart+curSectLen) = aECG->Section1.Tag14.INST_NUMBER; *(uint16_t*)(ptr+sectionStart+curSectLen+2) = aECG->Section1.Tag14.DEPT_NUMBER; *(uint16_t*)(ptr+sectionStart+curSectLen+4) = aECG->Section1.Tag14.DEVICE_ID; *(ptr+sectionStart+curSectLen+ 6) = aECG->Section1.Tag14.DeviceType; *(ptr+sectionStart+curSectLen+ 7) = aECG->Section1.Tag14.MANUF_CODE; // tag 14, byte 7 (MANUF_CODE has to be 255) strncpy((char*)(ptr+sectionStart+curSectLen+8), aECG->Section1.Tag14.MOD_DESC, 6); // tag 14, byte 7 (MOD_DESC has to be "Cart1") *(ptr+sectionStart+curSectLen+14) = VERSION; // tag 14, byte 14 (VERSION has to be 20) *(ptr+sectionStart+curSectLen+14) = aECG->Section1.Tag14.VERSION; *(ptr+sectionStart+curSectLen+15) = aECG->Section1.Tag14.PROT_COMP_LEVEL; // tag 14, byte 15 (PROT_COMP_LEVEL has to be 0xA0 => level II) *(ptr+sectionStart+curSectLen+16) = aECG->Section1.Tag14.LANG_SUPP_CODE; // tag 14, byte 16 (LANG_SUPP_CODE has to be 0x00 => Ascii only, latin and 1-byte code) *(ptr+sectionStart+curSectLen+17) = aECG->Section1.Tag14.ECG_CAP_DEV; // tag 14, byte 17 (ECG_CAP_DEV has to be 0xD0 => Acquire, (No Analysis), Print and Store) *(ptr+sectionStart+curSectLen+18) = aECG->Section1.Tag14.MAINS_FREQ; // tag 14, byte 18 (MAINS_FREQ has to be 0: unspecified, 1: 50 Hz, 2: 60Hz) *(ptr+sectionStart+curSectLen+35) = strlen(aECG->Section1.Tag14.ANAL_PROG_REV_NUM)+1; // tag 14, byte 34 => length of ANAL_PROG_REV_NUM + 1 = 1 uint16_t len1 = 36; char* tmp; tmp = aECG->Section1.Tag14.ANAL_PROG_REV_NUM; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; tmp = aECG->Section1.Tag14.SERIAL_NUMBER_ACQ_DEV; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; tmp = aECG->Section1.Tag14.ACQ_DEV_SYS_SW_ID; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; tmp = aECG->Section1.Tag14.ACQ_DEV_SCP_SW; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; tmp = aECG->Section1.Tag14.ACQ_DEV_MANUF; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; *(uint16_t*)(ptr+sectionStart+curSectLen+1-3) = l_endian_u16(len1); // length curSectLen += len1; // Tag 16 (max len = 80) len = strlen(hdr->ID.Hospital); if (len>0) { *(ptr+sectionStart+curSectLen) = 16; // tag len = min(64,len+1); *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),hdr->ID.Hospital,len); curSectLen += 3+len; }; // Tag 20 (max len = 64 ) len = strlen(aECG->ReferringPhysician); if (len>0) { *(ptr+sectionStart+curSectLen) = 20; // tag len = min(64,len+1); *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),aECG->ReferringPhysician,len); curSectLen += 3+len; }; // Tag 21 (max len = 64 ) len = strlen(aECG->MedicationDrugs); if (len>0) { *(ptr+sectionStart+curSectLen) = 21; // tag len = min(64,len+1); *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),aECG->MedicationDrugs,len); curSectLen += 3+len; }; // Tag 22 (max len = 40 ) len = strlen(hdr->ID.Technician); if (len>0) { *(ptr+sectionStart+curSectLen) = 22; // tag len = min(64,len+1); *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(len); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),hdr->ID.Technician,len); curSectLen += 3+len; }; // Tag 24 ( len = 1 ) *(ptr+sectionStart+curSectLen) = 24; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(1); // length *(ptr+sectionStart+curSectLen+3) = aECG->EmergencyLevel; curSectLen += 4; // Tag 25 (len = 4) gdf_time T1 = hdr->T0; #ifndef __APPLE__ T1 += (int32_t)ldexp(timezone/86400.0,32); #endif T0_tm = gdf_time2tm_time(T1); *(ptr+sectionStart+curSectLen) = 25; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(4); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16((uint16_t)(T0_tm->tm_year+1900));// year *(ptr+sectionStart+curSectLen+5) = (uint8_t)(T0_tm->tm_mon + 1);// month *(ptr+sectionStart+curSectLen+6) = (uint8_t)T0_tm->tm_mday; // day curSectLen += 7; // Tag 26 (len = 3) *(ptr+sectionStart+curSectLen) = 26; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(3); // length *(ptr+sectionStart+curSectLen+3) = (uint8_t)T0_tm->tm_hour; // hour *(ptr+sectionStart+curSectLen+4) = (uint8_t)T0_tm->tm_min; // minute *(ptr+sectionStart+curSectLen+5) = (uint8_t)T0_tm->tm_sec; // second curSectLen += 6; if (hdr->NS>0) { // Tag 27 (len = 3) highpass filter *(ptr+sectionStart+curSectLen) = 27; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(2); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = (uint16_t)hdr->CHANNEL[1].HighPass; // hour curSectLen += 5; // Tag 28 (len = 3) lowpass filter *(ptr+sectionStart+curSectLen) = 28; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(2); // length *(uint16_t*)(ptr+sectionStart+curSectLen+3) = (uint16_t)hdr->CHANNEL[1].LowPass; // hour curSectLen += 5; // Tag 29 (len = 1) filter bitmap uint8_t bitmap = 0; if (fabs(hdr->CHANNEL[1].LowPass-60.0)<0.01) bitmap = 1; else if (fabs(hdr->CHANNEL[1].LowPass-50.0)<0.01) bitmap = 2; else bitmap = 0; *(ptr+sectionStart+curSectLen) = 29; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(1); // length *(ptr+sectionStart+curSectLen+3) = bitmap; curSectLen += 4; } // Tag 32 (len = 5) *(ptr+sectionStart+curSectLen) = 32; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(2); // length if (hdr->Patient.Impairment.Heart==1) { *(ptr+sectionStart+curSectLen+3) = 0; *(ptr+sectionStart+curSectLen+4) = 1; // Apparently healthy curSectLen += 5; } else if (hdr->Patient.Impairment.Heart==3) { *(ptr+sectionStart+curSectLen+3) = 0; *(ptr+sectionStart+curSectLen+4) = 42; // Implanted cardiac pacemaker curSectLen += 5; } // Tag 34 (len = 5) *(ptr+sectionStart+curSectLen) = 34; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(5); // length // FIXME: compensation for daylight saving time not included #ifdef __APPLE__ // ### FIXME: for some (unknown) reason, timezone does not work on MacOSX *(int16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_i16(0x7fff); printf("Warning SOPEN(SCP,write): timezone not supported\n"); #else *(int16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_i16((int16_t)lrint(-timezone/60.0)); #endif //*(int16_t*)(ptr+sectionStart+curSectLen+3) = l_endian_u16((int16_t)round(T0_tm->tm_gmtoff/60)); *(int16_t*)(ptr+sectionStart+curSectLen+5) = 0; curSectLen += 8; // Tag 255 (len = 0) *(ptr+sectionStart+curSectLen) = 255; // tag *(uint16_t*)(ptr+sectionStart+curSectLen+1) = l_endian_u16(0); // length curSectLen += 3; // Evaluate the size and correct it if odd if (curSectLen & 1) { *(ptr+sectionStart+curSectLen++) = 0; } } else if (curSect==2) // SECTION 2 { } else if (curSect==3) // SECTION 3 { ptr = (uint8_t*)realloc(ptr,sectionStart+16+2+9*hdr->NS+1); PtrCurSect = ptr+sectionStart; curSectLen = 16; // current section length // Number of leads enclosed *(ptr+sectionStart+curSectLen++) = hdr->NS; // ### Situations with reference beat subtraction are not supported // Situations with not all the leads simultaneously recorded are not supported // Situations number of leads simultaneouly recorded != total number of leads are not supported // We assume all the leads are recorded simultaneously *(ptr+sectionStart+curSectLen++) = (hdr->NS<<3) | 0x04; for (i = 0; i < hdr->NS; i++) { *(uint32_t*)(ptr+sectionStart+curSectLen) = l_endian_u32(1L); *(uint32_t*)(ptr+sectionStart+curSectLen+4) = l_endian_u32(hdr->data.size[0]); *(ptr+sectionStart+curSectLen+8) = (uint8_t)hdr->CHANNEL[i].LeadIdCode; curSectLen += 9; } // Evaluate the size and correct it if odd if ((curSectLen % 2) != 0) { *(ptr+sectionStart+curSectLen++) = 0; } memset(ptr+sectionStart+10,0,6); // reserved } else if (curSect==4) // SECTION 4 { } else if (curSect==5) // SECTION 5 { curSectLen = 0; // current section length aECG->Section5.StartPtr = sectionStart; aECG->Section5.Length = curSectLen; } else if (curSect==6) // SECTION 6 { uint16_t GDFTYP = 3; size_t SZ = GDFTYP_BITS[GDFTYP]>>3; for (i = 0; i < hdr->NS; i++) hdr->CHANNEL[i].GDFTYP = GDFTYP; ptr = (uint8_t*)realloc(ptr,sectionStart+16+6+2*hdr->NS+SZ*(hdr->data.size[0]*hdr->data.size[1])); PtrCurSect = ptr+sectionStart; curSectLen = 16; // current section length // Create all the fields // Amplitude Value Multiplier (AVM) i = 0; AVM = hdr->CHANNEL[i].Cal * 1e9 * PhysDimScale(hdr->CHANNEL[i].PhysDimCode); for (i = 1; i < hdr->NS; i++) { // check for physical dimension and adjust scaling factor to "nV" avm = hdr->CHANNEL[i].Cal * 1e9 * PhysDimScale(hdr->CHANNEL[i].PhysDimCode); // check whether all channels have the same scaling factor if (fabs((AVM - avm)/AVM) > 1e-14) fprintf(stderr,"Warning SOPEN (SCP-WRITE): scaling factors differ between channel #1 and #%i. Scaling factor of 1st channel is used.\n",i+1); }; *(uint16_t*)(ptr+sectionStart+curSectLen) = l_endian_u16((uint16_t)lrint(AVM)); avm = l_endian_u16(*(uint16_t*)(ptr+sectionStart+curSectLen)); curSectLen += 2; if (fabs((AVM - avm)/AVM)>1e-14) fprintf(stderr,"Warning SOPEN (SCP-WRITE): Scaling factor has been truncated (%f instead %f).\n",avm,AVM); // Sample interval AVM = 1e6/hdr->SampleRate; *(uint16_t*)(ptr+sectionStart+curSectLen) = l_endian_u16((uint16_t)lrint(AVM)); avm = l_endian_u16(*(uint16_t*)(ptr+sectionStart+curSectLen)); curSectLen += 2; if (fabs((AVM - avm)/AVM)>1e-14) fprintf(stderr,"Warning SOPEN (SCP-WRITE): Sampling interval has been truncated (%f instead %f us).\n",avm,AVM); // Diff used *(ptr+sectionStart+curSectLen++) = 0; // Bimodal/Non-bimodal *(ptr+sectionStart+curSectLen++) = 0; /* DATA COMPRESSION currently, no compression method is supported. In case of data compression, the data compression can happen here. */ // Fill the length block for (i = 0; i < hdr->NS; i++) { *(uint16_t*)(ptr+sectionStart+curSectLen) = l_endian_u16((uint16_t)hdr->data.size[0]*2); avm = l_endian_u16(*(uint16_t*)(ptr+sectionStart+curSectLen)); AVM = hdr->data.size[0]*2; if (fabs((AVM - avm)/AVM)>1e-14) fprintf(stderr,"Warning SOPEN (SCP-WRITE): Block length truncated (%f instead %f us).\n",avm,AVM); curSectLen += 2; } /* data in channel multiplexed order */ for (i = 0; i < hdr->NS; i++) { hdr->CHANNEL[i].SPR *= hdr->NRec; }; hdr->NRec = 1; // Prepare filling the data block with the ECG samples by SWRITE // free(hdr->AS.rawdata); // hdr->AS.rawdata = PtrCurSect+16+6+2*hdr->NS; curSectLen += SZ*(hdr->data.size[0]*hdr->data.size[1]); // Evaluate the size and correct it if odd if ((curSectLen % 2) != 0) { fprintf(stderr,"Warning Section 6 has an odd length\n"); *(ptr+sectionStart+curSectLen++) = 0; } memset(ptr+sectionStart+10,0,6); // reserved aECG->Section6.StartPtr = sectionStart; aECG->Section6.Length = curSectLen; } else if (curSect==7) // SECTION 7
void ChordRest::layoutArticulations() { if (parent() == 0 || _articulations.isEmpty()) return; qreal _spatium = spatium(); qreal _spStaff = _spatium * staff()->lineDistance(); // scaled to staff line distance for vert. pos. within a staff if (type() == Element::Type::CHORD) { if (_articulations.size() == 1) { static_cast<Chord*>(this)->layoutArticulation(_articulations[0]); return; } if (_articulations.size() == 2) { // // staccato | tenuto + marcato // Articulation* a1 = _articulations[0]; Articulation* a2 = _articulations[1]; ArticulationType st1 = a1->articulationType(); ArticulationType st2 = a2->articulationType(); if ((st2 == ArticulationType::Tenuto || st2 == ArticulationType::Staccato) && (st1 == ArticulationType::Marcato)) { qSwap(a1, a2); qSwap(st1, st2); } if ((st1 == ArticulationType::Tenuto || st1 == ArticulationType::Staccato) && (st2 == ArticulationType::Marcato)) { QPointF pt = static_cast<Chord*>(this)->layoutArticulation(a1); pt.ry() += a1->up() ? -_spStaff * .5 : _spStaff * .5; a2->layout(); a2->setUp(a1->up()); a2->setPos(pt); a2->adjustReadPos(); return; } // // staccato | tenuto + sforzato // if ((st2 == ArticulationType::Tenuto || st2 == ArticulationType::Staccato) && (st1 == ArticulationType::Sforzatoaccent)) { qSwap(a1, a2); qSwap(st1, st2); } if ((st1 == ArticulationType::Tenuto || st1 == ArticulationType::Staccato) && (st2 == ArticulationType::Sforzatoaccent)) { QPointF pt = static_cast<Chord*>(this)->layoutArticulation(a1); pt.ry() += a1->up() ? -_spStaff * .7 : _spStaff * .7; a2->layout(); a2->setUp(a1->up()); a2->setPos(pt); a2->adjustReadPos(); return; } } } qreal x = centerX(); qreal distance0 = score()->styleS(StyleIdx::propertyDistance).val() * _spatium; qreal distance1 = score()->styleS(StyleIdx::propertyDistanceHead).val() * _spatium; qreal distance2 = score()->styleS(StyleIdx::propertyDistanceStem).val() * _spatium; qreal chordTopY = upPos(); // note position of highest note qreal chordBotY = downPos(); // note position of lowest note qreal staffTopY = -distance2; qreal staffBotY = staff()->height() + distance2; // avoid collisions of staff articulations with chord notes: // gap between note and staff articulation is distance0 + 0.5 spatium if (type() == Element::Type::CHORD) { Chord* chord = static_cast<Chord*>(this); Stem* stem = chord->stem(); if (stem) { qreal y = stem->pos().y() + pos().y(); if (up() && stem->stemLen() < 0.0) y += stem->stemLen(); else if (!up() && stem->stemLen() > 0.0) y -= stem->stemLen(); if (beam()) { qreal bw = score()->styleS(StyleIdx::beamWidth).val() * _spatium; y += up() ? -bw : bw; } if (up()) staffTopY = qMin(staffTopY, qreal(y - 0.5 * _spatium)); else staffBotY = qMax(staffBotY, qreal(y + 0.5 * _spatium)); } } staffTopY = qMin(staffTopY, qreal(chordTopY - distance0 - 0.5 * _spatium)); staffBotY = qMax(staffBotY, qreal(chordBotY + distance0 + 0.5 * _spatium)); qreal dy = 0.0; int n = _articulations.size(); for (int i = 0; i < n; ++i) { Articulation* a = _articulations.at(i); // // determine MScore::Direction // if (a->direction() != MScore::Direction::AUTO) { a->setUp(a->direction() == MScore::Direction::UP); } else { if (a->anchor() == ArticulationAnchor::CHORD) a->setUp(!up()); else a->setUp(a->anchor() == ArticulationAnchor::TOP_STAFF || a->anchor() == ArticulationAnchor::TOP_CHORD); } } // // pass 1 // place tenuto and staccato // for (int i = 0; i < n; ++i) { Articulation* a = _articulations.at(i); a->layout(); ArticulationAnchor aa = a->anchor(); if ((a->articulationType() != ArticulationType::Tenuto) && (a->articulationType() != ArticulationType::Staccato)) continue; if (aa != ArticulationAnchor::CHORD && aa != ArticulationAnchor::TOP_CHORD && aa != ArticulationAnchor::BOTTOM_CHORD) continue; bool bottom; if ((aa == ArticulationAnchor::CHORD) && measure()->hasVoices(a->staffIdx())) bottom = !up(); else bottom = (aa == ArticulationAnchor::BOTTOM_CHORD) || (aa == ArticulationAnchor::CHORD && up()); bool headSide = bottom == up(); dy += distance1; qreal y; Chord* chord = static_cast<Chord*>(this); if (bottom) { int line = downLine(); y = chordBotY + dy; if (!headSide && type() == Element::Type::CHORD && chord->stem()) { Stem* stem = chord->stem(); y = chordTopY + stem->stemLen(); if (chord->beam()) y += score()->styleS(StyleIdx::beamWidth).val() * _spatium * .5; x = stem->pos().x(); int line = lrint((y+0.5*_spatium) / _spatium); if (line <= 4) // align between staff lines y = line * _spatium + _spatium * .5; else y += _spatium; } else { int lines = (staff()->lines() - 1) * 2; if (line < lines) y = (line & ~1) + 3; else y = line + 2; y *= _spatium * .5; } } else { int line = upLine(); y = chordTopY - dy; if (!headSide && type() == Element::Type::CHORD && chord->stem()) { Stem* stem = chord->stem(); y = chordBotY + stem->stemLen(); if (chord->beam()) y -= score()->styleS(StyleIdx::beamWidth).val() * _spatium * .5; x = stem->pos().x(); int line = lrint((y-0.5*_spatium) / _spatium); if (line >= 0) // align between staff lines y = line * _spatium - _spatium * .5; else y -= _spatium; } else { if (line > 0) y = ((line+1) & ~1) - 3; else y = line - 2; y *= _spatium * .5; } } dy += _spatium * .5; a->setPos(x, y); } // reserve space for slur bool botGap = false; bool topGap = false; #if 0 // TODO-S: optimize for (Spanner* sp = _spannerFor; sp; sp = sp->next()) { if (sp->type() != SLUR) continue; Slur* s = static_cast<Slur*>(sp); if (s->up()) topGap = true; else botGap = true; } for (Spanner* sp = _spannerBack; sp; sp = sp->next()) { if (sp->type() != SLUR) continue; Slur* s = static_cast<Slur*>(sp); if (s->up()) topGap = true; else botGap = true; } #endif if (botGap) chordBotY += _spatium; if (topGap) chordTopY -= _spatium; // // pass 2 // place all articulations with anchor at chord/rest // n = _articulations.size(); for (int i = 0; i < n; ++i) { Articulation* a = _articulations.at(i); a->layout(); ArticulationAnchor aa = a->anchor(); if ((a->articulationType() == ArticulationType::Tenuto) || (a->articulationType() == ArticulationType::Staccato)) continue; if (aa != ArticulationAnchor::CHORD && aa != ArticulationAnchor::TOP_CHORD && aa != ArticulationAnchor::BOTTOM_CHORD) continue; // for tenuto and staccate check for staff line collision bool staffLineCT = a->articulationType() == ArticulationType::Tenuto || a->articulationType() == ArticulationType::Staccato; // qreal sh = a->bbox().height() * mag(); bool bottom = (aa == ArticulationAnchor::BOTTOM_CHORD) || (aa == ArticulationAnchor::CHORD && up()); dy += distance1; if (bottom) { qreal y = chordBotY + dy; if (staffLineCT && (y <= staffBotY -.1 - dy)) { qreal l = y / _spatium; qreal delta = fabs(l - round(l)); if (delta < 0.4) { y += _spatium * .5; dy += _spatium * .5; } } a->setPos(x, y); // - a->bbox().y() + a->bbox().height() * .5); } else { qreal y = chordTopY - dy; if (staffLineCT && (y >= (staffTopY +.1 + dy))) { qreal l = y / _spatium; qreal delta = fabs(l - round(l)); if (delta < 0.4) { y -= _spatium * .5; dy += _spatium * .5; } } a->setPos(x, y); // + a->bbox().y() - a->bbox().height() * .5); } } // // pass 3 // now place all articulations with staff top or bottom anchor // qreal dyTop = staffTopY; qreal dyBot = staffBotY; /* if ((upPos() - _spatium) < dyTop) dyTop = upPos() - _spatium; if ((downPos() + _spatium) > dyBot) dyBot = downPos() + _spatium; */ for (int i = 0; i < n; ++i) { Articulation* a = _articulations.at(i); ArticulationAnchor aa = a->anchor(); if (aa == ArticulationAnchor::TOP_STAFF || aa == ArticulationAnchor::BOTTOM_STAFF) { if (a->up()) { a->setPos(x, dyTop); dyTop -= distance0; } else { a->setPos(x, dyBot); dyBot += distance0; } } a->adjustReadPos(); } }
void FretCanvas::paintEvent(QPaintEvent* ev) { double mag = 1.5; double _spatium = 20.0 * mag; double lw1 = _spatium * 0.08; int fretOffset = diagram->fretOffset(); double lw2 = fretOffset ? lw1 : _spatium * 0.2; double stringDist = _spatium * .7; double fretDist = _spatium * .8; int _strings = diagram->strings(); int _frets = diagram->frets(); // char* _dots = diagram->dots(); // char* _marker = diagram->marker(); double w = (_strings - 1) * stringDist; double xo = (width() - w) * .5; double h = (_frets * fretDist) + fretDist * .5; double yo = (height() - h) * .5; QFont font("FreeSans"); int size = lrint(18.0 * mag); font.setPixelSize(size); QPainter p(this); p.setRenderHint(QPainter::Antialiasing, preferences.antialiasedDrawing); p.setRenderHint(QPainter::TextAntialiasing, true); p.translate(xo, yo); QPen pen(p.pen()); pen.setWidthF(lw2); pen.setCapStyle(Qt::FlatCap); p.setPen(pen); p.setBrush(pen.color()); double x2 = (_strings-1) * stringDist; p.drawLine(QLineF(-lw1 * .5, 0.0, x2+lw1*.5, 0.0)); pen.setWidthF(lw1); p.setPen(pen); double y2 = (_frets+1) * fretDist - fretDist*.5; for (int i = 0; i < _strings; ++i) { double x = stringDist * i; p.drawLine(QLineF(x, fretOffset ? -_spatium*.2 : 0.0, x, y2)); } for (int i = 1; i <= _frets; ++i) { double y = fretDist * i; p.drawLine(QLineF(0.0, y, x2, y)); } for (int i = 0; i < _strings; ++i) { p.setPen(Qt::NoPen); if (diagram->dot(i)) { double dotd = stringDist * .6 + lw1; int fret = diagram->dot(i) - 1; double x = stringDist * i - dotd * .5; double y = fretDist * fret + fretDist * .5 - dotd * .5; p.drawEllipse(QRectF(x, y, dotd, dotd)); } p.setPen(pen); if (diagram->marker(i)) { p.setFont(font); double x = stringDist * i; double y = -fretDist * .1; p.drawText(QRectF(x, y, 0.0, 0.0), Qt::AlignHCenter | Qt::AlignBottom | Qt::TextDontClip, QChar(diagram->marker(i))); } } if ((cfret > 0) && (cfret <= _frets) && (cstring >= 0) && (cstring < _strings)) { double dotd; if (diagram->dot(cstring) != cfret) { p.setPen(Qt::NoPen); dotd = stringDist * .6 + lw1; } else { p.setPen(pen); dotd = stringDist * .6; } double x = stringDist * cstring - dotd * .5; double y = fretDist * (cfret-1) + fretDist * .5 - dotd * .5; p.setBrush(Qt::lightGray); p.drawEllipse(QRectF(x, y, dotd, dotd)); } if (fretOffset > 0) { qreal fretNumMag = 2.0; // TODO: get the value from StyleIdx::fretNumMag QFont scaledFont(font); scaledFont.setPixelSize(font.pixelSize() * fretNumMag); p.setFont(scaledFont); p.setPen(pen); // Todo: make dependant from StyleIdx::fretNumPos p.drawText(QRectF(-stringDist * .4, 0.0, 0.0, fretDist), Qt::AlignVCenter|Qt::AlignRight|Qt::TextDontClip, QString("%1").arg(fretOffset+1)); p.setFont(font); } QFrame::paintEvent(ev); }
int Ruler::pos2pix(const Pos& p) const { return lrint((p.time(_timeType)+480) * _xmag) + MAP_OFFSET - _xpos; }
int main(int argc, char *argv[]) { printf("Cheetah for SACLA new offline API -- version 180705\n"); printf(" by Takanori Nakane\n"); printf(" This program is based on cheetah-sacla by Anton Barty.\n"); int c, retno; // default values int runNumber = -1; char cheetahIni[4096] = {}; double pd1_threshold = 0, pd2_threshold = 0, pd3_threshold = 0; char *pd1_sensor_name = "xfel_bl_3_st_4_pd_laser_fitting_peak/voltage"; char *pd2_sensor_name = "xfel_bl_3_st_4_pd_user_10_fitting_peak/voltage"; char *pd3_sensor_name = "xfel_bl_3_st_4_pd_user_10_fitting_peak/voltage"; // same as pd2 (dummy) int parallel_block = -1; int light_dark = PD_ANY; char outputH5[4096] = {}; char *tagList_file = NULL; const struct option longopts[] = { {"ini", 1, NULL, 'i'}, {"output", 1, NULL, 'o'}, {"run", 1, NULL, 'r'}, {"maxI", 1, NULL, 'm'}, {"stride", 1, NULL, 11}, {"station", 1, NULL, 12}, {"pd1_thresh", 1, NULL, 13}, {"pd2_thresh", 1, NULL, 14}, {"type", 1, NULL, 15}, {"list", 1, NULL, 16}, {"pd1_name", 1, NULL, 17}, {"pd2_name", 1, NULL, 18}, {"pd3_thresh", 1, NULL, 19}, {"pd3_name", 1, NULL, 20}, {"bl", 1, NULL, 21}, {0, 0, NULL, 0} }; while ((c = getopt_long(argc, argv, "i:r:m:o:", longopts, NULL)) != -1) { switch(c) { case 'i': strncpy(cheetahIni, optarg, 4096); break; case 'o': strncpy(outputH5, optarg, 4096); break; case 'r': runNumber = atoi(optarg); break; case 'm': printf("WARNING: LLF is no longer supported. Thus, maxI option is ignored.\n"); break; case 11: //stride printf("WARNING: stride option is no longer supported; ignored.\n"); break; case 12: // station printf("WARNING: LLF is no longer supported. Thus, station option is ignored.\n"); break; case 13: // pd1_thresh pd1_threshold = atof(optarg); break; case 14: // pd2_thresh pd2_threshold = atof(optarg); break; case 19: // pd3_thresh pd3_threshold = atof(optarg); break; case 15: // type if (strcmp(optarg, "light") == 0) { light_dark = PD_LIGHT; } else if (strcmp(optarg, "dark") == 0) { light_dark = PD_DARK_ANY; } else if (strlen(optarg) == 5 && optarg[0] == 'd' && optarg[1] == 'a' && optarg[2] == 'r' && optarg[3] == 'k' ) { // darkN light_dark = optarg[4] - '0'; if (light_dark < 1 || light_dark > 9) { printf("ERROR: wrong type.\n"); return -1; } } else { parallel_block = atoi(optarg); if (parallel_block < -1 || parallel_block >= parallel_size) { printf("ERROR: wrong type or parallel_block.\n"); return -1; } break; } break; case 16: // list if (tagList_file != NULL) { printf("ERROR: you cannot specify more than one tag list.\n"); return -1; } tagList_file = strdup(optarg); printf("A tag list file was specified. maxI check was disabled.\n"); break; case 17: // pd1_name pd1_sensor_name = strdup(optarg); // small leak. break; case 18: // pd2_name pd2_sensor_name = strdup(optarg); // small leak. break; case 20: // pd3_name pd3_sensor_name = strdup(optarg); // small leak. break; case 21: // bl bl = atoi(optarg); if (bl != 2 && bl != 3) { printf("ERROR: beamline must be 2 or 3.\n"); return -1; } break; } } if (strnlen(outputH5, 4096) == 0) { snprintf(outputH5, 4096, "run%d.h5", runNumber); } printf("\nConfigurations:\n"); printf(" runNumber (-r/--run): %d\n", runNumber); printf(" cheetah ini file (-i/--ini): %s\n", cheetahIni); printf(" output H5 file (-o/--output): %s (default = run######.h5)\n", outputH5); printf(" beamline (--bl): %d (default = 3)\n", bl); printf(" PD1 threshold (--pd1_thresh): %.3f (default = 0; ignore.)\n", pd1_threshold); printf(" PD2 threshold (--pd2_thresh): %.3f (default = 0; ignore.)\n", pd2_threshold); printf(" PD3 threshold (--pd3_thresh): %.3f (default = 0; ignore.)\n", pd3_threshold); printf(" PD1 sensor name (--pd1_name): %s)\n", pd1_sensor_name); printf(" PD2 sensor name (--pd2_name): %s)\n", pd2_sensor_name); printf(" PD3 sensor name (--pd3_name): %s)\n", pd3_sensor_name); printf(" nFrame after light: %d (default = -1; accept all image. -2; accept all dark images)\n", light_dark); printf(" parallel_block: %d (default = -1; no parallelization)\n", parallel_block); if (runNumber < 0 || strlen(cheetahIni) == 0) { printf("Wrong argument! \nUsage: cheetah-sacla-api -i cheetah.ini -r runNumber\n"); return -1; } /* * Initialise Cheetah */ printf("\nSetting up Cheetah...\n"); static uint32_t ntriggers = 0; static long frameNumber = 0; static cGlobal cheetahGlobal; char message[512]; static time_t startT = 0; time(&startT); strcpy(cheetahGlobal.configFile, cheetahIni); cheetahInit(&cheetahGlobal); cheetahGlobal.runNumber = runNumber; strncpy(cheetahGlobal.cxiFilename, outputH5, MAX_FILENAME_LENGTH); printf("\n"); hsize_t dims[2]; dims[0] = NDET * ysize; dims[1] = xsize; // get tag_hi and start int tag_hi, tag_start, tag_end; retno = sy_read_start_tagnumber(&tag_hi, &tag_start, bl, runNumber); if (retno != 0) { printf("ERROR: Cannot read run %d.\n", runNumber); printf("If this run is before Nov 2014, please use the old API version.\n"); return -1; } retno = sy_read_end_tagnumber(&tag_hi, &tag_end, bl, runNumber); // How many dark frames? struct da_int_array *tagbuf; int numAll; da_alloc_int_array(&tagbuf, 0, NULL); sy_read_taglist_byrun(tagbuf, bl, runNumber); da_getsize_int_array(&numAll, tagbuf); printf("Run %d contains tag %d (inclusive) to %d (exclusive), thus %d images\n", runNumber, tag_start, tag_end, numAll); int *tagAll = (int*)malloc(sizeof(int) * numAll); for (int i = 0; i < numAll; i++) { da_getint_int_array(tagAll + i, tagbuf, i); } da_destroy_int_array(&tagbuf); bool workaround_18feb = (bl == 2) && (runNumber >= 32348); std::vector<std::string> shutterAll; if ((workaround_18feb && myReadSyncDataList(&shutterAll, "xfel_bl_2_st_3_bm_1_pd/charge", tag_hi, numAll, tagAll) != 0) || (bl == 3 && myReadSyncDataList(&shutterAll, "xfel_bl_3_shutter_1_open_valid/status", tag_hi, numAll, tagAll) != 0) || (bl == 2 && myReadSyncDataList(&shutterAll, "xfel_bl_2_shutter_1_open_valid/status", tag_hi, numAll, tagAll) != 0)) { printf("Failed to get shutter status.\n"); return -1; } if (workaround_18feb) printf("Warning: applyied workaround for unreliable shutter status since 18 feb.\n"); int numDark = 0; for (int i = 0; i < numAll; i++) { tag_start = tagAll[i]; if (shutterAll[i] != "saturated" && (shutterAll[i] == "not-converged" || atoi(shutterAll[i].c_str()) == 0)) { numDark++; } else { break; } } printf("Number of dark frames: %d\nThus, exposed images start from %d\n\n", numDark, tag_start); int parallel_cnt = 0; std::vector<int> tagList; if (tagList_file == NULL) { int blockstart = numDark, blockend = numAll - 1; // inclusive if (parallel_block != -1) { // block division int width = (numAll - numDark + 1) / parallel_size; blockstart = numDark + width * parallel_block; blockend = numDark + width * (parallel_block + 1) - 1; if (parallel_block == parallel_size - 1) { // last block blockend = numAll - 1; } } printf("parallel: start %d end %d blockstart %d blockend %d\n", tagAll[0], tagAll[numAll - 1], tagAll[blockstart], tagAll[blockend]); for (int i = blockstart; i <= blockend; i++) { tagList.push_back(tagAll[i]); } } else { FILE *fh = fopen(tagList_file, "r"); free(tagList_file); if (fh == NULL) { printf("ERROR: Unable to open tagList.\n"); return -1; } int i = 0; while (!feof(fh)) { fscanf(fh, "%d\n", &i); if (i < tag_start || i >= tag_end) { printf("WARNING: tag %d does not belong to run %d. skipped.\n", i, runNumber); continue; } parallel_cnt++; // TODO: refactor and merge above, use block parallelization if (parallel_block == -1 || // no parallelization parallel_cnt % parallel_size == parallel_block) { tagList.push_back(i); } } fclose(fh); } free(tagAll); if (tagList.size() == 0) { printf("No images to process! Exiting...\n"); cheetahExit(&cheetahGlobal); snprintf(message, 512, "Status=Error-NoImage"); cheetahGlobal.writeStatus(message); return -1; } printf("\n"); // for API int *tagList_array = (int*)malloc(sizeof(int) * tagList.size()); std::copy(tagList.begin(), tagList.end(), tagList_array); // find detector ID struct da_string_array *det_ids; int n_detid; char det_template[256] = {}; printf("Detector configulation:\n"); da_alloc_string_array(&det_ids); sy_read_detidlist(det_ids, bl, runNumber); da_getsize_string_array(&n_detid, det_ids); for (int i = 0; i < n_detid; i++) { char *detid; da_getstring_string_array(&detid, det_ids, i); printf(" detID #%02d = %s\n", i, detid); if (strncmp(detid, "MPCCD-8", 7) == 0) { int len = strlen(detid); if (detid[len - 2] == '-' && detid[len - 1] == '1') { printf(" prefix and suffix matched. using this as the detector name template.\n"); strncpy(det_template, detid, 255); } } if (strcmp(detid, "EventInfo_stor01") == 0) { printf("ERROR: This detector is not longer supported by the API. Use old Cheetah.\n"); } free(detid); } da_destroy_string_array(&det_ids); if (det_template[0] == 0) { printf("ERROR: Unknown or non-supported detector ID.\n"); cheetahExit(&cheetahGlobal); snprintf(message, 512, "Status=Error-BadDetID"); cheetahGlobal.writeStatus(message); return -1; } printf("\n"); // Create storage readers and buffers // and get detector gains printf("Initializing reader and buffer\n"); for (int det_id = 0; det_id < NDET; det_id++) { char det_name[256]; strncpy(det_name, det_template, 255); det_name[strlen(det_name) - 1] = '0' + det_id + 1; printf(" detector %s\n", det_name); retno = st_create_streader(&streaders[det_id], det_name, bl, 1, &runNumber); if (retno != 0) { printf("Failed to create streader for %s.\n", det_name); return -1; } retno = st_create_stbuf(&databufs[det_id], streaders[det_id]); if (retno != 0) { printf("Failed to allocate databuffer for %s.\n", det_name); return -1; } uint32_t tagid = tag_start; retno = st_collect_data(databufs[det_id], streaders[det_id], &tagid); if (retno != 0) { printf("Failed to collect data for %s.\n", det_name); return -1; } mp_read_absgain(&gains[det_id], databufs[det_id]); } printf("\n"); // Pulse energies (in keV) double config_photon_energy; sy_read_config_photonenergy(&config_photon_energy, bl, runNumber); std::vector<std::string> pulse_energies; if (runNumber >=333661 && runNumber <= 333682) { // 19 May 2015: spectrometer broken! use config value instead printf("Using 7000 eV to fill in missing photon energies due to DB failure during run 333661-333682\n"); for (unsigned int i = 0; i < tagList.size(); i++) { pulse_energies.push_back("7.0"); } } else { if (bl == 3) { retno = myReadSyncDataList(&pulse_energies, "xfel_bl_3_tc_spec_1/energy", tag_hi, tagList.size(), tagList_array); } else if (bl == 2) { retno = myReadSyncDataList(&pulse_energies, "xfel_bl_2_tc_spec_1/energy", tag_hi, tagList.size(), tagList_array); } if (retno != 0) { printf("Failed to get photon_energy. Exiting...\n"); cheetahExit(&cheetahGlobal); snprintf(message, 512, "Status=Error-PhotonEnergy"); cheetahGlobal.writeStatus(message); return -1; } } std::vector<std::string> pd1_values, pd2_values, pd3_values, shutter; retno = myReadSyncDataList(&pd1_values, pd1_sensor_name, tag_hi, tagList.size(), tagList_array); if (retno != 0) { printf("WARNING: Failed to get %s.\n", pd1_sensor_name); } retno = myReadSyncDataList(&pd2_values, pd2_sensor_name, tag_hi, tagList.size(), tagList_array); if (retno != 0) { printf("WARNING: Failed to get %s.\n", pd2_sensor_name); } retno = myReadSyncDataList(&pd3_values, pd3_sensor_name, tag_hi, tagList.size(), tagList_array); if (retno != 0) { printf("WARNING: Failed to get %s.\n", pd3_sensor_name); } if (bl == 3) { retno = myReadSyncDataList(&shutter, "xfel_bl_3_shutter_1_open_valid/status", tag_hi, tagList.size(), tagList_array); } else if (bl == 2) { retno = myReadSyncDataList(&shutter, "xfel_bl_2_shutter_1_open_valid/status", tag_hi, tagList.size(), tagList_array); } if (retno != 0) { printf("WARNING: Failed to get shutter status.\n"); } int processedTags = 0, LLFpassed = 0, tagSize = tagList.size(), frame_after_light = 9999; for (int j = 0; j < tagSize; j++) { int tagID = tagList[j]; printf("tag %d shutter = %s\n", tagID, shutter[j].c_str()); if (runNumber >= 358814 && runNumber <=358842) { // 2015 Oct: new run control GUI produces gaps in tag number // attempts to read such tags cause crash, so we have to skip. // For other runs, reading shutter-closed images does not cause any harm. // Actually, some runs in 2018 Feb have unreliable shuter status, so // we should NOT skip images based on shutter status! if (atoi(shutter[j].c_str()) != 1) { printf("SHUTTER: tag %d rejected. shutter = %s\n", tagID, shutter[j].c_str()); continue; } } double pd1_value = atof(pd1_values[j].c_str()); double pd2_value = atof(pd2_values[j].c_str()); double pd3_value = atof(pd3_values[j].c_str()); double photon_energy; // in eV photon_energy = 1000 * atof(pulse_energies[j].c_str()); if (photon_energy == 0) { printf("WARNING: The wavelength from the inline spectrometer for tag %d is not available\n", tagID); if (config_photon_energy < 5000 || config_photon_energy > 14000) { printf(" The accelerator config value also looks broken; assumed 7 keV as a last resort.\n"); printf(" The scale factor for this image can be wrong!!\n"); photon_energy = 7000; } else { printf(" Used the accelerator config value (%f eV) instead.\n", config_photon_energy); photon_energy = config_photon_energy; } } bool light = true; if (pd1_threshold != 0 && !(pd1_threshold > 0 && pd1_threshold <= pd1_value) && !(pd1_threshold < 0 && -pd1_threshold > pd1_value)) light = false; if (pd2_threshold != 0 && !(pd2_threshold > 0 && pd2_threshold <= pd2_value) && !(pd2_threshold < 0 && -pd2_threshold > pd2_value)) light = false; if (pd3_threshold != 0 && !(pd3_threshold > 0 && pd3_threshold <= pd3_value) && !(pd3_threshold < 0 && -pd3_threshold > pd3_value)) light = false; if (light) { frame_after_light = 0; } else { frame_after_light++; } // printf("Event %d: energy %f frame_after_light %d pd1_value %f pd2_value %f pd3_value %f\n", tagID, photon_energy, frame_after_light, pd1_value, pd2_value, pd3_value); if ((light_dark >= 0 && frame_after_light != light_dark) || (light_dark == PD_DARK_ANY && frame_after_light == 0)) continue; processedTags++; printf("Event: %d (%d / %d (%.1f%%), Filter passed %d / %d (%.1f%%), Hits %ld (%.1f%%), pd1_value = %.1f, pd2_value = %.3f, pd3_value = %.3f\n", tagID, (j + 1), tagSize, 100.0 * (j + 1) / tagSize, LLFpassed, processedTags, 100.0 * LLFpassed / processedTags, cheetahGlobal.nhits, 100.0 * cheetahGlobal.nhits / processedTags, pd1_value, pd2_value, pd3_value); LLFpassed++; if (!get_image(buffer, tagID, photon_energy)) { continue; // image not available } frameNumber++; /* * Cheetah: Calculate time beteeen processing of data frames */ time_t tnow; double dtime, datarate; time(&tnow); dtime = difftime(tnow, cheetahGlobal.tlast); if(dtime > 1.) { datarate = (frameNumber - cheetahGlobal.lastTimingFrame)/dtime; cheetahGlobal.lastTimingFrame = frameNumber; time(&cheetahGlobal.tlast); cheetahGlobal.datarate = datarate; } snprintf(message, 512, "Total=%d,Processed=%d,LLFpassed=%d,Hits=%ld,Status=Hitfinding", tagSize, (j + 1), LLFpassed, cheetahGlobal.nhits); if (processedTags % 5 == 0) { cheetahGlobal.writeStatus(message); } /* * Cheetah: Create a new eventData structure in which to place all information */ cEventData *eventData; eventData = cheetahNewEvent(&cheetahGlobal); ntriggers++; eventData->pulnixFail = 1; eventData->specFail = 1; eventData->frameNumber = tagID; eventData->runNumber = runNumber; eventData->nPeaks = 0; eventData->pumpLaserCode = 0; eventData->pumpLaserDelay = 0; eventData->photonEnergyeV = photon_energy; // in eV eventData->wavelengthA = 12398 / eventData->photonEnergyeV; // 4.1357E-15 * 2.9979E8 * 1E10 / eV (A) eventData->pGlobal = &cheetahGlobal; eventData->fiducial = tagID; // must be unique int detID = 0; long pix_nn = cheetahGlobal.detector[detID].pix_nn; // int underflow = 0, overflow = 0; for(long ii = 0; ii < pix_nn; ii++) { long tmp = lrint(buffer[ii]); if (tmp < 0) { // underflow++; printf("%ld ", tmp); tmp = 0; } else if (tmp > USHRT_MAX) { // overflow++; tmp = USHRT_MAX; } eventData->detector[detID].data_raw16[ii] = (uint16_t)tmp; } // printf("#underflow = %d, #overflow = %d\n", underflow, overflow); cheetahProcessEventMultithreaded(&cheetahGlobal, eventData); } cheetahExit(&cheetahGlobal); snprintf(message, 512, "Total=%d,Processed=%d,LLFpassed=%d,Hits=%ld,Status=Finished", tagSize, tagSize, LLFpassed, cheetahGlobal.nhits); cheetahGlobal.writeStatus(message); // Overwrite "Status: Finished" free(tagList_array); time_t endT; time(&endT); double dif = difftime(endT,startT); std::cout << "time taken: " << dif << " seconds\n"; std::cout << "Clean exit\n"; return 0; }
static size_t opt_m(const double fp, const size_t n) { return n * (size_t)lrint(-log(fp) / LOG2_SQ); }