static void gpsd_transit_fix_dump(struct gps_device_t *session, char bufp[], size_t len) { struct tm tm; time_t intfixtime; tm.tm_mday = tm.tm_mon = tm.tm_year = tm.tm_hour = tm.tm_min = tm.tm_sec = 0; if (isnan(session->gpsdata.fix.time) == 0) { intfixtime = (time_t) session->gpsdata.fix.time; (void)gmtime_r(&intfixtime, &tm); tm.tm_mon++; tm.tm_year %= 100; } #define ZEROIZE(x) (isnan(x)!=0 ? 0.0 : x) /*@ -usedef @*/ (void)snprintf(bufp, len, "$GPRMC,%02d%02d%02d,%c,%09.4f,%c,%010.4f,%c,%.4f,%.3f,%02d%02d%02d,,", tm.tm_hour, tm.tm_min, tm.tm_sec, session->gpsdata.status ? 'A' : 'V', ZEROIZE(degtodm(fabs(session->gpsdata.fix.latitude))), ((session->gpsdata.fix.latitude > 0) ? 'N' : 'S'), ZEROIZE(degtodm(fabs(session->gpsdata.fix.longitude))), ((session->gpsdata.fix.longitude > 0) ? 'E' : 'W'), ZEROIZE(session->gpsdata.fix.speed * MPS_TO_KNOTS), ZEROIZE(session->gpsdata.fix.track), tm.tm_mday, tm.tm_mon, tm.tm_year); /*@ +usedef @*/ #undef ZEROIZE nmea_add_checksum(bufp); }
static void gpsd_binary_quality_dump(struct gps_device_t *session, char bufp[], size_t len) { char *bufp2 = bufp; bool used_valid = (session->gpsdata.set & USED_IS) != 0; if (session->device_type != NULL && (session->gpsdata.set & MODE_SET) != 0) { int i, j; (void)snprintf(bufp, len - strlen(bufp), "$GPGSA,%c,%d,", 'A', session->gpsdata.fix.mode); j = 0; for (i = 0; i < session->device_type->channels; i++) { if (session->gpsdata.used[i]) { bufp += strlen(bufp); (void)snprintf(bufp, len - strlen(bufp), "%02d,", used_valid ? session->gpsdata.used[i] : 0); j++; } } for (i = j; i < session->device_type->channels; i++) { bufp += strlen(bufp); (void)strlcpy(bufp, ",", len); } bufp += strlen(bufp); #define ZEROIZE(x) (isnan(x)!=0 ? 0.0 : x) if (session->gpsdata.fix.mode == MODE_NO_FIX) (void)strlcat(bufp, ",,,", len); else (void)snprintf(bufp, len - strlen(bufp), "%.1f,%.1f,%.1f*", ZEROIZE(session->gpsdata.dop.pdop), ZEROIZE(session->gpsdata.dop.hdop), ZEROIZE(session->gpsdata.dop.vdop)); nmea_add_checksum(bufp2); bufp += strlen(bufp); } if (isfinite(session->gpsdata.fix.epx)!=0 && isfinite(session->gpsdata.fix.epy)!=0 && isfinite(session->gpsdata.fix.epv)!=0 && isfinite(session->gpsdata.epe)!=0) { struct tm tm; time_t intfixtime; tm.tm_hour = tm.tm_min = tm.tm_sec = 0; if (isnan(session->gpsdata.fix.time) == 0) { intfixtime = (time_t) session->gpsdata.fix.time; (void)gmtime_r(&intfixtime, &tm); } (void)snprintf(bufp, len - strlen(bufp), "$GPGBS,%02d%02d%02d,%.2f,M,%.2f,M,%.2f,M", tm.tm_hour, tm.tm_min, tm.tm_sec, ZEROIZE(session->gpsdata.fix.epx), ZEROIZE(session->gpsdata.fix.epy), ZEROIZE(session->gpsdata.fix.epv)); nmea_add_checksum(bufp); } #undef ZEROIZE }
static int _read_iff(dmoz_file_t *file, song_sample_t *smp, const uint8_t *data, size_t length) { chunk_t chunk; size_t pos = 0; chunk_t vhdr, body, name, comm, auth, anno, ssnd; // butt if (!iff_chunk_read(&chunk, data, length, &pos)) return 0; if (chunk.id != ID_FORM) return 0; // jump "into" the FORM chunk // if (pos < length), there's more data after the FORM chunk -- but I don't care about this scenario pos = 0; length = MIN(length, chunk.size); data = chunk.data->FORM.data; /* the header is already byteswapped, but anything in 'chunk' will need to be swapped as needed because the structure is a const pointing into the data itself */ switch (bswapBE32(chunk.data->FORM.filetype)) { case ID_8SVX: // shut up, gcc ZEROIZE(vhdr); ZEROIZE(body); ZEROIZE(name); ZEROIZE(auth); ZEROIZE(anno); while (iff_chunk_read(&chunk, data, length, &pos)) { switch (chunk.id) { case ID_VHDR: vhdr = chunk; break; case ID_BODY: body = chunk; break; case ID_NAME: name = chunk; break; case ID_AUTH: auth = chunk; break; case ID_ANNO: anno = chunk; break; default: break; } } if (!(vhdr.id && body.id)) return 0; if (vhdr.data->VHDR.compression) { log_appendf(4, "error: compressed 8SVX files are unsupported"); return 0; } if (vhdr.data->VHDR.num_octaves != 1) { log_appendf(4, "warning: 8SVX file contains %d octaves", vhdr.data->VHDR.num_octaves); } if (file) { file->description = "8SVX sample"; file->type = TYPE_SAMPLE_PLAIN; } if (!name.id) name = auth; if (!name.id) name = anno; if (name.id) { if (file) { file->title = calloc(1, name.size + 1); memcpy(file->title, name.data->bytes, name.size); file->title[name.size] = '\0'; } if (smp) { int len = MIN(25, name.size); memcpy(smp->name, name.data->bytes, len); smp->name[len] = 0; } } if (smp) { smp->c5speed = bswapBE16(vhdr.data->VHDR.smp_per_sec); smp->length = body.size; csf_read_sample(smp, SF_BE | SF_PCMS | SF_8 | SF_M, body.data->bytes, body.size); smp->volume = 64*4; smp->global_volume = 64; // this is done kinda weird smp->loop_end = bswapBE32(vhdr.data->VHDR.smp_highoct_repeat); if (smp->loop_end) { smp->loop_start = bswapBE32(vhdr.data->VHDR.smp_highoct_1shot); smp->loop_end += smp->loop_start; if (smp->loop_start > smp->length) smp->loop_start = 0; if (smp->loop_end > smp->length) smp->loop_end = smp->length; if (smp->loop_start + 2 < smp->loop_end) smp->flags |= CHN_LOOP; } // TODO vhdr.data->VHDR.volume ? } return 1; case ID_AIFF: ZEROIZE(comm); ZEROIZE(ssnd); ZEROIZE(name); ZEROIZE(auth); ZEROIZE(anno); while (iff_chunk_read(&chunk, data, length, &pos)) { switch (chunk.id) { case ID_COMM: comm = chunk; break; case ID_SSND: ssnd = chunk; break; case ID_NAME: name = chunk; break; default: break; } } if (!(comm.id && ssnd.id)) return 0; if (file) { file->description = "Audio IFF sample"; file->type = TYPE_SAMPLE_PLAIN; } if (!name.id) name = auth; if (!name.id) name = anno; if (name.id) { if (file) { file->title = calloc(1, name.size + 1); memcpy(file->title, name.data->bytes, name.size); file->title[name.size] = '\0'; } if (smp) { int len = MIN(25, name.size); memcpy(smp->name, name.data->bytes, len); smp->name[len] = 0; } } /* TODO loop points */ if (smp) { uint32_t flags = SF_BE | SF_PCMS; switch (bswapBE16(comm.data->COMM.num_channels)) { default: log_appendf(4, "warning: multichannel AIFF is unsupported"); case 1: flags |= SF_M; break; case 2: flags |= SF_SI; break; } switch ((bswapBE16(comm.data->COMM.sample_size) + 7) & ~7) { default: log_appendf(4, "warning: AIFF has unsupported bit-width"); case 8: flags |= SF_8; break; case 16: flags |= SF_16; break; } // TODO: data checking; make sure sample count and byte size agree // (and if not, cut to shorter of the two) smp->c5speed = ConvertFromIeeeExtended(comm.data->COMM.sample_rate); smp->length = bswapBE32(comm.data->COMM.num_frames); smp->volume = 64*4; smp->global_volume = 64; // the audio data starts 8 bytes into the chunk // (don't care about the block alignment stuff) csf_read_sample(smp, flags, ssnd.data->bytes + 8, ssnd.size - 8); } return 1; } return 0; }