int main(int argc, char *argv[]) { float x = 0.0; if (argv) x = lrintf((float) argc); return 0; }
static int avi_write_header(AVFormatContext *s) { AVIContext *avi = s->priv_data; ByteIOContext *pb = s->pb; int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale; AVCodecContext *stream, *video_enc; offset_t list1, list2, strh, strf; /* header list */ avi->riff_id = 0; list1 = avi_start_new_riff(avi, pb, "AVI ", "hdrl"); /* avi header */ put_tag(pb, "avih"); put_le32(pb, 14 * 4); bitrate = 0; video_enc = NULL; for(n=0;n<s->nb_streams;n++) { stream = s->streams[n]->codec; bitrate += stream->bit_rate; if (stream->codec_type == CODEC_TYPE_VIDEO) video_enc = stream; } nb_frames = 0; if(video_enc){ put_le32(pb, (uint32_t)(INT64_C(1000000) * video_enc->time_base.num / video_enc->time_base.den)); } else { put_le32(pb, 0); } put_le32(pb, bitrate / 8); /* XXX: not quite exact */ put_le32(pb, 0); /* padding */ if (url_is_streamed(pb)) put_le32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED); /* flags */ else put_le32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED); /* flags */ avi->frames_hdr_all = url_ftell(pb); /* remember this offset to fill later */ put_le32(pb, nb_frames); /* nb frames, filled later */ put_le32(pb, 0); /* initial frame */ put_le32(pb, s->nb_streams); /* nb streams */ put_le32(pb, 1024 * 1024); /* suggested buffer size */ if(video_enc){ put_le32(pb, video_enc->width); put_le32(pb, video_enc->height); } else { put_le32(pb, 0); put_le32(pb, 0); } put_le32(pb, 0); /* reserved */ put_le32(pb, 0); /* reserved */ put_le32(pb, 0); /* reserved */ put_le32(pb, 0); /* reserved */ /* stream list */ for(i=0;i<n;i++) { list2 = start_tag(pb, "LIST"); put_tag(pb, "strl"); stream = s->streams[i]->codec; /* stream generic header */ strh = start_tag(pb, "strh"); switch(stream->codec_type) { case CODEC_TYPE_VIDEO: put_tag(pb, "vids"); break; case CODEC_TYPE_AUDIO: put_tag(pb, "auds"); break; // case CODEC_TYPE_TEXT : put_tag(pb, "txts"); break; case CODEC_TYPE_DATA : put_tag(pb, "dats"); break; } if(stream->codec_type == CODEC_TYPE_VIDEO) put_le32(pb, stream->codec_tag); else put_le32(pb, 1); put_le32(pb, 0); /* flags */ put_le16(pb, 0); /* priority */ put_le16(pb, 0); /* language */ put_le32(pb, 0); /* initial frame */ ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); put_le32(pb, au_scale); /* scale */ put_le32(pb, au_byterate); /* rate */ av_set_pts_info(s->streams[i], 64, au_scale, au_byterate); put_le32(pb, 0); /* start */ avi->frames_hdr_strm[i] = url_ftell(pb); /* remember this offset to fill later */ if (url_is_streamed(pb)) put_le32(pb, AVI_MAX_RIFF_SIZE); /* FIXME: this may be broken, but who cares */ else put_le32(pb, 0); /* length, XXX: filled later */ /* suggested buffer size */ //FIXME set at the end to largest chunk if(stream->codec_type == CODEC_TYPE_VIDEO) put_le32(pb, 1024 * 1024); else if(stream->codec_type == CODEC_TYPE_AUDIO) put_le32(pb, 12 * 1024); else put_le32(pb, 0); put_le32(pb, -1); /* quality */ put_le32(pb, au_ssize); /* sample size */ put_le32(pb, 0); put_le16(pb, stream->width); put_le16(pb, stream->height); end_tag(pb, strh); if(stream->codec_type != CODEC_TYPE_DATA){ strf = start_tag(pb, "strf"); switch(stream->codec_type) { case CODEC_TYPE_VIDEO: put_bmp_header(pb, stream, codec_bmp_tags, 0); break; case CODEC_TYPE_AUDIO: if (put_wav_header(pb, stream) < 0) { av_free(avi); return -1; } break; default: return -1; } end_tag(pb, strf); } if (!url_is_streamed(pb)) { unsigned char tag[5]; int j; /* Starting to lay out AVI OpenDML master index. * We want to make it JUNK entry for now, since we'd * like to get away without making AVI an OpenDML one * for compatibility reasons. */ avi->indexes[i].entry = avi->indexes[i].ents_allocated = 0; avi->indexes[i].indx_start = start_tag(pb, "JUNK"); put_le16(pb, 4); /* wLongsPerEntry */ put_byte(pb, 0); /* bIndexSubType (0 == frame index) */ put_byte(pb, 0); /* bIndexType (0 == AVI_INDEX_OF_INDEXES) */ put_le32(pb, 0); /* nEntriesInUse (will fill out later on) */ put_tag(pb, avi_stream2fourcc(&tag[0], i, stream->codec_type)); /* dwChunkId */ put_le64(pb, 0); /* dwReserved[3] put_le32(pb, 0); Must be 0. */ for (j=0; j < AVI_MASTER_INDEX_SIZE * 2; j++) put_le64(pb, 0); end_tag(pb, avi->indexes[i].indx_start); } if( stream->codec_type == CODEC_TYPE_VIDEO && stream->sample_aspect_ratio.num>0 && stream->sample_aspect_ratio.den>0){ int vprp= start_tag(pb, "vprp"); AVRational dar = av_mul_q(stream->sample_aspect_ratio, (AVRational){stream->width, stream->height}); int num, den; av_reduce(&num, &den, dar.num, dar.den, 0xFFFF); put_le32(pb, 0); //video format = unknown put_le32(pb, 0); //video standard= unknown put_le32(pb, lrintf(1.0/av_q2d(stream->time_base))); put_le32(pb, stream->width ); put_le32(pb, stream->height); put_le16(pb, den); put_le16(pb, num); put_le32(pb, stream->width ); put_le32(pb, stream->height); put_le32(pb, 1); //progressive FIXME put_le32(pb, stream->height); put_le32(pb, stream->width ); put_le32(pb, stream->height); put_le32(pb, stream->width ); put_le32(pb, 0); put_le32(pb, 0); put_le32(pb, 0); put_le32(pb, 0); end_tag(pb, vprp); } end_tag(pb, list2); } if (!url_is_streamed(pb)) { /* AVI could become an OpenDML one, if it grows beyond 2Gb range */ avi->odml_list = start_tag(pb, "JUNK"); put_tag(pb, "odml"); put_tag(pb, "dmlh"); put_le32(pb, 248); for (i = 0; i < 248; i+= 4) put_le32(pb, 0); end_tag(pb, avi->odml_list); } end_tag(pb, list1); list2 = start_tag(pb, "LIST"); put_tag(pb, "INFO"); avi_write_info_tag(pb, "INAM", s->title); avi_write_info_tag(pb, "IART", s->author); avi_write_info_tag(pb, "ICOP", s->copyright); avi_write_info_tag(pb, "ICMT", s->comment); avi_write_info_tag(pb, "IPRD", s->album); avi_write_info_tag(pb, "IGNR", s->genre); if (s->track) { char str_track[4]; snprintf(str_track, 4, "%d", s->track); avi_write_info_tag(pb, "IPRT", str_track); } if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) avi_write_info_tag(pb, "ISFT", LIBAVFORMAT_IDENT); end_tag(pb, list2); /* some padding for easier tag editing */ list2 = start_tag(pb, "JUNK"); for (i = 0; i < 1016; i += 4) put_le32(pb, 0); end_tag(pb, list2); avi->movi_list = start_tag(pb, "LIST"); put_tag(pb, "movi"); put_flush_packet(pb); return 0; }
static int dm5_dive(void *param, int columns, char **data, char **column) { UNUSED(columns); UNUSED(column); int i; int tempformat = 0; int interval, retval = 0, block_size; struct parser_state *state = (struct parser_state *)param; sqlite3 *handle = state->sql_handle; unsigned const char *sampleBlob; char *err = NULL; char get_events_template[] = "select * from Mark where DiveId = %d"; char get_tags_template[] = "select Text from DiveTag where DiveId = %d"; char get_cylinders_template[] = "select * from DiveMixture where DiveId = %d"; char get_gaschange_template[] = "select GasChangeTime,Oxygen,Helium from DiveGasChange join DiveMixture on DiveGasChange.DiveMixtureId=DiveMixture.DiveMixtureId where DiveId = %d"; char get_events[512]; dive_start(state); state->cur_dive->number = atoi(data[0]); state->cur_dive->when = (time_t)(atol(data[1])); if (data[2]) utf8_string(data[2], &state->cur_dive->notes); if (data[3]) state->cur_dive->duration.seconds = atoi(data[3]); if (data[15]) state->cur_dive->dc.duration.seconds = atoi(data[15]); /* * TODO: the deviceid hash should be calculated here. */ settings_start(state); dc_settings_start(state); if (data[4]) { utf8_string(data[4], &state->cur_settings.dc.serial_nr); state->cur_settings.dc.deviceid = atoi(data[4]); } if (data[5]) utf8_string(data[5], &state->cur_settings.dc.model); dc_settings_end(state); settings_end(state); if (data[6]) state->cur_dive->dc.maxdepth.mm = lrint(strtod_flags(data[6], NULL, 0) * 1000); if (data[8]) state->cur_dive->dc.airtemp.mkelvin = C_to_mkelvin(atoi(data[8])); if (data[9]) state->cur_dive->dc.watertemp.mkelvin = C_to_mkelvin(atoi(data[9])); if (data[4]) { state->cur_dive->dc.deviceid = atoi(data[4]); } if (data[5]) utf8_string(data[5], &state->cur_dive->dc.model); snprintf(get_events, sizeof(get_events) - 1, get_cylinders_template, state->cur_dive->number); retval = sqlite3_exec(handle, get_events, &dm5_cylinders, state, &err); if (retval != SQLITE_OK) { fprintf(stderr, "%s", "Database query dm5_cylinders failed.\n"); return 1; } if (data[14]) state->cur_dive->dc.surface_pressure.mbar = (atoi(data[14]) / 100); interval = data[16] ? atoi(data[16]) : 0; /* * sampleBlob[0] version number, indicates the size of one sample * * Following ones describe single sample, bugs in interpretation of the binary blob are likely: * * sampleBlob[3] depth * sampleBlob[7-9] pressure * sampleBlob[11] temperature - either full Celsius or float, might be different field for some version of DM */ sampleBlob = (unsigned const char *)data[24]; if (sampleBlob) { switch (sampleBlob[0]) { case 1: // Log is converted from DM4 to DM5 block_size = 16; break; case 2: block_size = 19; break; case 3: block_size = 23; break; case 4: // Temperature is stored in float tempformat = 1; block_size = 26; break; case 5: // Temperature is stored in float tempformat = 1; block_size = 30; break; default: block_size = 16; break; } } for (i = 0; interval && sampleBlob && i * interval < state->cur_dive->duration.seconds; i++) { float *depth = (float *)&sampleBlob[i * block_size + 3]; int32_t pressure = (sampleBlob[i * block_size + 9] << 16) + (sampleBlob[i * block_size + 8] << 8) + sampleBlob[i * block_size + 7]; sample_start(state); state->cur_sample->time.seconds = i * interval; state->cur_sample->depth.mm = lrintf(depth[0] * 1000.0f); if (tempformat == 1) { float *temp = (float *)&(sampleBlob[i * block_size + 11]); state->cur_sample->temperature.mkelvin = C_to_mkelvin(*temp); } else { if ((sampleBlob[i * block_size + 11]) != 0x7F) { state->cur_sample->temperature.mkelvin = C_to_mkelvin(sampleBlob[i * block_size + 11]); } } /* * Limit cylinder pressures to somewhat sensible values */ if (pressure >= 0 && pressure < 350000) state->cur_sample->pressure[0].mbar = pressure; sample_end(state); } /* * Log was converted from DM4, thus we need to parse the profile * from DM4 format */ if (i == 0) { float *profileBlob; unsigned char *tempBlob; int *pressureBlob; profileBlob = (float *)data[17]; tempBlob = (unsigned char *)data[18]; pressureBlob = (int *)data[19]; for (i = 0; interval && i * interval < state->cur_dive->duration.seconds; i++) { sample_start(state); state->cur_sample->time.seconds = i * interval; if (profileBlob) state->cur_sample->depth.mm = lrintf(profileBlob[i] * 1000.0f); else state->cur_sample->depth.mm = state->cur_dive->dc.maxdepth.mm; if (data[18] && data[18][0]) state->cur_sample->temperature.mkelvin = C_to_mkelvin(tempBlob[i]); if (data[19] && data[19][0]) state->cur_sample->pressure[0].mbar = pressureBlob[i]; sample_end(state); } } snprintf(get_events, sizeof(get_events) - 1, get_gaschange_template, state->cur_dive->number); retval = sqlite3_exec(handle, get_events, &dm5_gaschange, state, &err); if (retval != SQLITE_OK) { fprintf(stderr, "%s", "Database query dm5_gaschange failed.\n"); return 1; } snprintf(get_events, sizeof(get_events) - 1, get_events_template, state->cur_dive->number); retval = sqlite3_exec(handle, get_events, &dm4_events, state, &err); if (retval != SQLITE_OK) { fprintf(stderr, "%s", "Database query dm4_events failed.\n"); return 1; } snprintf(get_events, sizeof(get_events) - 1, get_tags_template, state->cur_dive->number); retval = sqlite3_exec(handle, get_events, &dm4_tags, state, &err); if (retval != SQLITE_OK) { fprintf(stderr, "%s", "Database query dm4_tags failed.\n"); return 1; } dive_end(state); return SQLITE_OK; }
av_cold int swri_rematrix_init(SwrContext *s){ int i, j; int nb_in = av_get_channel_layout_nb_channels(s->in_ch_layout); int nb_out = av_get_channel_layout_nb_channels(s->out_ch_layout); s->mix_any_f = NULL; if (!s->rematrix_custom) { int r = auto_matrix(s); if (r) return r; } if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){ s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int)); s->native_one = av_mallocz(sizeof(int)); for (i = 0; i < nb_out; i++) for (j = 0; j < nb_in; j++) ((int*)s->native_matrix)[i * nb_in + j] = lrintf(s->matrix[i][j] * 32768); *((int*)s->native_one) = 32768; s->mix_1_1_f = (mix_1_1_func_type*)copy_s16; s->mix_2_1_f = (mix_2_1_func_type*)sum2_s16; s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s16(s); }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){ s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float)); s->native_one = av_mallocz(sizeof(float)); for (i = 0; i < nb_out; i++) for (j = 0; j < nb_in; j++) ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j]; *((float*)s->native_one) = 1.0; s->mix_1_1_f = (mix_1_1_func_type*)copy_float; s->mix_2_1_f = (mix_2_1_func_type*)sum2_float; s->mix_any_f = (mix_any_func_type*)get_mix_any_func_float(s); }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){ s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double)); s->native_one = av_mallocz(sizeof(double)); for (i = 0; i < nb_out; i++) for (j = 0; j < nb_in; j++) ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j]; *((double*)s->native_one) = 1.0; s->mix_1_1_f = (mix_1_1_func_type*)copy_double; s->mix_2_1_f = (mix_2_1_func_type*)sum2_double; s->mix_any_f = (mix_any_func_type*)get_mix_any_func_double(s); }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){ // Only for dithering currently // s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double)); s->native_one = av_mallocz(sizeof(int)); // for (i = 0; i < nb_out; i++) // for (j = 0; j < nb_in; j++) // ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j]; *((int*)s->native_one) = 32768; s->mix_1_1_f = (mix_1_1_func_type*)copy_s32; s->mix_2_1_f = (mix_2_1_func_type*)sum2_s32; s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s32(s); }else av_assert0(0); //FIXME quantize for integeres for (i = 0; i < SWR_CH_MAX; i++) { int ch_in=0; for (j = 0; j < SWR_CH_MAX; j++) { s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768); if(s->matrix[i][j]) s->matrix_ch[i][++ch_in]= j; } s->matrix_ch[i][0]= ch_in; } if(HAVE_YASM && HAVE_MMX) swri_rematrix_init_x86(s); return 0; }
/*---------------------------------------------------------------------------- | Software IEC/IEEE single-precision conversion routines. *----------------------------------------------------------------------------*/ int float32_to_int32( float32 a STATUS_PARAM) { return long_to_int32(lrintf(a)); }
void* seam_progress(void *arg) { const int n = labs(*(int*)arg); const float fn = n; #ifdef ANDROID_BUILD char progBuf[500]; JNIEnv *env; jmethodID updateProgMID; (*cachedJvm)->AttachCurrentThread(cachedJvm, &env, NULL); jstring progStr; jclass mainActivityClass = (*env)->GetObjectClass(env, cachedMainActObj); updateProgMID = (*env)->GetMethodID(env, mainActivityClass, "updateProgress", "(Ljava/lang/String;I)V"); if (NULL == updateProgMID) { LOGE(1, "error finding method updateProgress at seam_progress"); (*cachedJvm)->DetachCurrentThread(cachedJvm); pthread_exit((void*)NULL); } #endif // printf("Fugensuche: ges. erm. %% Fu/s Dauer verstr. verbl.\n %4d ", n); #ifdef ANDROID_BUILD sprintf(progBuf, "%s\n", MSG[I_COMPUTING_TABLE]); progStr = (*env)->NewStringUTF(env, progBuf); (*env)->CallVoidMethod(env, cachedMainActObj, updateProgMID, progStr, 0); #else puts(MSG[I_COMPUTING_TABLE]); printf(" %4d ", n); #endif int i = 0, s = 0; bool goon = true; do { sleep_sync(500); s = sc_seam_progress(); goon = (s < n); const int ela = i >> 1; const float rate = ela? (float)(s) / (float)(ela): 1; const int lrate = lrintf(rate), pc = (float)(s * 100) / fn; if ((i++ & 1) && goon) { printf("%4d %3d %4d\b\b\b\b\b\b\b\b\b\b\b\b\b\b ", s, pc, lrate); } else { const int ttl = lrintf(n / rate); struct hms_s tela, trem, tttl; ftime(ela, &tela); ftime(ttl - ela, &trem); ftime(ttl, &tttl); #ifdef ANDROID_BUILD sprintf(progBuf, "%4d %4d %3d %4d " "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d", n, s, pc, lrate, tttl.h, tttl.m, tttl.s, tela.h, tela.m, tela.s, trem.h, trem.m, trem.s ); progStr = (*env)->NewStringUTF(env, progBuf); (*env)->CallVoidMethod(env, cachedMainActObj, updateProgMID, progStr, 1); #else printf( "%4d %3d %4d " "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d" "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", s, pc, lrate, tttl.h, tttl.m, tttl.s, tela.h, tela.m, tela.s, trem.h, trem.m, trem.s ); #endif } } while (goon); #ifdef ANDROID_BUILD (*cachedJvm)->DetachCurrentThread(cachedJvm); #endif pthread_exit((void*)NULL); }
static void to_PCM_16bit(NeAACDecHandle hDecoder, real_t **input, uint8_t channels, uint16_t frame_len, int16_t **sample_buffer) { uint8_t ch, ch1; uint16_t i; switch (CONV(channels,hDecoder->downMatrix)) { case CONV(1,0): case CONV(1,1): for(i = 0; i < frame_len; i++) { real_t inp = input[hDecoder->internal_channel[0]][i]; CLIP(inp, 32767.0f, -32768.0f); (*sample_buffer)[i] = (int16_t)lrintf(inp); } break; case CONV(2,0): if (hDecoder->upMatrix) { ch = hDecoder->internal_channel[0]; for(i = 0; i < frame_len; i++) { real_t inp0 = input[ch][i]; CLIP(inp0, 32767.0f, -32768.0f); (*sample_buffer)[(i*2)+0] = (int16_t)lrintf(inp0); (*sample_buffer)[(i*2)+1] = (int16_t)lrintf(inp0); } } else { ch = hDecoder->internal_channel[0]; ch1 = hDecoder->internal_channel[1]; for(i = 0; i < frame_len; i++) { real_t inp0 = input[ch ][i]; real_t inp1 = input[ch1][i]; CLIP(inp0, 32767.0f, -32768.0f); CLIP(inp1, 32767.0f, -32768.0f); (*sample_buffer)[(i*2)+0] = (int16_t)lrintf(inp0); (*sample_buffer)[(i*2)+1] = (int16_t)lrintf(inp1); } } break; default: for (ch = 0; ch < channels; ch++) { for(i = 0; i < frame_len; i++) { real_t inp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->internal_channel); CLIP(inp, 32767.0f, -32768.0f); (*sample_buffer)[(i*channels)+ch] = (int16_t)lrintf(inp); } } break; } }
int RageSoundReader_Preload::GetNextSourceFrame() const { return lrintf(m_iPosition * m_fRate); }
bool RageSoundReader_Preload::Open( RageSoundReader *pSource ) { ASSERT( pSource != NULL ); m_iSampleRate = pSource->GetSampleRate(); m_iChannels = pSource->GetNumChannels(); m_fRate = pSource->GetStreamToSourceRatio(); int iMaxSamples = g_iSoundPreloadMaxSamples.Get(); /* Check the length, and see if we think it'll fit in the buffer. */ int iLen = pSource->GetLength_Fast(); if( iLen != -1 ) { float fSecs = iLen / 1000.f; int iFrames = lrintf( fSecs * m_iSampleRate ); /* seconds -> frames */ int iSamples = unsigned( iFrames * m_iChannels ); /* frames -> samples */ if( iSamples > iMaxSamples ) return false; /* Don't bother trying to preload it. */ int iBytes = unsigned( iSamples * samplesize ); /* samples -> bytes */ m_Buffer.Get()->reserve( iBytes ); } for(;;) { /* If the rate changes, we won't preload it. */ if( pSource->GetStreamToSourceRatio() != m_fRate ) { return false; /* Don't bother trying to preload it. */ } float buffer[1024]; int iCnt = pSource->Read( buffer, ARRAYLEN(buffer) / m_iChannels ); if( iCnt == END_OF_FILE ) { break; } if( iCnt < 0 ) { return false; } /* Add the buffer. */ if( m_bBufferIs16Bit ) { int16_t buffer16[1024]; RageSoundUtil::ConvertFloatToNativeInt16( buffer, buffer16, iCnt*m_iChannels ); m_Buffer.Get()->append( (char *) buffer16, (char *) (buffer16+iCnt*m_iChannels) ); } else { m_Buffer.Get()->append( (char *) buffer, (char *) (buffer+iCnt*m_iChannels) ); } if( m_Buffer.Get()->size() > iMaxSamples * samplesize ) { return false; /* too big */ } } m_iPosition = 0; delete pSource; return true; }
void mixTable(void) { uint32_t i; bool isFailsafeActive = failsafeIsActive(); if (motorCount >= 4 && mixerConfig()->yaw_jump_prevention_limit < YAW_JUMP_PREVENTION_LIMIT_HIGH) { // prevent "yaw jump" during yaw correction axisPID[FD_YAW] = constrain(axisPID[FD_YAW], -mixerConfig()->yaw_jump_prevention_limit - ABS(rcCommand[YAW]), mixerConfig()->yaw_jump_prevention_limit + ABS(rcCommand[YAW])); } if (rcModeIsActive(BOXAIRMODE)) { // Initial mixer concept by bdoiron74 reused and optimized for Air Mode int16_t rollPitchYawMix[MAX_SUPPORTED_MOTORS]; int16_t rollPitchYawMixMax = 0; // assumption: symetrical about zero. int16_t rollPitchYawMixMin = 0; // Find roll/pitch/yaw desired output for (i = 0; i < motorCount; i++) { rollPitchYawMix[i] = axisPID[FD_PITCH] * currentMixer[i].pitch + axisPID[FD_ROLL] * currentMixer[i].roll + -mixerConfig()->yaw_motor_direction * axisPID[FD_YAW] * currentMixer[i].yaw; if (rollPitchYawMix[i] > rollPitchYawMixMax) rollPitchYawMixMax = rollPitchYawMix[i]; if (rollPitchYawMix[i] < rollPitchYawMixMin) rollPitchYawMixMin = rollPitchYawMix[i]; } // Scale roll/pitch/yaw uniformly to fit within throttle range int16_t rollPitchYawMixRange = rollPitchYawMixMax - rollPitchYawMixMin; int16_t throttleRange, throttle; int16_t throttleMin, throttleMax; static int16_t throttlePrevious = 0; // Store the last throttle direction for deadband transitions in 3D. // Find min and max throttle based on condition. Use rcData for 3D to prevent loss of power due to min_check if (feature(FEATURE_3D)) { if (!ARMING_FLAG(ARMED)) throttlePrevious = rxConfig()->midrc; // When disarmed set to mid_rc. It always results in positive direction after arming. if ((rcData[THROTTLE] <= (rxConfig()->midrc - rcControlsConfig()->deadband3d_throttle))) { // Out of band handling throttleMax = motor3DConfig()->deadband3d_low; throttleMin = motorAndServoConfig()->minthrottle; throttlePrevious = throttle = rcData[THROTTLE]; } else if (rcData[THROTTLE] >= (rxConfig()->midrc + rcControlsConfig()->deadband3d_throttle)) { // Positive handling throttleMax = motorAndServoConfig()->maxthrottle; throttleMin = motor3DConfig()->deadband3d_high; throttlePrevious = throttle = rcData[THROTTLE]; } else if ((throttlePrevious <= (rxConfig()->midrc - rcControlsConfig()->deadband3d_throttle))) { // Deadband handling from negative to positive throttle = throttleMax = motor3DConfig()->deadband3d_low; throttleMin = motorAndServoConfig()->minthrottle; } else { // Deadband handling from positive to negative throttleMax = motorAndServoConfig()->maxthrottle; throttle = throttleMin = motor3DConfig()->deadband3d_high; } } else { throttle = rcCommand[THROTTLE]; throttleMin = motorAndServoConfig()->minthrottle; throttleMax = motorAndServoConfig()->maxthrottle; } throttleRange = throttleMax - throttleMin; if (rollPitchYawMixRange > throttleRange) { motorLimitReached = true; float mixReduction = (float) throttleRange / rollPitchYawMixRange; for (i = 0; i < motorCount; i++) { rollPitchYawMix[i] = lrintf((float) rollPitchYawMix[i] * mixReduction); } // Get the maximum correction by setting throttle offset to center. throttleMin = throttleMax = throttleMin + (throttleRange / 2); } else { motorLimitReached = false; throttleMin = throttleMin + (rollPitchYawMixRange / 2); throttleMax = throttleMax - (rollPitchYawMixRange / 2); } // Now add in the desired throttle, but keep in a range that doesn't clip adjusted // roll/pitch/yaw. This could move throttle down, but also up for those low throttle flips. for (i = 0; i < motorCount; i++) { motor[i] = rollPitchYawMix[i] + constrain(throttle * currentMixer[i].throttle, throttleMin, throttleMax); if (isFailsafeActive) { motor[i] = mixConstrainMotorForFailsafeCondition(i); } else if (feature(FEATURE_3D)) { if (throttlePrevious <= (rxConfig()->midrc - rcControlsConfig()->deadband3d_throttle)) { motor[i] = constrain(motor[i], motorAndServoConfig()->minthrottle, motor3DConfig()->deadband3d_low); } else { motor[i] = constrain(motor[i], motor3DConfig()->deadband3d_high, motorAndServoConfig()->maxthrottle); } } else { motor[i] = constrain(motor[i], motorAndServoConfig()->minthrottle, motorAndServoConfig()->maxthrottle); } } } else { // motors for non-servo mixes for (i = 0; i < motorCount; i++) { motor[i] = rcCommand[THROTTLE] * currentMixer[i].throttle + axisPID[FD_PITCH] * currentMixer[i].pitch + axisPID[FD_ROLL] * currentMixer[i].roll + -mixerConfig()->yaw_motor_direction * axisPID[FD_YAW] * currentMixer[i].yaw; } // Find the maximum motor output. int16_t maxMotor = motor[0]; for (i = 1; i < motorCount; i++) { // If one motor is above the maxthrottle threshold, we reduce the value // of all motors by the amount of overshoot. That way, only one motor // is at max and the relative power of each motor is preserved. if (motor[i] > maxMotor) { maxMotor = motor[i]; } } int16_t maxThrottleDifference = 0; if (maxMotor > motorAndServoConfig()->maxthrottle) { maxThrottleDifference = maxMotor - motorAndServoConfig()->maxthrottle; } for (i = 0; i < motorCount; i++) { // this is a way to still have good gyro corrections if at least one motor reaches its max. motor[i] -= maxThrottleDifference; if (feature(FEATURE_3D)) { if (mixerConfig()->pid_at_min_throttle || rcData[THROTTLE] <= rxConfig()->midrc - rcControlsConfig()->deadband3d_throttle || rcData[THROTTLE] >= rxConfig()->midrc + rcControlsConfig()->deadband3d_throttle) { if (rcData[THROTTLE] > rxConfig()->midrc) { motor[i] = constrain(motor[i], motor3DConfig()->deadband3d_high, motorAndServoConfig()->maxthrottle); } else { motor[i] = constrain(motor[i], motorAndServoConfig()->mincommand, motor3DConfig()->deadband3d_low); } } else { if (rcData[THROTTLE] > rxConfig()->midrc) { motor[i] = motor3DConfig()->deadband3d_high; } else { motor[i] = motor3DConfig()->deadband3d_low; } } } else { if (isFailsafeActive) { motor[i] = mixConstrainMotorForFailsafeCondition(i); } else { // If we're at minimum throttle and FEATURE_MOTOR_STOP enabled, // do not spin the motors. motor[i] = constrain(motor[i], motorAndServoConfig()->minthrottle, motorAndServoConfig()->maxthrottle); if ((rcData[THROTTLE]) < rxConfig()->mincheck) { if (feature(FEATURE_MOTOR_STOP)) { motor[i] = motorAndServoConfig()->mincommand; } else if (mixerConfig()->pid_at_min_throttle == 0) { motor[i] = motorAndServoConfig()->minthrottle; } } } } } } /* Disarmed for all mixers */ if (!ARMING_FLAG(ARMED)) { for (i = 0; i < motorCount; i++) { motor[i] = motor_disarmed[i]; } } // motor outputs are used as sources for servo mixing, so motors must be calculated before servos. #if !defined(USE_QUAD_MIXER_ONLY) && defined(USE_SERVOS) servoMixTable(); #endif }
int swr_rematrix_init(SwrContext *s){ int i, j, out_i; double matrix[64][64]={{0}}; int64_t unaccounted= s->in_ch_layout & ~s->out_ch_layout; double maxcoef=0; for(i=0; i<64; i++){ if(s->in_ch_layout & s->out_ch_layout & (1LL<<i)) matrix[i][i]= 1.0; } if(!sane_layout(s->in_ch_layout)){ av_log(s, AV_LOG_ERROR, "Input channel layout isnt supported\n"); return AVERROR(EINVAL); } if(!sane_layout(s->out_ch_layout)){ av_log(s, AV_LOG_ERROR, "Output channel layout isnt supported\n"); return AVERROR(EINVAL); } //FIXME implement dolby surround //FIXME implement full ac3 if(unaccounted & AV_CH_FRONT_CENTER){ if((s->out_ch_layout & AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO){ matrix[ FRONT_LEFT][FRONT_CENTER]+= M_SQRT1_2; matrix[FRONT_RIGHT][FRONT_CENTER]+= M_SQRT1_2; }else av_assert0(0); } if(unaccounted & AV_CH_LAYOUT_STEREO){ if(s->out_ch_layout & AV_CH_FRONT_CENTER){ matrix[FRONT_CENTER][ FRONT_LEFT]+= M_SQRT1_2; matrix[FRONT_CENTER][FRONT_RIGHT]+= M_SQRT1_2; if(s->in_ch_layout & AV_CH_FRONT_CENTER) matrix[FRONT_CENTER][ FRONT_CENTER] = s->clev*sqrt(2); }else av_assert0(0); } if(unaccounted & AV_CH_BACK_CENTER){ if(s->out_ch_layout & AV_CH_BACK_LEFT){ matrix[ BACK_LEFT][BACK_CENTER]+= M_SQRT1_2; matrix[BACK_RIGHT][BACK_CENTER]+= M_SQRT1_2; }else if(s->out_ch_layout & AV_CH_SIDE_LEFT){ matrix[ SIDE_LEFT][BACK_CENTER]+= M_SQRT1_2; matrix[SIDE_RIGHT][BACK_CENTER]+= M_SQRT1_2; }else if(s->out_ch_layout & AV_CH_FRONT_LEFT){ matrix[ FRONT_LEFT][BACK_CENTER]+= s->slev*M_SQRT1_2; matrix[FRONT_RIGHT][BACK_CENTER]+= s->slev*M_SQRT1_2; }else if(s->out_ch_layout & AV_CH_FRONT_CENTER){ matrix[ FRONT_CENTER][BACK_CENTER]+= s->slev*M_SQRT1_2; }else av_assert0(0); } if(unaccounted & AV_CH_BACK_LEFT){ if(s->out_ch_layout & AV_CH_BACK_CENTER){ matrix[BACK_CENTER][ BACK_LEFT]+= M_SQRT1_2; matrix[BACK_CENTER][BACK_RIGHT]+= M_SQRT1_2; }else if(s->out_ch_layout & AV_CH_SIDE_LEFT){ if(s->in_ch_layout & AV_CH_SIDE_LEFT){ matrix[ SIDE_LEFT][ BACK_LEFT]+= M_SQRT1_2; matrix[SIDE_RIGHT][BACK_RIGHT]+= M_SQRT1_2; }else{ matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0; matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0; } }else if(s->out_ch_layout & AV_CH_FRONT_LEFT){ matrix[ FRONT_LEFT][ BACK_LEFT]+= s->slev; matrix[FRONT_RIGHT][BACK_RIGHT]+= s->slev; }else if(s->out_ch_layout & AV_CH_FRONT_CENTER){ matrix[ FRONT_CENTER][BACK_LEFT ]+= s->slev*M_SQRT1_2; matrix[ FRONT_CENTER][BACK_RIGHT]+= s->slev*M_SQRT1_2; }else av_assert0(0); } if(unaccounted & AV_CH_SIDE_LEFT){ if(s->out_ch_layout & AV_CH_BACK_LEFT){ matrix[ BACK_LEFT][ SIDE_LEFT]+= 1.0; matrix[BACK_RIGHT][SIDE_RIGHT]+= 1.0; }else if(s->out_ch_layout & AV_CH_BACK_CENTER){ matrix[BACK_CENTER][ SIDE_LEFT]+= M_SQRT1_2; matrix[BACK_CENTER][SIDE_RIGHT]+= M_SQRT1_2; }else if(s->out_ch_layout & AV_CH_FRONT_LEFT){ matrix[ FRONT_LEFT][ SIDE_LEFT]+= s->slev; matrix[FRONT_RIGHT][SIDE_RIGHT]+= s->slev; }else if(s->out_ch_layout & AV_CH_FRONT_CENTER){ matrix[ FRONT_CENTER][SIDE_LEFT ]+= s->slev*M_SQRT1_2; matrix[ FRONT_CENTER][SIDE_RIGHT]+= s->slev*M_SQRT1_2; }else av_assert0(0); } if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){ if(s->out_ch_layout & AV_CH_FRONT_LEFT){ matrix[ FRONT_LEFT][ FRONT_LEFT_OF_CENTER]+= 1.0; matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER]+= 1.0; }else if(s->out_ch_layout & AV_CH_FRONT_CENTER){ matrix[ FRONT_CENTER][ FRONT_LEFT_OF_CENTER]+= M_SQRT1_2; matrix[ FRONT_CENTER][FRONT_RIGHT_OF_CENTER]+= M_SQRT1_2; }else av_assert0(0); } //FIXME quantize for integeres for(out_i=i=0; i<64; i++){ double sum=0; int in_i=0; int ch_in=0; for(j=0; j<64; j++){ s->matrix[out_i][in_i]= matrix[i][j]; s->matrix32[out_i][in_i]= lrintf(matrix[i][j] * 32768); if(matrix[i][j]){ s->matrix_ch[out_i][++ch_in]= in_i; sum += fabs(matrix[i][j]); } if(s->in_ch_layout & (1ULL<<j)) in_i++; } s->matrix_ch[out_i][0]= ch_in; maxcoef= FFMAX(maxcoef, sum); if(s->out_ch_layout & (1ULL<<i)) out_i++; } if(s->rematrix_volume < 0) maxcoef = -s->rematrix_volume; if(( s->out_sample_fmt < AV_SAMPLE_FMT_FLT || s->int_sample_fmt < AV_SAMPLE_FMT_FLT) && maxcoef > 1.0){ for(i=0; i<SWR_CH_MAX; i++) for(j=0; j<SWR_CH_MAX; j++){ s->matrix[i][j] /= maxcoef; s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768); } } if(s->rematrix_volume > 0){ for(i=0; i<SWR_CH_MAX; i++) for(j=0; j<SWR_CH_MAX; j++){ s->matrix[i][j] *= s->rematrix_volume; s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768); } } for(i=0; i<av_get_channel_layout_nb_channels(s->out_ch_layout); i++){ for(j=0; j<av_get_channel_layout_nb_channels(s->in_ch_layout); j++){ av_log(NULL, AV_LOG_DEBUG, "%f ", s->matrix[i][j]); } av_log(NULL, AV_LOG_DEBUG, "\n"); } return 0; }
__global__ void FloatMathPrecise() { int iX; float fX, fY; acosf(1.0f); acoshf(1.0f); asinf(0.0f); asinhf(0.0f); atan2f(0.0f, 1.0f); atanf(0.0f); atanhf(0.0f); cbrtf(0.0f); fX = ceilf(0.0f); fX = copysignf(1.0f, -2.0f); cosf(0.0f); coshf(0.0f); cospif(0.0f); cyl_bessel_i0f(0.0f); cyl_bessel_i1f(0.0f); erfcf(0.0f); erfcinvf(2.0f); erfcxf(0.0f); erff(0.0f); erfinvf(1.0f); exp10f(0.0f); exp2f(0.0f); expf(0.0f); expm1f(0.0f); fX = fabsf(1.0f); fdimf(1.0f, 0.0f); fdividef(0.0f, 1.0f); fX = floorf(0.0f); fmaf(1.0f, 2.0f, 3.0f); fX = fmaxf(0.0f, 0.0f); fX = fminf(0.0f, 0.0f); fmodf(0.0f, 1.0f); frexpf(0.0f, &iX); hypotf(1.0f, 0.0f); ilogbf(1.0f); isfinite(0.0f); fX = isinf(0.0f); fX = isnan(0.0f); j0f(0.0f); j1f(0.0f); jnf(-1.0f, 1.0f); ldexpf(0.0f, 0); lgammaf(1.0f); llrintf(0.0f); llroundf(0.0f); log10f(1.0f); log1pf(-1.0f); log2f(1.0f); logbf(1.0f); logf(1.0f); lrintf(0.0f); lroundf(0.0f); modff(0.0f, &fX); fX = nanf("1"); fX = nearbyintf(0.0f); nextafterf(0.0f, 0.0f); norm3df(1.0f, 0.0f, 0.0f); norm4df(1.0f, 0.0f, 0.0f, 0.0f); normcdff(0.0f); normcdfinvf(1.0f); fX = 1.0f; normf(1, &fX); powf(1.0f, 0.0f); rcbrtf(1.0f); remainderf(2.0f, 1.0f); remquof(1.0f, 2.0f, &iX); rhypotf(0.0f, 1.0f); fY = rintf(1.0f); rnorm3df(0.0f, 0.0f, 1.0f); rnorm4df(0.0f, 0.0f, 0.0f, 1.0f); fX = 1.0f; rnormf(1, &fX); fY = roundf(0.0f); rsqrtf(1.0f); scalblnf(0.0f, 1); scalbnf(0.0f, 1); signbit(1.0f); sincosf(0.0f, &fX, &fY); sincospif(0.0f, &fX, &fY); sinf(0.0f); sinhf(0.0f); sinpif(0.0f); sqrtf(0.0f); tanf(0.0f); tanhf(0.0f); tgammaf(2.0f); fY = truncf(0.0f); y0f(1.0f); y1f(1.0f); ynf(1, 1.0f); }
static void pidLuxFloat(pidProfile_t *pidProfile, controlRateConfig_t *controlRateConfig, uint16_t max_angle_inclination, rollAndPitchTrims_t *angleTrim, rxConfig_t *rxConfig) { float RateError, errorAngle, AngleRate, gyroRate; float ITerm,PTerm,DTerm; int32_t stickPosAil, stickPosEle, mostDeflectedPos; static float lastGyroRate[3]; static float delta1[3], delta2[3]; float delta, deltaSum; float dT; int axis; float horizonLevelStrength = 1; dT = (float)cycleTime * 0.000001f; if (FLIGHT_MODE(HORIZON_MODE)) { // Figure out the raw stick positions stickPosAil = getRcStickDeflection(FD_ROLL, rxConfig->midrc); stickPosEle = getRcStickDeflection(FD_PITCH, rxConfig->midrc); if(ABS(stickPosAil) > ABS(stickPosEle)){ mostDeflectedPos = ABS(stickPosAil); } else { mostDeflectedPos = ABS(stickPosEle); } // Progressively turn off the horizon self level strength as the stick is banged over horizonLevelStrength = (float)(500 - mostDeflectedPos) / 500; // 1 at centre stick, 0 = max stick deflection if(pidProfile->H_sensitivity == 0){ horizonLevelStrength = 0; } else { horizonLevelStrength = constrainf(((horizonLevelStrength - 1) * (100 / pidProfile->H_sensitivity)) + 1, 0, 1); } } // ----------PID controller---------- for (axis = 0; axis < 3; axis++) { // -----Get the desired angle rate depending on flight mode uint8_t rate = controlRateConfig->rates[axis]; if (axis == FD_YAW) { // YAW is always gyro-controlled (MAG correction is applied to rcCommand) 100dps to 1100dps max yaw rate AngleRate = (float)((rate + 10) * rcCommand[YAW]) / 50.0f; } else { // calculate error and limit the angle to the max inclination #ifdef GPS errorAngle = (constrain(rcCommand[axis] + GPS_angle[axis], -((int) max_angle_inclination), +max_angle_inclination) - inclination.raw[axis] + angleTrim->raw[axis]) / 10.0f; // 16 bits is ok here #else errorAngle = (constrain(rcCommand[axis], -((int) max_angle_inclination), +max_angle_inclination) - inclination.raw[axis] + angleTrim->raw[axis]) / 10.0f; // 16 bits is ok here #endif #ifdef AUTOTUNE if (shouldAutotune()) { errorAngle = autotune(rcAliasToAngleIndexMap[axis], &inclination, errorAngle); } #endif if (FLIGHT_MODE(ANGLE_MODE)) { // it's the ANGLE mode - control is angle based, so control loop is needed AngleRate = errorAngle * pidProfile->A_level; } else { //control is GYRO based (ACRO and HORIZON - direct sticks control is applied to rate PID AngleRate = (float)((rate + 20) * rcCommand[axis]) / 50.0f; // 200dps to 1200dps max yaw rate if (FLIGHT_MODE(HORIZON_MODE)) { // mix up angle error to desired AngleRate to add a little auto-level feel AngleRate += errorAngle * pidProfile->H_level * horizonLevelStrength; } } } gyroRate = gyroData[axis] * gyro.scale; // gyro output scaled to dps // --------low-level gyro-based PID. ---------- // Used in stand-alone mode for ACRO, controlled by higher level regulators in other modes // -----calculate scaled error.AngleRates // multiplication of rcCommand corresponds to changing the sticks scaling here RateError = AngleRate - gyroRate; // -----calculate P component PTerm = RateError * pidProfile->P_f[axis]; // -----calculate I component errorGyroIf[axis] = constrainf(errorGyroIf[axis] + RateError * dT * pidProfile->I_f[axis], -250.0f, 250.0f); // limit maximum integrator value to prevent WindUp - accumulating extreme values when system is saturated. // I coefficient (I8) moved before integration to make limiting independent from PID settings ITerm = errorGyroIf[axis]; //-----calculate D-term delta = gyroRate - lastGyroRate[axis]; // 16 bits is ok here, the dif between 2 consecutive gyro reads is limited to 800 lastGyroRate[axis] = gyroRate; // Correct difference by cycle time. Cycle time is jittery (can be different 2 times), so calculated difference // would be scaled by different dt each time. Division by dT fixes that. delta *= (1.0f / dT); // add moving average here to reduce noise deltaSum = delta1[axis] + delta2[axis] + delta; delta2[axis] = delta1[axis]; delta1[axis] = delta; DTerm = constrainf((deltaSum / 3.0f) * pidProfile->D_f[axis], -300.0f, 300.0f); // -----calculate total PID output axisPID[axis] = constrain(lrintf(PTerm + ITerm - DTerm), -1000, 1000); #ifdef BLACKBOX axisPID_P[axis] = PTerm; axisPID_I[axis] = ITerm; axisPID_D[axis] = -DTerm; #endif } }
static int avi_write_header(AVFormatContext *s) { AVIContext *avi = s->priv_data; AVIOContext *pb = s->pb; int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale; AVCodecContext *stream, *video_enc; int64_t list1, list2, strh, strf; AVDictionaryEntry *t = NULL; if (s->nb_streams > AVI_MAX_STREAM_COUNT) { av_log(s, AV_LOG_ERROR, "AVI does not support >%d streams\n", AVI_MAX_STREAM_COUNT); return -1; } for(n=0;n<s->nb_streams;n++) { s->streams[n]->priv_data= av_mallocz(sizeof(AVIStream)); if(!s->streams[n]->priv_data) return AVERROR(ENOMEM); } /* header list */ avi->riff_id = 0; list1 = avi_start_new_riff(s, pb, "AVI ", "hdrl"); /* avi header */ ffio_wfourcc(pb, "avih"); avio_wl32(pb, 14 * 4); bitrate = 0; video_enc = NULL; for(n=0;n<s->nb_streams;n++) { stream = s->streams[n]->codec; bitrate += stream->bit_rate; if (stream->codec_type == AVMEDIA_TYPE_VIDEO) video_enc = stream; } nb_frames = 0; if(video_enc){ avio_wl32(pb, (uint32_t)(INT64_C(1000000) * video_enc->time_base.num / video_enc->time_base.den)); } else { avio_wl32(pb, 0); } avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */ avio_wl32(pb, 0); /* padding */ if (!pb->seekable) avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED); /* flags */ else avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED); /* flags */ avi->frames_hdr_all = avio_tell(pb); /* remember this offset to fill later */ avio_wl32(pb, nb_frames); /* nb frames, filled later */ avio_wl32(pb, 0); /* initial frame */ avio_wl32(pb, s->nb_streams); /* nb streams */ avio_wl32(pb, 1024 * 1024); /* suggested buffer size */ if(video_enc){ avio_wl32(pb, video_enc->width); avio_wl32(pb, video_enc->height); } else { avio_wl32(pb, 0); avio_wl32(pb, 0); } avio_wl32(pb, 0); /* reserved */ avio_wl32(pb, 0); /* reserved */ avio_wl32(pb, 0); /* reserved */ avio_wl32(pb, 0); /* reserved */ /* stream list */ for(i=0;i<n;i++) { AVIStream *avist= s->streams[i]->priv_data; list2 = ff_start_tag(pb, "LIST"); ffio_wfourcc(pb, "strl"); stream = s->streams[i]->codec; /* stream generic header */ strh = ff_start_tag(pb, "strh"); switch(stream->codec_type) { case AVMEDIA_TYPE_SUBTITLE: // XSUB subtitles behave like video tracks, other subtitles // are not (yet) supported. if (stream->codec_id != CODEC_ID_XSUB) { av_log(s, AV_LOG_ERROR, "Subtitle streams other than DivX XSUB are not supported by the AVI muxer.\n"); return AVERROR_PATCHWELCOME; } case AVMEDIA_TYPE_VIDEO: ffio_wfourcc(pb, "vids"); break; case AVMEDIA_TYPE_AUDIO: ffio_wfourcc(pb, "auds"); break; // case AVMEDIA_TYPE_TEXT : ffio_wfourcc(pb, "txts"); break; case AVMEDIA_TYPE_DATA : ffio_wfourcc(pb, "dats"); break; } if(stream->codec_type == AVMEDIA_TYPE_VIDEO || stream->codec_id == CODEC_ID_XSUB) avio_wl32(pb, stream->codec_tag); else avio_wl32(pb, 1); avio_wl32(pb, 0); /* flags */ avio_wl16(pb, 0); /* priority */ avio_wl16(pb, 0); /* language */ avio_wl32(pb, 0); /* initial frame */ ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); avio_wl32(pb, au_scale); /* scale */ avio_wl32(pb, au_byterate); /* rate */ avpriv_set_pts_info(s->streams[i], 64, au_scale, au_byterate); avio_wl32(pb, 0); /* start */ avist->frames_hdr_strm = avio_tell(pb); /* remember this offset to fill later */ if (!pb->seekable) avio_wl32(pb, AVI_MAX_RIFF_SIZE); /* FIXME: this may be broken, but who cares */ else avio_wl32(pb, 0); /* length, XXX: filled later */ /* suggested buffer size */ //FIXME set at the end to largest chunk if(stream->codec_type == AVMEDIA_TYPE_VIDEO) avio_wl32(pb, 1024 * 1024); else if(stream->codec_type == AVMEDIA_TYPE_AUDIO) avio_wl32(pb, 12 * 1024); else avio_wl32(pb, 0); avio_wl32(pb, -1); /* quality */ avio_wl32(pb, au_ssize); /* sample size */ avio_wl32(pb, 0); avio_wl16(pb, stream->width); avio_wl16(pb, stream->height); ff_end_tag(pb, strh); if(stream->codec_type != AVMEDIA_TYPE_DATA){ strf = ff_start_tag(pb, "strf"); switch(stream->codec_type) { case AVMEDIA_TYPE_SUBTITLE: // XSUB subtitles behave like video tracks, other subtitles // are not (yet) supported. if (stream->codec_id != CODEC_ID_XSUB) break; case AVMEDIA_TYPE_VIDEO: ff_put_bmp_header(pb, stream, ff_codec_bmp_tags, 0); break; case AVMEDIA_TYPE_AUDIO: if (ff_put_wav_header(pb, stream) < 0) { return -1; } break; default: return -1; } ff_end_tag(pb, strf); if ((t = av_dict_get(s->streams[i]->metadata, "title", NULL, 0))) { avi_write_info_tag(s->pb, "strn", t->value); t = NULL; } } if (pb->seekable) { unsigned char tag[5]; int j; /* Starting to lay out AVI OpenDML master index. * We want to make it JUNK entry for now, since we'd * like to get away without making AVI an OpenDML one * for compatibility reasons. */ avist->indexes.entry = avist->indexes.ents_allocated = 0; avist->indexes.indx_start = ff_start_tag(pb, "JUNK"); avio_wl16(pb, 4); /* wLongsPerEntry */ avio_w8(pb, 0); /* bIndexSubType (0 == frame index) */ avio_w8(pb, 0); /* bIndexType (0 == AVI_INDEX_OF_INDEXES) */ avio_wl32(pb, 0); /* nEntriesInUse (will fill out later on) */ ffio_wfourcc(pb, avi_stream2fourcc(tag, i, stream->codec_type)); /* dwChunkId */ avio_wl64(pb, 0); /* dwReserved[3] avio_wl32(pb, 0); Must be 0. */ for (j=0; j < AVI_MASTER_INDEX_SIZE * 2; j++) avio_wl64(pb, 0); ff_end_tag(pb, avist->indexes.indx_start); } if( stream->codec_type == AVMEDIA_TYPE_VIDEO && s->streams[i]->sample_aspect_ratio.num>0 && s->streams[i]->sample_aspect_ratio.den>0){ int vprp= ff_start_tag(pb, "vprp"); AVRational dar = av_mul_q(s->streams[i]->sample_aspect_ratio, (AVRational){stream->width, stream->height}); int num, den; av_reduce(&num, &den, dar.num, dar.den, 0xFFFF); avio_wl32(pb, 0); //video format = unknown avio_wl32(pb, 0); //video standard= unknown avio_wl32(pb, lrintf(1.0/av_q2d(stream->time_base))); avio_wl32(pb, stream->width ); avio_wl32(pb, stream->height); avio_wl16(pb, den); avio_wl16(pb, num); avio_wl32(pb, stream->width ); avio_wl32(pb, stream->height); avio_wl32(pb, 1); //progressive FIXME avio_wl32(pb, stream->height); avio_wl32(pb, stream->width ); avio_wl32(pb, stream->height); avio_wl32(pb, stream->width ); avio_wl32(pb, 0); avio_wl32(pb, 0); avio_wl32(pb, 0); avio_wl32(pb, 0); ff_end_tag(pb, vprp); } ff_end_tag(pb, list2); } if (pb->seekable) { /* AVI could become an OpenDML one, if it grows beyond 2Gb range */ avi->odml_list = ff_start_tag(pb, "JUNK"); ffio_wfourcc(pb, "odml"); ffio_wfourcc(pb, "dmlh"); avio_wl32(pb, 248); for (i = 0; i < 248; i+= 4) avio_wl32(pb, 0); ff_end_tag(pb, avi->odml_list); } ff_end_tag(pb, list1); list2 = ff_start_tag(pb, "LIST"); ffio_wfourcc(pb, "INFO"); ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL); for (i = 0; *ff_riff_tags[i]; i++) { if ((t = av_dict_get(s->metadata, ff_riff_tags[i], NULL, AV_DICT_MATCH_CASE))) avi_write_info_tag(s->pb, t->key, t->value); } ff_end_tag(pb, list2); /* some padding for easier tag editing */ list2 = ff_start_tag(pb, "JUNK"); for (i = 0; i < 1016; i += 4) avio_wl32(pb, 0); ff_end_tag(pb, list2); avi->movi_list = ff_start_tag(pb, "LIST"); ffio_wfourcc(pb, "movi"); avio_flush(pb); return 0; }
static inline void p8idct(DCTELEM data[64], FLOAT temp[64], uint8_t *dest, int stride, int x, int y, int type){ int i; FLOAT av_unused tmp0; FLOAT s04, d04, s17, d17, s26, d26, s53, d53; FLOAT os07, os16, os25, os34; FLOAT od07, od16, od25, od34; for(i=0; i<y*8; i+=y){ s17= temp[1*x + i] + temp[7*x + i]; d17= temp[1*x + i] - temp[7*x + i]; s53= temp[5*x + i] + temp[3*x + i]; d53= temp[5*x + i] - temp[3*x + i]; od07= s17 + s53; od25= (s17 - s53)*(2*A4); #if 0 //these 2 are equivalent tmp0= (d17 + d53)*(2*A2); od34= d17*( 2*B6) - tmp0; od16= d53*(-2*B2) + tmp0; #else od34= d17*(2*(B6-A2)) - d53*(2*A2); od16= d53*(2*(A2-B2)) + d17*(2*A2); #endif od16 -= od07; od25 -= od16; od34 += od25; s26 = temp[2*x + i] + temp[6*x + i]; d26 = temp[2*x + i] - temp[6*x + i]; d26*= 2*A4; d26-= s26; s04= temp[0*x + i] + temp[4*x + i]; d04= temp[0*x + i] - temp[4*x + i]; os07= s04 + s26; os34= s04 - s26; os16= d04 + d26; os25= d04 - d26; if(type==0){ temp[0*x + i]= os07 + od07; temp[7*x + i]= os07 - od07; temp[1*x + i]= os16 + od16; temp[6*x + i]= os16 - od16; temp[2*x + i]= os25 + od25; temp[5*x + i]= os25 - od25; temp[3*x + i]= os34 - od34; temp[4*x + i]= os34 + od34; }else if(type==1){ data[0*x + i]= lrintf(os07 + od07); data[7*x + i]= lrintf(os07 - od07); data[1*x + i]= lrintf(os16 + od16); data[6*x + i]= lrintf(os16 - od16); data[2*x + i]= lrintf(os25 + od25); data[5*x + i]= lrintf(os25 - od25); data[3*x + i]= lrintf(os34 - od34); data[4*x + i]= lrintf(os34 + od34); }else if(type==2){ dest[0*stride + i]= av_clip_uint8(((int)dest[0*stride + i]) + lrintf(os07 + od07)); dest[7*stride + i]= av_clip_uint8(((int)dest[7*stride + i]) + lrintf(os07 - od07)); dest[1*stride + i]= av_clip_uint8(((int)dest[1*stride + i]) + lrintf(os16 + od16)); dest[6*stride + i]= av_clip_uint8(((int)dest[6*stride + i]) + lrintf(os16 - od16)); dest[2*stride + i]= av_clip_uint8(((int)dest[2*stride + i]) + lrintf(os25 + od25)); dest[5*stride + i]= av_clip_uint8(((int)dest[5*stride + i]) + lrintf(os25 - od25)); dest[3*stride + i]= av_clip_uint8(((int)dest[3*stride + i]) + lrintf(os34 - od34)); dest[4*stride + i]= av_clip_uint8(((int)dest[4*stride + i]) + lrintf(os34 + od34)); }else{ dest[0*stride + i]= av_clip_uint8(lrintf(os07 + od07)); dest[7*stride + i]= av_clip_uint8(lrintf(os07 - od07)); dest[1*stride + i]= av_clip_uint8(lrintf(os16 + od16)); dest[6*stride + i]= av_clip_uint8(lrintf(os16 - od16)); dest[2*stride + i]= av_clip_uint8(lrintf(os25 + od25)); dest[5*stride + i]= av_clip_uint8(lrintf(os25 - od25)); dest[3*stride + i]= av_clip_uint8(lrintf(os34 - od34)); dest[4*stride + i]= av_clip_uint8(lrintf(os34 + od34)); } } }
/* main loop */ int main (void) { uint8_t string[SCANDALLONGSTRINGSIZE]; /* can packet parameters */ sion_entry entry; char dbfilename[MAX_LINE_LENGTH]; struct timeval tstamp; /* set up signals */ signal(SIGINT, shutdown_cleanly); signal(SIGINT, shutdown_cleanly); /* set up sqlite db */ makedbfile(dbfilename, ACCURACY_DAY); FILE *textlog = fopen("../canlog/scandal.log", "a"); if (checkdbfile(dbfilename)){ init_sqlite3(&db, dbfilename, OLDDB); init_sqlite3(&dbsync, dbfilename, OLDDB); printf("CIEL: opening previous database....\n"); } else { init_sqlite3(&db, dbfilename, NEWDB); init_sqlite3(&dbsync, dbfilename, OLDDB); printf("CIEL: creating new database...\n"); } /* Set up sockets */ int numbytes; int loopcounter; char receivequeue[MAX_SOCKET_BLOCK_LENGTH]; //select() stuff fd_set master; fd_set read_fds; int fdmax; int fdcount; FD_ZERO(&master); FD_ZERO(&read_fds); //socket for receiving SION data socket_init(&sockfd_sion, &sioninfo, CIELIN_SION_HOST, CIELIN_SION_PORT, SIONOUTHOST, SIONOUTPORT) ; //socket for sending sync requests and receiving their reply socket_init(&sockfd_sync, &syncinfo, CIELOUT_SYNC_HOST, CIELOUT_SYNC_PORT, SIONIN_SYNC_HOST, SIONIN_SYNC_PORT); //socket for receiving Seven data. socket_init(&sockfd_seven, &seveninfo, CIELIN_SEVEN_HOST, CIELIN_SEVEN_PORT, SEVENOUTHOST, SEVENOUTPORT); //socket for sending these to something else eg scanalysis socket_init(&sockfd_telemout, &telemoutinfo, CIELOUT_OPEN_HOST, CIELOUT_OPEN_PORT, TELEM_TARGET_HOST , TELEM_TARGET_PORT) ; //socket for sending packed telemetry to something else eg sunswift live socket_init(&sockfd_telemout2, &telemoutinfo2, CIELOUT_OPEN_HOST2, CIELOUT_OPEN_PORT2, TELEM_TARGET_HOST2 , TELEM_TARGET_PORT2) ; //more select() stuff FD_SET(sockfd_sion, &master); FD_SET(sockfd_seven, &master); FD_SET(sockfd_sync, &master); fdmax = sockfd_sync; if (fdmax < sockfd_seven) //checking to make sure fdmax is the largest fdmax = sockfd_seven; if (fdmax < sockfd_sion) fdmax = sockfd_sion; fdmax++; //+1 as required by select() /* Set up threads */ printf("CIEL: Setting up threads...\n "); pthread_t out_thread, sync_thread_handler; int rc; rc = pthread_create(&out_thread, NULL, output_thread, NULL); if (rc) { printf("CIEL: ERROR: Return code from pthread_create for output thread is %d\n", rc); exit(-1); } /* rc = pthread_create(&sync_thread_handler, NULL, sync_thread, NULL); if (rc) { printf("CIEL: ERROR: Return code from pthread_create for sync thread is %d\n", rc); exit(-1); } */ //FIXME /* int date_is_set=0; int number_of_seconds_since_epoch = 0; int delay = 0; */ printf("CIEL: Entering main receiver loop..\n"); while ( loop ) { read_fds = master; if (select(fdmax, &read_fds, NULL, NULL, NULL) == -1) { perror("select"); exit(4); } for(fdcount = 0; fdcount <=fdmax; fdcount++ ) { //for all the socket descriptors.... if(FD_ISSET(fdcount, &read_fds)) { if (fdcount == sockfd_sion ) { /* Receiving live telemetry stream */ numbytes = socket_recv(&sockfd_sion, receivequeue, SCANDALLONGSTRINGSIZE * SOCKET_BLOCK_LENGTH); gettimeofday(&tstamp, NULL); //hurry, grab the timestamp! } else if (fdcount == sockfd_seven) { /* Receiving live control car stream */ numbytes = socket_recv(&sockfd_seven, receivequeue, SCANDALLONGSTRINGSIZE * SOCKET_BLOCK_LENGTH); gettimeofday(&tstamp, NULL); //hurry, grab the timestamp! } else if (fdcount == sockfd_sync) { /* Receiving solar car retransmission */ numbytes = socket_recv(&sockfd_sync, receivequeue, SCANDALLONGSTRINGSIZE * SOCKET_BLOCK_LENGTH); gettimeofday(&tstamp, NULL); //hurry, grab the timestamp! } } } /* Send packed frames to something else. Used in 2011 for sunswift live */ socket_send(&sockfd_telemout2, receivequeue, SCANDALLONGSTRINGSIZE * SOCKET_BLOCK_LENGTH, telemoutinfo2); /* Since each ethernet packet contains multiple CAN packets, we unpack them one by one and process them individually. */ for (loopcounter=0; loopcounter < SOCKET_BLOCK_LENGTH; loopcounter++) { //extract an individual packet memmove(string, &receivequeue[(SCANDALLONGSTRINGSIZE*loopcounter)], SCANDALLONGSTRINGSIZE); //TODO: Fix the Scandal Channel messages etc timestamps to full 64-bit. longstringtoentry(string, &entry); entry.ciel_timestamp = (((uint64_t) tstamp.tv_sec) * 1000) + ( (uint64_t) lrintf( ((float) tstamp.tv_usec) / 1000 ) ); entrytostring(&entry, string); //we don't send everything to scanalysis socket_send(&sockfd_telemout, string, SCANDALSTRINGSIZE, telemoutinfo); //to scanalysis //FIXME: plaintext log, not needed fprintf(textlog,"%d\t%d\t%d\t%d\t%d\t%llu\t%llu\t%u\n\r", entry.priority, entry.message_type, entry.source_address, entry.specifics, entry.value, entry.scandal_timestamp, entry.ciel_timestamp, entry.pkt_id); queue_can_packet(db, &entry, SQLITE_BLOCKLEN); //duplicate packets are ignored by sqlite /* Debug function. Do not print too much UART or you'll slow everything down. */ #define SION_DEBUG #ifdef SION_DEBUG //printf_sion_entry(&entry); printf("%llu\t%u\n\r", entry.scandal_timestamp, entry.pkt_id); #endif } //end processing individual packets }// end infinite loop shutdown_sqlite3(db);//why is this even here return 0; //makes compiler happy }
CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 , *(const uint8_t*)pi) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80U)<<8) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80U)<<24) CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0f/ (1<<7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7))) CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t*)pi<<16) CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0f/ (1<<15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15))) CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi>>16) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, *(const int32_t*)pi) CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0f/ (1U<<31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1U<<31))) CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8( lrintf(*(const float*)pi * (1<<7)) + 0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16( lrintf(*(const float*)pi * (1<<15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31)))) CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_FLT, *(const float*)pi) CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi) CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8( lrint(*(const double*)pi * (1<<7)) + 0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16( lrint(*(const double*)pi * (1<<15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31)))) CONV_FUNC(AV_SAMPLE_FMT_FLT, float , AV_SAMPLE_FMT_DBL, *(const double*)pi) CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi) #define FMT_PAIR_FUNC(out, in) [(out) + AV_SAMPLE_FMT_NB*(in)] = CONV_FUNC_NAME(out, in) static conv_func_type * const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB*AV_SAMPLE_FMT_NB] = { FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_U8 ), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8 ),
void imuInit() { smallAngle = lrintf(acc_1G * cos_approx(degreesToRadians(imuRuntimeConfig->small_angle))); accVelScale = 9.80665f / acc_1G / 10000.0f; gyroScaleRad = gyro.scale * (M_PIf / 180.0f) * 0.000001f; }
/** * builds a polyphase filterbank. * @param factor resampling factor * @param scale wanted sum of coefficients for each filter * @param filter_type filter type * @param kaiser_beta kaiser window beta * @return 0 on success, negative on error */ static int build_filter(ResampleContext *c, void *filter, double factor, int tap_count, int alloc, int phase_count, int scale, int filter_type, double kaiser_beta){ int ph, i; int ph_nb = phase_count % 2 ? phase_count : phase_count / 2 + 1; double x, y, w, t, s; double *tab = av_malloc_array(tap_count+1, sizeof(*tab)); double *sin_lut = av_malloc_array(ph_nb, sizeof(*sin_lut)); const int center= (tap_count-1)/2; int ret = AVERROR(ENOMEM); if (!tab || !sin_lut) goto fail; /* if upsampling, only need to interpolate, no filter */ if (factor > 1.0) factor = 1.0; if (factor == 1.0) { for (ph = 0; ph < ph_nb; ph++) sin_lut[ph] = sin(M_PI * ph / phase_count); } for(ph = 0; ph < ph_nb; ph++) { double norm = 0; s = sin_lut[ph]; for(i=0;i<=tap_count;i++) { x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor; if (x == 0) y = 1.0; else if (factor == 1.0) y = s / x; else y = sin(x) / x; switch(filter_type){ case SWR_FILTER_TYPE_CUBIC:{ const float d= -0.5; //first order derivative = -0.5 x = fabs(((double)(i - center) - (double)ph / phase_count) * factor); if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*( -x*x + x*x*x); else y= d*(-4 + 8*x - 5*x*x + x*x*x); break;} case SWR_FILTER_TYPE_BLACKMAN_NUTTALL: w = 2.0*x / (factor*tap_count); t = -cos(w); y *= 0.3635819 - 0.4891775 * t + 0.1365995 * (2*t*t-1) - 0.0106411 * (4*t*t*t - 3*t); break; case SWR_FILTER_TYPE_KAISER: w = 2.0*x / (factor*tap_count*M_PI); y *= bessel(kaiser_beta*sqrt(FFMAX(1-w*w, 0))); break; default: av_assert0(0); } tab[i] = y; s = -s; if (i < tap_count) norm += y; } /* normalize so that an uniform color remains the same */ switch(c->format){ case AV_SAMPLE_FMT_S16P: for(i=0;i<tap_count;i++) ((int16_t*)filter)[ph * alloc + i] = av_clip_int16(lrintf(tab[i] * scale / norm)); if (phase_count % 2) break; if (tap_count % 2 == 0 || tap_count == 1) { for (i = 0; i < tap_count; i++) ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int16_t*)filter)[ph * alloc + i]; } else { for (i = 1; i <= tap_count; i++) ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-i] = av_clip_int16(lrintf(tab[i] * scale / (norm - tab[0] + tab[tap_count]))); } break; case AV_SAMPLE_FMT_S32P: for(i=0;i<tap_count;i++) ((int32_t*)filter)[ph * alloc + i] = av_clipl_int32(llrint(tab[i] * scale / norm)); if (phase_count % 2) break; if (tap_count % 2 == 0 || tap_count == 1) { for (i = 0; i < tap_count; i++) ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int32_t*)filter)[ph * alloc + i]; } else { for (i = 1; i <= tap_count; i++) ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-i] = av_clipl_int32(llrint(tab[i] * scale / (norm - tab[0] + tab[tap_count]))); } break; case AV_SAMPLE_FMT_FLTP: for(i=0;i<tap_count;i++) ((float*)filter)[ph * alloc + i] = tab[i] * scale / norm; if (phase_count % 2) break; if (tap_count % 2 == 0 || tap_count == 1) { for (i = 0; i < tap_count; i++) ((float*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((float*)filter)[ph * alloc + i]; } else { for (i = 1; i <= tap_count; i++) ((float*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / (norm - tab[0] + tab[tap_count]); } break; case AV_SAMPLE_FMT_DBLP: for(i=0;i<tap_count;i++) ((double*)filter)[ph * alloc + i] = tab[i] * scale / norm; if (phase_count % 2) break; if (tap_count % 2 == 0 || tap_count == 1) { for (i = 0; i < tap_count; i++) ((double*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((double*)filter)[ph * alloc + i]; } else { for (i = 1; i <= tap_count; i++) ((double*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / (norm - tab[0] + tab[tap_count]); } break; } } #if 0 { #define LEN 1024 int j,k; double sine[LEN + tap_count]; double filtered[LEN]; double maxff=-2, minff=2, maxsf=-2, minsf=2; for(i=0; i<LEN; i++){ double ss=0, sf=0, ff=0; for(j=0; j<LEN+tap_count; j++) sine[j]= cos(i*j*M_PI/LEN); for(j=0; j<LEN; j++){ double sum=0; ph=0; for(k=0; k<tap_count; k++) sum += filter[ph * tap_count + k] * sine[k+j]; filtered[j]= sum / (1<<FILTER_SHIFT); ss+= sine[j + center] * sine[j + center]; ff+= filtered[j] * filtered[j]; sf+= sine[j + center] * filtered[j]; } ss= sqrt(2*ss/LEN); ff= sqrt(2*ff/LEN); sf= 2*sf/LEN; maxff= FFMAX(maxff, ff); minff= FFMIN(minff, ff); maxsf= FFMAX(maxsf, sf); minsf= FFMIN(minsf, sf); if(i%11==0){ av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf); minff=minsf= 2; maxff=maxsf= -2; } } } #endif ret = 0; fail: av_free(tab); av_free(sin_lut); return ret; }
static void showSensorsPage(void) { uint8_t rowIndex = PAGE_TITLE_LINE_COUNT; static const char *format = "%s %5d %5d %5d"; i2c_OLED_set_line(bus, rowIndex++); i2c_OLED_send_string(bus, " X Y Z"); if (sensors(SENSOR_ACC)) { tfp_sprintf(lineBuffer, format, "ACC", lrintf(acc.accADC[X]), lrintf(acc.accADC[Y]), lrintf(acc.accADC[Z])); padLineBuffer(); i2c_OLED_set_line(bus, rowIndex++); i2c_OLED_send_string(bus, lineBuffer); } if (sensors(SENSOR_GYRO)) { tfp_sprintf(lineBuffer, format, "GYR", lrintf(gyro.gyroADCf[X]), lrintf(gyro.gyroADCf[Y]), lrintf(gyro.gyroADCf[Z])); padLineBuffer(); i2c_OLED_set_line(bus, rowIndex++); i2c_OLED_send_string(bus, lineBuffer); } #ifdef USE_MAG if (sensors(SENSOR_MAG)) { tfp_sprintf(lineBuffer, format, "MAG", lrintf(mag.magADC[X]), lrintf(mag.magADC[Y]), lrintf(mag.magADC[Z])); padLineBuffer(); i2c_OLED_set_line(bus, rowIndex++); i2c_OLED_send_string(bus, lineBuffer); } #endif tfp_sprintf(lineBuffer, format, "I&H", attitude.values.roll, attitude.values.pitch, DECIDEGREES_TO_DEGREES(attitude.values.yaw)); padLineBuffer(); i2c_OLED_set_line(bus, rowIndex++); i2c_OLED_send_string(bus, lineBuffer); /* uint8_t length; ftoa(EstG.A[X], lineBuffer); length = strlen(lineBuffer); while (length < HALF_SCREEN_CHARACTER_COLUMN_COUNT) { lineBuffer[length++] = ' '; lineBuffer[length+1] = 0; } ftoa(EstG.A[Y], lineBuffer + length); padLineBuffer(); i2c_OLED_set_line(bus, rowIndex++); i2c_OLED_send_string(bus, lineBuffer); ftoa(EstG.A[Z], lineBuffer); length = strlen(lineBuffer); while (length < HALF_SCREEN_CHARACTER_COLUMN_COUNT) { lineBuffer[length++] = ' '; lineBuffer[length+1] = 0; } ftoa(smallAngle, lineBuffer + length); padLineBuffer(); i2c_OLED_set_line(bus, rowIndex++); i2c_OLED_send_string(bus, lineBuffer); */ }
/** * builds a polyphase filterbank. * @param factor resampling factor * @param scale wanted sum of coefficients for each filter * @param type 0->cubic, 1->blackman nuttall windowed sinc, 2..16->kaiser windowed sinc beta=2..16 */ void av_build_filter(FELEM *filter, double factor, int tap_count, int phase_count, int scale, int type){ int ph, i, v; double x, y, w, tab[tap_count]; const int center= (tap_count-1)/2; /* if upsampling, only need to interpolate, no filter */ if (factor > 1.0) factor = 1.0; for(ph=0;ph<phase_count;ph++) { double norm = 0; for(i=0;i<tap_count;i++) { x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor; if (x == 0) y = 1.0; else y = sin(x) / x; switch(type){ case 0:{ const float d= -0.5; //first order derivative = -0.5 x = fabs(((double)(i - center) - (double)ph / phase_count) * factor); if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*( -x*x + x*x*x); else y= d*(-4 + 8*x - 5*x*x + x*x*x); break;} case 1: w = 2.0*x / (factor*tap_count) + M_PI; y *= 0.3635819 - 0.4891775 * cos(w) + 0.1365995 * cos(2*w) - 0.0106411 * cos(3*w); break; default: w = 2.0*x / (factor*tap_count*M_PI); y *= bessel(type*sqrt(FFMAX(1-w*w, 0))); break; } tab[i] = y; norm += y; } /* normalize so that an uniform color remains the same */ for(i=0;i<tap_count;i++) { #ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE filter[ph * tap_count + i] = tab[i] / norm; #else filter[ph * tap_count + i] = av_clip(lrintf(tab[i] * scale / norm), FELEM_MIN, FELEM_MAX); #endif } } #if 0 { #define LEN 1024 int j,k; double sine[LEN + tap_count]; double filtered[LEN]; double maxff=-2, minff=2, maxsf=-2, minsf=2; for(i=0; i<LEN; i++){ double ss=0, sf=0, ff=0; for(j=0; j<LEN+tap_count; j++) sine[j]= cos(i*j*M_PI/LEN); for(j=0; j<LEN; j++){ double sum=0; ph=0; for(k=0; k<tap_count; k++) sum += filter[ph * tap_count + k] * sine[k+j]; filtered[j]= sum / (1<<FILTER_SHIFT); ss+= sine[j + center] * sine[j + center]; ff+= filtered[j] * filtered[j]; sf+= sine[j + center] * filtered[j]; } ss= sqrt(2*ss/LEN); ff= sqrt(2*ff/LEN); sf= 2*sf/LEN; maxff= FFMAX(maxff, ff); minff= FFMIN(minff, ff); maxsf= FFMAX(maxsf, sf); minsf= FFMIN(minsf, sf); if(i%11==0){ av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf); minff=minsf= 2; maxff=maxsf= -2; } } } #endif }
void calculateEstimatedAltitude(uint32_t currentTime) { static uint32_t previousTime; uint32_t dTime; int32_t baroVel; float dt; float vel_acc; int32_t vel_tmp; float accZ_tmp; static float accZ_old = 0.0f; static float vel = 0.0f; static float accAlt = 0.0f; static int32_t lastBaroAlt; static int32_t baroAlt_offset = 0; float sonarTransition; #ifdef SONAR int16_t tiltAngle; #endif dTime = currentTime - previousTime; if (dTime < BARO_UPDATE_FREQUENCY_40HZ) return; previousTime = currentTime; if (!isBaroCalibrationComplete()) { performBaroCalibrationCycle(); vel = 0; accAlt = 0; } BaroAlt = baroCalculateAltitude(); #ifdef SONAR tiltAngle = calculateTiltAngle(&inclination); sonarAlt = sonarCalculateAltitude(sonarAlt, tiltAngle); #endif if (sonarAlt > 0 && sonarAlt < 200) { baroAlt_offset = BaroAlt - sonarAlt; BaroAlt = sonarAlt; } else { BaroAlt -= baroAlt_offset; if (sonarAlt > 0) { sonarTransition = (300 - sonarAlt) / 100.0f; BaroAlt = sonarAlt * sonarTransition + BaroAlt * (1.0f - sonarTransition); } } dt = accTimeSum * 1e-6f; // delta acc reading time in seconds // Integrator - velocity, cm/sec accZ_tmp = (float)accSum[2] / (float)accSumCount; vel_acc = accZ_tmp * accVelScale * (float)accTimeSum; // Integrator - Altitude in cm accAlt += (vel_acc * 0.5f) * dt + vel * dt; // integrate velocity to get distance (x= a/2 * t^2) accAlt = accAlt * barometerConfig->baro_cf_alt + (float)BaroAlt * (1.0f - barometerConfig->baro_cf_alt); // complementary filter for altitude estimation (baro & acc) vel += vel_acc; #if 0 debug[1] = accSum[2] / accSumCount; // acceleration debug[2] = vel; // velocity debug[3] = accAlt; // height #endif accSum_reset(); if (!isBaroCalibrationComplete()) { return; } if (sonarAlt > 0 && sonarAlt < 200) { // the sonar has the best range EstAlt = BaroAlt; } else { EstAlt = accAlt; } baroVel = (BaroAlt - lastBaroAlt) * 1000000.0f / dTime; lastBaroAlt = BaroAlt; baroVel = constrain(baroVel, -1500, 1500); // constrain baro velocity +/- 1500cm/s baroVel = applyDeadband(baroVel, 10); // to reduce noise near zero // apply Complimentary Filter to keep the calculated velocity based on baro velocity (i.e. near real velocity). // By using CF it's possible to correct the drift of integrated accZ (velocity) without loosing the phase, i.e without delay vel = vel * barometerConfig->baro_cf_vel + baroVel * (1.0f - barometerConfig->baro_cf_vel); vel_tmp = lrintf(vel); // set vario vario = applyDeadband(vel_tmp, 5); BaroPID = calculateBaroPid(vel_tmp, accZ_tmp, accZ_old); accZ_old = accZ_tmp; }
int tone_gen(tone_gen_state_t *s, int16_t amp[], int max_samples) { int samples; int limit; float xamp; int i; if (s->current_section < 0) return 0; for (samples = 0; samples < max_samples; ) { limit = samples + s->duration[s->current_section] - s->current_position; if (limit > max_samples) limit = max_samples; s->current_position += (limit - samples); if (s->current_section & 1) { /* A silent section */ for ( ; samples < limit; samples++) amp[samples] = 0; } else { if (s->tone[0].phase_rate < 0) { for ( ; samples < limit; samples++) { /* There must be two, and only two tones */ xamp = dds_modf(&s->phase[0], -s->tone[0].phase_rate, s->tone[0].gain, 0) *(1.0f + dds_modf(&s->phase[1], s->tone[1].phase_rate, s->tone[1].gain, 0)); amp[samples] = (int16_t) lrintf(xamp); } } else { for ( ; samples < limit; samples++) { xamp = 0.0f; for (i = 0; i < 4; i++) { if (s->tone[i].phase_rate == 0) break; xamp += dds_modf(&s->phase[i], s->tone[i].phase_rate, s->tone[i].gain, 0); } /* Saturation of the answer is the right thing at this point. However, we are normally generating well controlled tones, that cannot clip. So, the overhead of doing saturation is a waste of valuable time. */ amp[samples] = (int16_t) lrintf(xamp); } } } if (s->current_position >= s->duration[s->current_section]) { s->current_position = 0; if (++s->current_section > 3 || s->duration[s->current_section] == 0) { if (!s->repeat) { /* Force a quick exit */ s->current_section = -1; break; } s->current_section = 0; } } } return samples; }
void imuInit() { smallAngle = lrintf(acc_1G * cosf(RAD * imuRuntimeConfig->small_angle)); accVelScale = 9.80665f / acc_1G / 10000.0f; gyroScaleRad = gyro.scale * (M_PI / 180.0f) * 0.000001f; }
void ff_faandct(int16_t *data) { FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; FLOAT tmp10, tmp11, tmp12, tmp13; FLOAT z2, z4, z11, z13; FLOAT temp[64]; int i; emms_c(); row_fdct(temp, data); for (i=0; i<8; i++) { tmp0= temp[8*0 + i] + temp[8*7 + i]; tmp7= temp[8*0 + i] - temp[8*7 + i]; tmp1= temp[8*1 + i] + temp[8*6 + i]; tmp6= temp[8*1 + i] - temp[8*6 + i]; tmp2= temp[8*2 + i] + temp[8*5 + i]; tmp5= temp[8*2 + i] - temp[8*5 + i]; tmp3= temp[8*3 + i] + temp[8*4 + i]; tmp4= temp[8*3 + i] - temp[8*4 + i]; tmp10= tmp0 + tmp3; tmp13= tmp0 - tmp3; tmp11= tmp1 + tmp2; tmp12= tmp1 - tmp2; data[8*0 + i]= lrintf(postscale[8*0 + i] * (tmp10 + tmp11)); data[8*4 + i]= lrintf(postscale[8*4 + i] * (tmp10 - tmp11)); tmp12 += tmp13; tmp12 *= A1; data[8*2 + i]= lrintf(postscale[8*2 + i] * (tmp13 + tmp12)); data[8*6 + i]= lrintf(postscale[8*6 + i] * (tmp13 - tmp12)); tmp4 += tmp5; tmp5 += tmp6; tmp6 += tmp7; #if 0 { FLOAT z5; z5 = (tmp4 - tmp6) * A5; z2 = tmp4 * A2 + z5; z4 = tmp6 * A4 + z5; } #else z2= tmp4*(A2+A5) - tmp6*A5; z4= tmp6*(A4-A5) + tmp4*A5; #endif tmp5*=A1; z11= tmp7 + tmp5; z13= tmp7 - tmp5; data[8*5 + i]= lrintf(postscale[8*5 + i] * (z13 + z2)); data[8*3 + i]= lrintf(postscale[8*3 + i] * (z13 - z2)); data[8*1 + i]= lrintf(postscale[8*1 + i] * (z11 + z4)); data[8*7 + i]= lrintf(postscale[8*7 + i] * (z11 - z4)); } }
long int test11f(float x) { return lrintf(x); }
static void imuCalculateEstimatedAttitude(void) { int32_t axis; int32_t accMag = 0; static t_fp_vector EstM; static t_fp_vector EstN = { .A = { 1.0f, 0.0f, 0.0f } }; static float accLPF[3]; static uint32_t previousT; uint32_t currentT = micros(); uint32_t deltaT; float scale; fp_angles_t deltaGyroAngle; deltaT = currentT - previousT; scale = deltaT * gyroScaleRad; previousT = currentT; // Initialization for (axis = 0; axis < 3; axis++) { deltaGyroAngle.raw[axis] = gyroADC[axis] * scale; if (imuRuntimeConfig->acc_lpf_factor > 0) { accLPF[axis] = accLPF[axis] * (1.0f - (1.0f / imuRuntimeConfig->acc_lpf_factor)) + accADC[axis] * (1.0f / imuRuntimeConfig->acc_lpf_factor); accSmooth[axis] = accLPF[axis]; } else { accSmooth[axis] = accADC[axis]; } accMag += (int32_t)accSmooth[axis] * accSmooth[axis]; } accMag = accMag * 100 / ((int32_t)acc_1G * acc_1G); rotateV(&EstG.V, &deltaGyroAngle); // Apply complimentary filter (Gyro drift correction) // If accel magnitude >1.15G or <0.85G and ACC vector outside of the limit range => we neutralize the effect of accelerometers in the angle estimation. // To do that, we just skip filter, as EstV already rotated by Gyro float invGyroComplimentaryFilterFactor = (1.0f / (imuRuntimeConfig->gyro_cmpf_factor + 1.0f)); if (72 < (uint16_t)accMag && (uint16_t)accMag < 133) { for (axis = 0; axis < 3; axis++) EstG.A[axis] = (EstG.A[axis] * imuRuntimeConfig->gyro_cmpf_factor + accSmooth[axis]) * invGyroComplimentaryFilterFactor; } if (EstG.A[Z] > smallAngle) { ENABLE_STATE(SMALL_ANGLE); } else { DISABLE_STATE(SMALL_ANGLE); } // Attitude of the estimated vector anglerad[AI_ROLL] = atan2f(EstG.V.Y, EstG.V.Z); anglerad[AI_PITCH] = atan2f(-EstG.V.X, sqrtf(EstG.V.Y * EstG.V.Y + EstG.V.Z * EstG.V.Z)); inclination.values.rollDeciDegrees = lrintf(anglerad[AI_ROLL] * (1800.0f / M_PIf)); inclination.values.pitchDeciDegrees = lrintf(anglerad[AI_PITCH] * (1800.0f / M_PIf)); if (sensors(SENSOR_MAG)) { rotateV(&EstM.V, &deltaGyroAngle); // FIXME what does the _M_ mean? float invGyroComplimentaryFilter_M_Factor = (1.0f / (imuRuntimeConfig->gyro_cmpfm_factor + 1.0f)); for (axis = 0; axis < 3; axis++) { EstM.A[axis] = (EstM.A[axis] * imuRuntimeConfig->gyro_cmpfm_factor + magADC[axis]) * invGyroComplimentaryFilter_M_Factor; } heading = imuCalculateHeading(&EstM); } else { rotateV(&EstN.V, &deltaGyroAngle); normalizeV(&EstN.V, &EstN.V); heading = imuCalculateHeading(&EstN); } imuCalculateAcceleration(deltaT); // rotate acc vector into earth frame }
static int dm4_dive(void *param, int columns, char **data, char **column) { UNUSED(columns); UNUSED(column); int i; int interval, retval = 0; struct parser_state *state = (struct parser_state *)param; sqlite3 *handle = state->sql_handle; float *profileBlob; unsigned char *tempBlob; int *pressureBlob; char *err = NULL; char get_events_template[] = "select * from Mark where DiveId = %d"; char get_tags_template[] = "select Text from DiveTag where DiveId = %d"; char get_events[64]; dive_start(state); state->cur_dive->number = atoi(data[0]); state->cur_dive->when = (time_t)(atol(data[1])); if (data[2]) utf8_string(data[2], &state->cur_dive->notes); /* * DM4 stores Duration and DiveTime. It looks like DiveTime is * 10 to 60 seconds shorter than Duration. However, I have no * idea what is the difference and which one should be used. * Duration = data[3] * DiveTime = data[15] */ if (data[3]) state->cur_dive->duration.seconds = atoi(data[3]); if (data[15]) state->cur_dive->dc.duration.seconds = atoi(data[15]); /* * TODO: the deviceid hash should be calculated here. */ settings_start(state); dc_settings_start(state); if (data[4]) utf8_string(data[4], &state->cur_settings.dc.serial_nr); if (data[5]) utf8_string(data[5], &state->cur_settings.dc.model); state->cur_settings.dc.deviceid = 0xffffffff; dc_settings_end(state); settings_end(state); if (data[6]) state->cur_dive->dc.maxdepth.mm = lrint(strtod_flags(data[6], NULL, 0) * 1000); if (data[8]) state->cur_dive->dc.airtemp.mkelvin = C_to_mkelvin(atoi(data[8])); if (data[9]) state->cur_dive->dc.watertemp.mkelvin = C_to_mkelvin(atoi(data[9])); /* * TODO: handle multiple cylinders */ cylinder_start(state); if (data[22] && atoi(data[22]) > 0) state->cur_dive->cylinder[state->cur_cylinder_index].start.mbar = atoi(data[22]); else if (data[10] && atoi(data[10]) > 0) state->cur_dive->cylinder[state->cur_cylinder_index].start.mbar = atoi(data[10]); if (data[23] && atoi(data[23]) > 0) state->cur_dive->cylinder[state->cur_cylinder_index].end.mbar = (atoi(data[23])); if (data[11] && atoi(data[11]) > 0) state->cur_dive->cylinder[state->cur_cylinder_index].end.mbar = (atoi(data[11])); if (data[12]) state->cur_dive->cylinder[state->cur_cylinder_index].type.size.mliter = lrint((strtod_flags(data[12], NULL, 0)) * 1000); if (data[13]) state->cur_dive->cylinder[state->cur_cylinder_index].type.workingpressure.mbar = (atoi(data[13])); if (data[20]) state->cur_dive->cylinder[state->cur_cylinder_index].gasmix.o2.permille = atoi(data[20]) * 10; if (data[21]) state->cur_dive->cylinder[state->cur_cylinder_index].gasmix.he.permille = atoi(data[21]) * 10; cylinder_end(state); if (data[14]) state->cur_dive->dc.surface_pressure.mbar = (atoi(data[14]) * 1000); interval = data[16] ? atoi(data[16]) : 0; profileBlob = (float *)data[17]; tempBlob = (unsigned char *)data[18]; pressureBlob = (int *)data[19]; for (i = 0; interval && i * interval < state->cur_dive->duration.seconds; i++) { sample_start(state); state->cur_sample->time.seconds = i * interval; if (profileBlob) state->cur_sample->depth.mm = lrintf(profileBlob[i] * 1000.0f); else state->cur_sample->depth.mm = state->cur_dive->dc.maxdepth.mm; if (data[18] && data[18][0]) state->cur_sample->temperature.mkelvin = C_to_mkelvin(tempBlob[i]); if (data[19] && data[19][0]) state->cur_sample->pressure[0].mbar = pressureBlob[i]; sample_end(state); } snprintf(get_events, sizeof(get_events) - 1, get_events_template, state->cur_dive->number); retval = sqlite3_exec(handle, get_events, &dm4_events, state, &err); if (retval != SQLITE_OK) { fprintf(stderr, "%s", "Database query dm4_events failed.\n"); return 1; } snprintf(get_events, sizeof(get_events) - 1, get_tags_template, state->cur_dive->number); retval = sqlite3_exec(handle, get_events, &dm4_tags, state, &err); if (retval != SQLITE_OK) { fprintf(stderr, "%s", "Database query dm4_tags failed.\n"); return 1; } dive_end(state); /* for (i=0; i<columns;++i) { fprintf(stderr, "%s\t", column[i]); } fprintf(stderr, "\n"); for (i=0; i<columns;++i) { fprintf(stderr, "%s\t", data[i]); } fprintf(stderr, "\n"); //exit(0); */ return SQLITE_OK; }