Initial commit based on common repo commit ffeb9c9b
This commit is contained in:
		
							
								
								
									
										75
									
								
								libs/gempa/caps/mseed/encoder.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								libs/gempa/caps/mseed/encoder.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,75 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * encoder.h
 | 
			
		||||
 *
 | 
			
		||||
 * Abstract Encoder interface
 | 
			
		||||
 *
 | 
			
		||||
 * (c) 2000 Andres Heinloo, GFZ Potsdam
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the
 | 
			
		||||
 * Free Software Foundation; either version 2, or (at your option) any later
 | 
			
		||||
 * version. For more information, see http://www.gnu.org/
 | 
			
		||||
 *
 | 
			
		||||
 * ================
 | 
			
		||||
 * Change log
 | 
			
		||||
 * ===============
 | 
			
		||||
 *
 | 
			
		||||
 * 01.01.2013 Adapted code to CAPS client library requirements (gempa GmbH)
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef CAPS_MSEED_ENCODER_H
 | 
			
		||||
#define CAPS_MSEED_ENCODER_H
 | 
			
		||||
 | 
			
		||||
#include "packet.h"
 | 
			
		||||
#include "spclock.h"
 | 
			
		||||
 | 
			
		||||
#include <gempa/caps/datetime.h>
 | 
			
		||||
#include <gempa/caps/pluginpacket.h>
 | 
			
		||||
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Gempa {
 | 
			
		||||
namespace CAPS {
 | 
			
		||||
 | 
			
		||||
class Encoder {
 | 
			
		||||
	public:
 | 
			
		||||
		Encoder(int freqn, int freqd) : _clk(freqn, freqd),
 | 
			
		||||
		    _sampleCount(0), _timingQuality(-1) {}
 | 
			
		||||
		virtual ~Encoder() {}
 | 
			
		||||
 | 
			
		||||
		virtual void push(void *sample) = 0;
 | 
			
		||||
		virtual void flush() = 0;
 | 
			
		||||
		virtual void reset() { _sampleCount = 0; }
 | 
			
		||||
		virtual int type() const = 0;
 | 
			
		||||
 | 
			
		||||
		const SPClock& clk() { return _clk; }
 | 
			
		||||
 | 
			
		||||
		void setStartTime(const SPClock::INT_TIME &time) { _clk.sync_time(time); }
 | 
			
		||||
		const SPClock::INT_TIME currentTime() const { return _clk.get_time(0); }
 | 
			
		||||
 | 
			
		||||
		int timingQuality() { return _timingQuality; }
 | 
			
		||||
		void setTimingQuality(int quality) { _timingQuality = quality; }
 | 
			
		||||
 | 
			
		||||
		PacketPtr pop() {
 | 
			
		||||
			if ( _packetQueue.empty() ) return PacketPtr();
 | 
			
		||||
 | 
			
		||||
			PacketPtr rec = _packetQueue.front();
 | 
			
		||||
			_packetQueue.pop_front(); 
 | 
			
		||||
			return rec;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		typedef std::list<PacketPtr>  PacketQueue;
 | 
			
		||||
		SPClock      _clk;
 | 
			
		||||
		int          _sampleCount;
 | 
			
		||||
		PacketQueue  _packetQueue;
 | 
			
		||||
		int          _timingQuality;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // __ENCODER_H__
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										162
									
								
								libs/gempa/caps/mseed/mseed.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								libs/gempa/caps/mseed/mseed.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,162 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * mseed.cpp
 | 
			
		||||
 *
 | 
			
		||||
 * Mini-SEED format implementation
 | 
			
		||||
 *
 | 
			
		||||
 * (c) 2000 Andres Heinloo, GFZ Potsdam
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the
 | 
			
		||||
 * Free Software Foundation; either version 2, or (at your option) any later
 | 
			
		||||
 * version. For more information, see http://www.gnu.org/
 | 
			
		||||
 *
 | 
			
		||||
 * ================
 | 
			
		||||
 * Change log
 | 
			
		||||
 * ===============
 | 
			
		||||
 *
 | 
			
		||||
 * 01.01.2013 Adapted code to CAPS client library requirements (gempa GmbH)
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <gempa/caps/mseedpacket.h>
 | 
			
		||||
#include <gempa/caps/rawpacket.h>
 | 
			
		||||
 | 
			
		||||
#include "mseed.h"
 | 
			
		||||
#include "slink.h"
 | 
			
		||||
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Gempa {
 | 
			
		||||
namespace CAPS {
 | 
			
		||||
 | 
			
		||||
MSEEDFormat::MSEEDFormat(const std::string &netcode, const std::string &stacode,
 | 
			
		||||
                         const std::string &loccode, const std::string &chacode,
 | 
			
		||||
                         unsigned short freqn, unsigned short freqd,
 | 
			
		||||
                         unsigned short packtype_init,
 | 
			
		||||
                         uint8_t recordLength)
 | 
			
		||||
    : networkCode(netcode), stationCode(stacode), locationCode(loccode),
 | 
			
		||||
      channelCode(chacode), packType(packtype_init), recordLength(recordLength)
 | 
			
		||||
{
 | 
			
		||||
	if(freqn == 0 || freqd == 0) {
 | 
			
		||||
		sample_rate_factor = 0;
 | 
			
		||||
		sample_rate_multiplier = 0;
 | 
			
		||||
	}
 | 
			
		||||
	else if(!(freqn % freqd)) {
 | 
			
		||||
		sample_rate_factor = freqn / freqd;
 | 
			
		||||
		sample_rate_multiplier = 1;
 | 
			
		||||
	}
 | 
			
		||||
	else if(!(freqd % freqn)) {
 | 
			
		||||
		sample_rate_factor = -freqd / freqn;
 | 
			
		||||
		sample_rate_multiplier = 1;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		sample_rate_factor = -freqd;
 | 
			
		||||
		sample_rate_multiplier = freqn;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MSEEDDataRecord *MSEEDFormat::get_buffer(const SPClock::INT_TIME &it, int usec_correction,
 | 
			
		||||
                                         int timing_quality, void *&dataptr, int &datalen) {
 | 
			
		||||
	size_t buflen = 1 << recordLength;
 | 
			
		||||
	MSEEDDataRecord *record = new MSEEDDataRecord();
 | 
			
		||||
	record->data()->resize(buflen);
 | 
			
		||||
 | 
			
		||||
	char *buf = record->data()->data();
 | 
			
		||||
	int n;
 | 
			
		||||
 | 
			
		||||
	sl_fsdh_s* fsdh = (sl_fsdh_s *)buf;
 | 
			
		||||
 | 
			
		||||
	memset(fsdh, 0, buflen);
 | 
			
		||||
 | 
			
		||||
	const int start_frames = (sizeof(sl_fsdh_s) + sizeof(sl_blkt_1000_s) +
 | 
			
		||||
	sizeof(sl_blkt_1001_s) + 63) & 0xffffffc0;    // align to 64 bytes
 | 
			
		||||
 | 
			
		||||
	dataptr = (void *)((char *) fsdh + start_frames);
 | 
			
		||||
	datalen = buflen - start_frames;
 | 
			
		||||
 | 
			
		||||
	fsdh->dhq_indicator = 'D';
 | 
			
		||||
	fsdh->reserved = ' ';
 | 
			
		||||
 | 
			
		||||
	strncpy(fsdh->station, stationCode.c_str(), 5);
 | 
			
		||||
	if((n = stationCode.length()) < 5) memset(fsdh->station + n, 32, 5 - n);
 | 
			
		||||
	strncpy(fsdh->location, locationCode.c_str(), 2);
 | 
			
		||||
	if((n = locationCode.length()) < 2) memset(fsdh->location + n, 32, 2 - n);
 | 
			
		||||
	strncpy(fsdh->channel, channelCode.c_str(), 3);
 | 
			
		||||
	if((n = channelCode.length()) < 3) memset(fsdh->channel + n, 32, 3 - n);
 | 
			
		||||
	strncpy(fsdh->network, networkCode.c_str(), 2);
 | 
			
		||||
	if((n = networkCode.length()) < 2) memset(fsdh->network + n, 32, 2 - n);
 | 
			
		||||
 | 
			
		||||
	int year, doy, hour, min, sec;
 | 
			
		||||
	it.get2(&year, &doy, &hour, &min, &sec);
 | 
			
		||||
 | 
			
		||||
	fsdh->start_time.year = htons(year);
 | 
			
		||||
	fsdh->start_time.day = htons(doy+1);
 | 
			
		||||
	fsdh->start_time.hour = hour;
 | 
			
		||||
	fsdh->start_time.min = min;
 | 
			
		||||
	fsdh->start_time.sec = sec;
 | 
			
		||||
	fsdh->start_time.fract = htons(it.microseconds() / 100);
 | 
			
		||||
	fsdh->samprate_fact = (int16_t)htons(sample_rate_factor);
 | 
			
		||||
	fsdh->samprate_mult = (int16_t)htons(sample_rate_multiplier);
 | 
			
		||||
	fsdh->num_blockettes = 1;
 | 
			
		||||
 | 
			
		||||
	div_t d_corr = div(usec_correction + ((usec_correction < 0) ? -50: 50), 100);
 | 
			
		||||
	fsdh->time_correct = (int32_t)htonl(d_corr.quot);
 | 
			
		||||
 | 
			
		||||
	fsdh->begin_data = htons(start_frames);
 | 
			
		||||
	fsdh->begin_blockette = htons(sizeof(sl_fsdh_s));
 | 
			
		||||
 | 
			
		||||
	sl_blkt_1000_s* blkt_1000 = (sl_blkt_1000_s *)((char *) fsdh + sizeof(sl_fsdh_s));
 | 
			
		||||
	blkt_1000->blkt_type = htons(1000);          // Data Only SEED Blockette
 | 
			
		||||
 | 
			
		||||
	blkt_1000->encoding = packType;
 | 
			
		||||
	blkt_1000->word_swap = 1;                    // big endian
 | 
			
		||||
	blkt_1000->rec_len = recordLength; // 9 = 512 bytes
 | 
			
		||||
 | 
			
		||||
	if ( timing_quality >= 0 ) {
 | 
			
		||||
		blkt_1000->next_blkt = htons(sizeof(sl_fsdh_s) + sizeof(sl_blkt_1000_s));
 | 
			
		||||
		++fsdh->num_blockettes;
 | 
			
		||||
 | 
			
		||||
		sl_blkt_1001_s* blkt_1001 = (sl_blkt_1001_s *)((char *) fsdh +
 | 
			
		||||
		  sizeof(sl_fsdh_s) + sizeof(sl_blkt_1000_s));
 | 
			
		||||
 | 
			
		||||
		blkt_1001->blkt_type = htons(1001);      // Data Extension Blockette
 | 
			
		||||
		blkt_1001->timing_qual = timing_quality;
 | 
			
		||||
 | 
			
		||||
		blkt_1001->usec = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return record;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void MSEEDFormat::updateBuffer(MSEEDDataRecord *rec, int samples, int frames) {
 | 
			
		||||
	sl_fsdh_s* fsdh = (sl_fsdh_s *)rec->data()->data();
 | 
			
		||||
	char temp[7];
 | 
			
		||||
 | 
			
		||||
	sprintf(temp, "%06d", (int)0);
 | 
			
		||||
	memcpy(fsdh->sequence_number,temp,6);
 | 
			
		||||
	fsdh->dhq_indicator = 'D';
 | 
			
		||||
	fsdh->num_samples = htons(samples);
 | 
			
		||||
 | 
			
		||||
	sl_blkt_1000_s* blkt_1000 = (sl_blkt_1000_s *)((char *) fsdh + sizeof(sl_fsdh_s));
 | 
			
		||||
 | 
			
		||||
	if ( ntohs(blkt_1000->next_blkt) != 0 ) {
 | 
			
		||||
		sl_blkt_1001_s* blkt_1001 = (sl_blkt_1001_s *)((char *) fsdh +
 | 
			
		||||
		                             sizeof(sl_fsdh_s) + sizeof(sl_blkt_1000_s));
 | 
			
		||||
 | 
			
		||||
		blkt_1001->frame_cnt = frames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rec->unpackHeader();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								libs/gempa/caps/mseed/mseed.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								libs/gempa/caps/mseed/mseed.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,90 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * mseed.h
 | 
			
		||||
 *
 | 
			
		||||
 * Mini-SEED format implementation
 | 
			
		||||
 *
 | 
			
		||||
 * (c) 2000 Andres Heinloo, GFZ Potsdam
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the
 | 
			
		||||
 * Free Software Foundation; either version 2, or (at your option) any later
 | 
			
		||||
 * version. For more information, see http://www.gnu.org/
 | 
			
		||||
 *
 | 
			
		||||
 * ================
 | 
			
		||||
 * Change log
 | 
			
		||||
 * ===============
 | 
			
		||||
 *
 | 
			
		||||
 * 01.01.2013 Adapted code to CAPS client library requirements (gempa GmbH)
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef CAPS_MSEED_MSEED_H
 | 
			
		||||
#define CAPS_MSEED_MSEED_H
 | 
			
		||||
 | 
			
		||||
#include "packet.h"
 | 
			
		||||
#include "spclock.h"
 | 
			
		||||
 | 
			
		||||
#include <gempa/caps/mseedpacket.h>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Gempa {
 | 
			
		||||
namespace CAPS {
 | 
			
		||||
 | 
			
		||||
/* SEED data encoding types */
 | 
			
		||||
enum SEEDDataEncodingType {
 | 
			
		||||
	DE_ASCII       = 0,
 | 
			
		||||
	DE_INT16       = 1,
 | 
			
		||||
	DE_INT32       = 3,
 | 
			
		||||
	DE_FLOAT32     = 4,
 | 
			
		||||
	DE_FLOAT64     = 5,
 | 
			
		||||
	DE_STEIM1      = 10,
 | 
			
		||||
	DE_STEIM2      = 11,
 | 
			
		||||
	DE_GEOSCOPE24  = 12,
 | 
			
		||||
	DE_GEOSCOPE163 = 13,
 | 
			
		||||
	DE_GEOSCOPE164 = 14,
 | 
			
		||||
	DE_CDSN        = 16,
 | 
			
		||||
	DE_SRO         = 30,
 | 
			
		||||
	DE_DWWSSN      = 32
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct MSEEDFormat {
 | 
			
		||||
	MSEEDFormat(const std::string &networkCode, const std::string &stationCode,
 | 
			
		||||
	            const std::string &locationCode, const std::string &channelCode,
 | 
			
		||||
	            unsigned short freqn, unsigned short freqd,
 | 
			
		||||
	            unsigned short packtype_init,
 | 
			
		||||
	            uint8_t recLen);
 | 
			
		||||
 | 
			
		||||
	template<class T>
 | 
			
		||||
	MSEEDEncoderPacket<T>
 | 
			
		||||
	get_packet(const SPClock::INT_TIME &it, int usec_correction, int timing_quality) {
 | 
			
		||||
		void *dataptr = NULL;
 | 
			
		||||
		int datalen = 0;
 | 
			
		||||
		unsigned int size = 0;
 | 
			
		||||
		MSEEDDataRecord *rec = get_buffer(it, usec_correction, timing_quality, dataptr, datalen);
 | 
			
		||||
 | 
			
		||||
		return MSEEDEncoderPacket<T>(rec, size, dataptr, datalen);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	MSEEDDataRecord *get_buffer(const SPClock::INT_TIME &it, int usec_correction,
 | 
			
		||||
	                 int timing_quality,
 | 
			
		||||
	                 void *&dataptr, int &datalen);
 | 
			
		||||
 | 
			
		||||
	void updateBuffer(MSEEDDataRecord *rec, int samples, int frames);
 | 
			
		||||
 | 
			
		||||
	std::string    networkCode;
 | 
			
		||||
	std::string    stationCode;
 | 
			
		||||
	std::string    locationCode;
 | 
			
		||||
	std::string    channelCode;
 | 
			
		||||
	int            sample_rate_factor;
 | 
			
		||||
	int            sample_rate_multiplier;
 | 
			
		||||
	unsigned short packType;
 | 
			
		||||
	int            timingQuality;
 | 
			
		||||
	uint8_t        recordLength;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										44
									
								
								libs/gempa/caps/mseed/packet.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								libs/gempa/caps/mseed/packet.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
			
		||||
/***************************************************************************
 | 
			
		||||
 * Copyright (C) 2012 by gempa GmbH                                        *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 * All Rights Reserved.                                                    *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 * NOTICE: All information contained herein is, and remains                *
 | 
			
		||||
 * the property of gempa GmbH and its suppliers, if any. The intellectual  *
 | 
			
		||||
 * and technical concepts contained herein are proprietary to gempa GmbH   *
 | 
			
		||||
 * and its suppliers.                                                      *
 | 
			
		||||
 * Dissemination of this information or reproduction of this material      *
 | 
			
		||||
 * is strictly forbidden unless prior written permission is obtained       *
 | 
			
		||||
 * from gempa GmbH.                                                        *
 | 
			
		||||
 ***************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef CAPS_MSEED_PACKET_H
 | 
			
		||||
#define CAPS_MSEED_PACKET_H
 | 
			
		||||
 | 
			
		||||
#include <gempa/caps/mseedpacket.h>
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
namespace Gempa {
 | 
			
		||||
namespace CAPS {
 | 
			
		||||
 | 
			
		||||
template<typename T> struct MSEEDEncoderPacket {
 | 
			
		||||
	MSEEDEncoderPacket(): record(NULL), data(NULL), datalen(0) {}
 | 
			
		||||
	MSEEDEncoderPacket(MSEEDDataRecord *rec, unsigned int size_init,
 | 
			
		||||
	       void *data_init, unsigned short datalen_init)
 | 
			
		||||
	    : record(rec), data(static_cast<T*>(data_init)),
 | 
			
		||||
	      datalen(datalen_init) {}
 | 
			
		||||
	~MSEEDEncoderPacket() {}
 | 
			
		||||
 | 
			
		||||
	void reset() { record = NULL; data = NULL; datalen = 0; }
 | 
			
		||||
	bool valid() const { return record != NULL; }
 | 
			
		||||
 | 
			
		||||
	MSEEDDataRecord *record;
 | 
			
		||||
	T               *data;
 | 
			
		||||
	unsigned short   datalen;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										131
									
								
								libs/gempa/caps/mseed/slink.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								libs/gempa/caps/mseed/slink.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,131 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * slink.h
 | 
			
		||||
 *
 | 
			
		||||
 * SeedLink protocol constants
 | 
			
		||||
 *
 | 
			
		||||
 * Token from libslink
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the
 | 
			
		||||
 * Free Software Foundation; either version 2, or (at your option) any later
 | 
			
		||||
 * version. For more information, see http://www.gnu.org/
 | 
			
		||||
 *
 | 
			
		||||
 * ================
 | 
			
		||||
 * Change log
 | 
			
		||||
 * ===============
 | 
			
		||||
 *
 | 
			
		||||
 * 01.01.2013 Adapted code to CAPS client library requirements (gempa GmbH)
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef CAPS_MSEED_SLINK_H
 | 
			
		||||
#define CAPS_MSEED_SLINK_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /* Portability to the XScale (ARM) architecture
 | 
			
		||||
   * requires a packed attribute in certain places
 | 
			
		||||
   * but this only works with GCC for now.
 | 
			
		||||
   */
 | 
			
		||||
#if defined (__GNUC__)
 | 
			
		||||
  #define SLP_PACKED __attribute__ ((packed))
 | 
			
		||||
#else
 | 
			
		||||
  #define SLP_PACKED
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define SIGNATURE           "SL"     /* SeedLink header signature */
 | 
			
		||||
#define INFOSIGNATURE       "SLINFO" /* SeedLink INFO packet signature */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* SeedLink packet types */
 | 
			
		||||
#define SLDATA 0     /* waveform data record */
 | 
			
		||||
#define SLDET  1     /* detection record */
 | 
			
		||||
#define SLCAL  2     /* calibration record */
 | 
			
		||||
#define SLTIM  3     /* timing record */
 | 
			
		||||
#define SLMSG  4     /* message record */
 | 
			
		||||
#define SLBLK  5     /* general record */
 | 
			
		||||
#define SLNUM  6     /* used as the error indicator (same as SLCHA) */
 | 
			
		||||
#define SLCHA  6     /* for requesting channel info or detectors */
 | 
			
		||||
#define SLINF  7     /* a non-terminating XML formatted message in a miniSEED
 | 
			
		||||
                        log record, used for INFO responses */
 | 
			
		||||
#define SLINFT 8     /* a terminating XML formatted message in a miniSEED log
 | 
			
		||||
                        record, used for INFO responses */
 | 
			
		||||
#define SLKEEP 9     /* an XML formatted message in a miniSEED log
 | 
			
		||||
                        record, used for keepalive/heartbeat responses */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* SEED binary time (10 bytes) */
 | 
			
		||||
struct sl_btime_s
 | 
			
		||||
{
 | 
			
		||||
  uint16_t  year;
 | 
			
		||||
  uint16_t  day;
 | 
			
		||||
  uint8_t   hour;
 | 
			
		||||
  uint8_t   min;
 | 
			
		||||
  uint8_t   sec;
 | 
			
		||||
  uint8_t   unused;
 | 
			
		||||
  uint16_t  fract;
 | 
			
		||||
} SLP_PACKED;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Fixed section data of header (48 bytes) */
 | 
			
		||||
struct sl_fsdh_s
 | 
			
		||||
{
 | 
			
		||||
  char        sequence_number[6];
 | 
			
		||||
  char        dhq_indicator;
 | 
			
		||||
  char        reserved;
 | 
			
		||||
  char        station[5];
 | 
			
		||||
  char        location[2];
 | 
			
		||||
  char        channel[3];
 | 
			
		||||
  char        network[2];
 | 
			
		||||
  struct sl_btime_s start_time;
 | 
			
		||||
  uint16_t    num_samples;
 | 
			
		||||
  int16_t     samprate_fact;
 | 
			
		||||
  int16_t     samprate_mult;
 | 
			
		||||
  uint8_t     act_flags;
 | 
			
		||||
  uint8_t     io_flags;
 | 
			
		||||
  uint8_t     dq_flags;
 | 
			
		||||
  uint8_t     num_blockettes;
 | 
			
		||||
  int32_t     time_correct;
 | 
			
		||||
  uint16_t    begin_data;
 | 
			
		||||
  uint16_t    begin_blockette;
 | 
			
		||||
} SLP_PACKED;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* 1000 Blockette (8 bytes) */
 | 
			
		||||
struct sl_blkt_1000_s
 | 
			
		||||
{
 | 
			
		||||
  uint16_t  blkt_type;
 | 
			
		||||
  uint16_t  next_blkt;
 | 
			
		||||
  uint8_t   encoding;
 | 
			
		||||
  uint8_t   word_swap;
 | 
			
		||||
  uint8_t   rec_len;
 | 
			
		||||
  uint8_t   reserved;
 | 
			
		||||
} SLP_PACKED;
 | 
			
		||||
 | 
			
		||||
/* 1001 Blockette (8 bytes) */
 | 
			
		||||
struct sl_blkt_1001_s
 | 
			
		||||
{
 | 
			
		||||
  uint16_t  blkt_type;
 | 
			
		||||
  uint16_t  next_blkt;
 | 
			
		||||
  int8_t    timing_qual;
 | 
			
		||||
  int8_t    usec;
 | 
			
		||||
  uint8_t   reserved;
 | 
			
		||||
  int8_t    frame_cnt;
 | 
			
		||||
} SLP_PACKED;
 | 
			
		||||
 | 
			
		||||
/* Generic struct for head of blockettes */
 | 
			
		||||
struct sl_blkt_head_s
 | 
			
		||||
{
 | 
			
		||||
  uint16_t  blkt_type;
 | 
			
		||||
  uint16_t  next_blkt;
 | 
			
		||||
} SLP_PACKED;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										78
									
								
								libs/gempa/caps/mseed/spclock.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								libs/gempa/caps/mseed/spclock.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * spclock.h
 | 
			
		||||
 *
 | 
			
		||||
 * Stream Processor Clock
 | 
			
		||||
 *
 | 
			
		||||
 * (c) 2000 Andres Heinloo, GFZ Potsdam
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the
 | 
			
		||||
 * Free Software Foundation; either version 2, or (at your option) any later
 | 
			
		||||
 * version. For more information, see http://www.gnu.org/
 | 
			
		||||
 *
 | 
			
		||||
 * ================
 | 
			
		||||
 * Change log
 | 
			
		||||
 * ===============
 | 
			
		||||
 *
 | 
			
		||||
 * 01.01.2013 Adapted code to CAPS client library requirements (gempa GmbH)
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef CAPS_MSEED_SPCLOCK_H
 | 
			
		||||
#define CAPS_MSEED_SPCLOCK_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <gempa/caps/datetime.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Gempa {
 | 
			
		||||
namespace CAPS {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SPClock
 | 
			
		||||
  {
 | 
			
		||||
  public:
 | 
			
		||||
    typedef Gempa::CAPS::Time INT_TIME;
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    INT_TIME itime;
 | 
			
		||||
    int ticks;
 | 
			
		||||
    int corr;
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
    const int freqn;
 | 
			
		||||
    const int freqd;
 | 
			
		||||
 | 
			
		||||
    SPClock(int freqn_init, int freqd_init): ticks(0), corr(0),
 | 
			
		||||
      freqn(freqn_init), freqd(freqd_init)
 | 
			
		||||
      {}
 | 
			
		||||
 | 
			
		||||
    void sync_time(const INT_TIME &time)
 | 
			
		||||
      {
 | 
			
		||||
        itime = time;
 | 
			
		||||
        ticks = 0;
 | 
			
		||||
        corr = 0;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    void tick()
 | 
			
		||||
      {
 | 
			
		||||
        ++ticks;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    INT_TIME get_time(int tick_diff) const
 | 
			
		||||
      {
 | 
			
		||||
        int64_t correctness = (double)freqd / (double)freqn * 1000000 * (ticks - tick_diff - corr);
 | 
			
		||||
        return itime + Gempa::CAPS::TimeSpan(long(correctness/1000000),long(correctness%1000000));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    int correction() const
 | 
			
		||||
      {
 | 
			
		||||
        return corr;
 | 
			
		||||
      }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // SPCLOCK_H
 | 
			
		||||
							
								
								
									
										90
									
								
								libs/gempa/caps/mseed/steim1.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								libs/gempa/caps/mseed/steim1.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,90 @@
 | 
			
		||||
/***************************************************************************** 
 | 
			
		||||
 * steim1.h
 | 
			
		||||
 *
 | 
			
		||||
 * Steim1 encoder
 | 
			
		||||
 *
 | 
			
		||||
 * (c) 2000 Andres Heinloo, GFZ Potsdam
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the
 | 
			
		||||
 * Free Software Foundation; either version 2, or (at your option) any later
 | 
			
		||||
 * version. For more information, see http://www.gnu.org/
 | 
			
		||||
 *
 | 
			
		||||
 * ================
 | 
			
		||||
 * Change log
 | 
			
		||||
 * ===============
 | 
			
		||||
 *
 | 
			
		||||
 * 01.01.2013 Adapted code to CAPS client library requirements (gempa GmbH)
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef CAPS_MSEED_STEIM1_H
 | 
			
		||||
#define CAPS_MSEED_STEIM1_H
 | 
			
		||||
 | 
			
		||||
#include "encoder.h"
 | 
			
		||||
#include "mseed.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Gempa {
 | 
			
		||||
namespace CAPS {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//*****************************************************************************
 | 
			
		||||
// Steim1Frame
 | 
			
		||||
//*****************************************************************************
 | 
			
		||||
 | 
			
		||||
struct Steim1Frame {
 | 
			
		||||
	u_int32_t nibble_word;
 | 
			
		||||
	u_int32_t sample_word[15];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//*****************************************************************************
 | 
			
		||||
// Steim1Encoder
 | 
			
		||||
//*****************************************************************************
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
class Steim1Encoder: public Encoder {
 | 
			
		||||
	private:
 | 
			
		||||
		MSEEDFormat *format;
 | 
			
		||||
		int frame_count;
 | 
			
		||||
		int bp;
 | 
			
		||||
		int fp;
 | 
			
		||||
		int spw;
 | 
			
		||||
		int32_t last_sample;
 | 
			
		||||
		int32_t buf[5];
 | 
			
		||||
		u_int32_t nibble_word;
 | 
			
		||||
		MSEEDEncoderPacket<Steim1Frame> current_packet;
 | 
			
		||||
 | 
			
		||||
		void update_spw(int bp);
 | 
			
		||||
		void store(int32_t value);
 | 
			
		||||
		void init_packet();
 | 
			
		||||
		void finish_packet();
 | 
			
		||||
		void update_packet();
 | 
			
		||||
 | 
			
		||||
		MSEEDEncoderPacket<Steim1Frame> get_packet() {
 | 
			
		||||
			return format->get_packet<Steim1Frame>(_clk.get_time(bp),
 | 
			
		||||
			                                       _clk.correction(), _timingQuality);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void queue_packet(MSEEDEncoderPacket<Steim1Frame> &pckt);
 | 
			
		||||
 | 
			
		||||
		int number_of_frames(const MSEEDEncoderPacket<Steim1Frame> &packet) {
 | 
			
		||||
			return (packet.datalen >> 6);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		Steim1Encoder(MSEEDFormat *format, int freqn, int freqd)
 | 
			
		||||
		    : Encoder(freqn, freqd), format(format), frame_count(0),
 | 
			
		||||
		      bp(0), fp(0), spw(4), last_sample(0), nibble_word(0) {}
 | 
			
		||||
		virtual ~Steim1Encoder();
 | 
			
		||||
		virtual void flush();
 | 
			
		||||
		virtual void push(void *value);
 | 
			
		||||
		virtual int type() const { return DE_STEIM1; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "steim1.ipp"
 | 
			
		||||
 | 
			
		||||
#endif // __STEIM1_H__
 | 
			
		||||
							
								
								
									
										184
									
								
								libs/gempa/caps/mseed/steim1.ipp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								libs/gempa/caps/mseed/steim1.ipp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,184 @@
 | 
			
		||||
/***************************************************************************** 
 | 
			
		||||
 * steim1.cc
 | 
			
		||||
 *
 | 
			
		||||
 * Steim1 encoder
 | 
			
		||||
 *
 | 
			
		||||
 * (c) 2000 Andres Heinloo, GFZ Potsdam
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the
 | 
			
		||||
 * Free Software Foundation; either version 2, or (at your option) any later
 | 
			
		||||
 * version. For more information, see http://www.gnu.org/
 | 
			
		||||
 *
 | 
			
		||||
 * ================
 | 
			
		||||
 * Change log
 | 
			
		||||
 * ===============
 | 
			
		||||
 *
 | 
			
		||||
 * 01.01.2013 Adapted code to CAPS client library requirements (gempa GmbH)
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iomanip>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
namespace Gempa {
 | 
			
		||||
namespace CAPS {
 | 
			
		||||
 | 
			
		||||
template<typename T> Steim1Encoder<T>::~Steim1Encoder() {
 | 
			
		||||
	if ( format != NULL ) delete format;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim1Encoder<T>::update_spw(int bp) {
 | 
			
		||||
	int spw1 = 4;
 | 
			
		||||
 | 
			
		||||
	assert(bp < 4);
 | 
			
		||||
	if(buf[bp] < -32768 || buf[bp] > 32767) spw1 = 1;
 | 
			
		||||
	else if(buf[bp] < -128 || buf[bp] > 127) spw1 = 2;
 | 
			
		||||
	if(spw1 < spw) spw = spw1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim1Encoder<T>::store(int32_t value) {
 | 
			
		||||
	assert(bp < 4);
 | 
			
		||||
	buf[bp] = value - last_sample;
 | 
			
		||||
	last_sample = value;
 | 
			
		||||
	update_spw(bp);
 | 
			
		||||
	++bp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim1Encoder<T>::init_packet() {
 | 
			
		||||
	int i;
 | 
			
		||||
	int32_t begin_sample = last_sample;
 | 
			
		||||
 | 
			
		||||
	for(i = 1; i < bp; ++i) {
 | 
			
		||||
		begin_sample -= buf[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	reset();
 | 
			
		||||
	current_packet.data[0].sample_word[0] = htonl(begin_sample);
 | 
			
		||||
	frame_count = 0;
 | 
			
		||||
	nibble_word = 0;
 | 
			
		||||
	fp = 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim1Encoder<T>::finish_packet() {
 | 
			
		||||
	int i;
 | 
			
		||||
	int32_t end_sample = last_sample;
 | 
			
		||||
 | 
			
		||||
	for(i = 0; i < bp; ++i) {
 | 
			
		||||
		end_sample -= buf[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	current_packet.data[0].sample_word[1] = htonl(end_sample);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim1Encoder<T>::update_packet() {
 | 
			
		||||
	unsigned int nibble = 0;
 | 
			
		||||
	u_int32_t sample_word = 0;
 | 
			
		||||
 | 
			
		||||
	assert(bp < 5);
 | 
			
		||||
 | 
			
		||||
	int used = bp;
 | 
			
		||||
 | 
			
		||||
	while(used > spw) {
 | 
			
		||||
		--used;
 | 
			
		||||
		spw = 4;
 | 
			
		||||
		for(int i = 0; i < used; ++i) update_spw(i);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while(used < spw) spw >>= 1;
 | 
			
		||||
 | 
			
		||||
	used = spw;
 | 
			
		||||
 | 
			
		||||
	switch(spw) {
 | 
			
		||||
		case 4:
 | 
			
		||||
			nibble = 1;
 | 
			
		||||
			sample_word = ((buf[0] & 0xff) << 24) | ((buf[1] & 0xff) << 16) |
 | 
			
		||||
			              ((buf[2] & 0xff) <<  8) | (buf[3] & 0xff);
 | 
			
		||||
			break;
 | 
			
		||||
		case 2:
 | 
			
		||||
			nibble = 2;
 | 
			
		||||
			sample_word = ((buf[0] & 0xffff) << 16) | (buf[1] & 0xffff);
 | 
			
		||||
			break;
 | 
			
		||||
		case 1:
 | 
			
		||||
			nibble = 3;
 | 
			
		||||
			sample_word = buf[0];
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			assert(0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	nibble_word |= (nibble << (30 - ((fp + 1) << 1)));
 | 
			
		||||
 | 
			
		||||
	spw = 4;
 | 
			
		||||
	for(int i = 0; i < bp - used; ++i) {
 | 
			
		||||
		buf[i] = buf[i + used];
 | 
			
		||||
		update_spw(i);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bp -= used;
 | 
			
		||||
	_sampleCount += used;
 | 
			
		||||
 | 
			
		||||
	current_packet.data[frame_count].nibble_word = htonl(nibble_word);
 | 
			
		||||
	current_packet.data[frame_count].sample_word[fp] = htonl(sample_word);
 | 
			
		||||
	if(++fp < 15) return;
 | 
			
		||||
 | 
			
		||||
	nibble_word = 0;
 | 
			
		||||
	fp = 0;
 | 
			
		||||
	++frame_count;
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim1Encoder<T>::queue_packet(MSEEDEncoderPacket<Steim1Frame> &pckt) {
 | 
			
		||||
	format->updateBuffer(pckt.record, _sampleCount, frame_count + (fp > 0));
 | 
			
		||||
 | 
			
		||||
	Packet *packet = new Packet(DataRecordPtr(pckt.record), format->networkCode, format->stationCode,
 | 
			
		||||
	                            format->locationCode, format->channelCode);
 | 
			
		||||
	_packetQueue.push_back(PacketPtr(packet));
 | 
			
		||||
	pckt.reset();
 | 
			
		||||
	reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim1Encoder<T>::push(void *value) {
 | 
			
		||||
	int32_t sample_val = *static_cast<T*>(value);
 | 
			
		||||
	store(sample_val);
 | 
			
		||||
	_clk.tick();
 | 
			
		||||
 | 
			
		||||
	while(bp >= spw) {
 | 
			
		||||
		if(!current_packet.valid()) {
 | 
			
		||||
			current_packet = get_packet();
 | 
			
		||||
			init_packet();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		update_packet();
 | 
			
		||||
		if(frame_count == number_of_frames(current_packet)) {
 | 
			
		||||
			finish_packet();
 | 
			
		||||
			queue_packet(current_packet);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim1Encoder<T>::flush() {
 | 
			
		||||
	while(bp) {
 | 
			
		||||
		if(!current_packet.valid()) {
 | 
			
		||||
			current_packet = get_packet();
 | 
			
		||||
			init_packet();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		update_packet();
 | 
			
		||||
		if(frame_count == number_of_frames(current_packet)) {
 | 
			
		||||
			finish_packet();
 | 
			
		||||
			queue_packet(current_packet);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(current_packet.valid()) {
 | 
			
		||||
		finish_packet();
 | 
			
		||||
		queue_packet(current_packet);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								libs/gempa/caps/mseed/steim2.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								libs/gempa/caps/mseed/steim2.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,94 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * steim2.h
 | 
			
		||||
 *
 | 
			
		||||
 * Steim2 encoder
 | 
			
		||||
 *
 | 
			
		||||
 * (c) 2000 Andres Heinloo, GFZ Potsdam
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the
 | 
			
		||||
 * Free Software Foundation; either version 2, or (at your option) any later
 | 
			
		||||
 * version. For more information, see http://www.gnu.org/
 | 
			
		||||
 *
 | 
			
		||||
 * ================
 | 
			
		||||
 * Change log
 | 
			
		||||
 * ===============
 | 
			
		||||
 *
 | 
			
		||||
 * 01.01.2013 Adapted code to CAPS client library requirements (gempa GmbH)
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef CAPS_MSEED_STEIM2_H
 | 
			
		||||
#define CAPS_MSEED_STEIM2_H
 | 
			
		||||
 | 
			
		||||
#include "encoder.h"
 | 
			
		||||
#include "mseed.h"
 | 
			
		||||
 | 
			
		||||
namespace Gempa {
 | 
			
		||||
namespace CAPS {
 | 
			
		||||
 | 
			
		||||
//*****************************************************************************
 | 
			
		||||
// Steim2Frame
 | 
			
		||||
//*****************************************************************************
 | 
			
		||||
 | 
			
		||||
struct Steim2Frame {
 | 
			
		||||
	u_int32_t nibble_word;
 | 
			
		||||
	u_int32_t sample_word[15];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//*****************************************************************************
 | 
			
		||||
// Steim2Encoder
 | 
			
		||||
//*****************************************************************************
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
class Steim2Encoder : public Encoder {
 | 
			
		||||
	public:
 | 
			
		||||
		Steim2Encoder(MSEEDFormat *format, int freqn, int freqd)
 | 
			
		||||
		    : Encoder(freqn, freqd), format(format), frame_count(0),
 | 
			
		||||
		  bp(0), fp(0), spw(4), last_sample(0), nibble_word(0) {
 | 
			
		||||
		}
 | 
			
		||||
		virtual ~Steim2Encoder();
 | 
			
		||||
		virtual void flush();
 | 
			
		||||
 | 
			
		||||
		virtual void push(void *value);
 | 
			
		||||
		virtual int type() const { return DE_STEIM2; }
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		void update_spw(int bp);
 | 
			
		||||
		void store(int32_t value);
 | 
			
		||||
		void init_packet();
 | 
			
		||||
		void finish_packet();
 | 
			
		||||
		void update_packet();
 | 
			
		||||
 | 
			
		||||
		MSEEDEncoderPacket<Steim2Frame> get_packet() {
 | 
			
		||||
			return format->get_packet<Steim2Frame>(_clk.get_time(bp),
 | 
			
		||||
			                                       _clk.correction(), _timingQuality);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void queue_packet(MSEEDEncoderPacket<Steim2Frame> &pckt);
 | 
			
		||||
 | 
			
		||||
		int number_of_frames(const MSEEDEncoderPacket<Steim2Frame> &packet) {
 | 
			
		||||
			return (packet.datalen >> 6);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		MSEEDFormat *format;
 | 
			
		||||
		int frame_count;
 | 
			
		||||
		int bp;
 | 
			
		||||
		int fp;
 | 
			
		||||
		int32_t last_s;
 | 
			
		||||
		int spw;
 | 
			
		||||
		int32_t last_sample;
 | 
			
		||||
		int32_t buf[8];
 | 
			
		||||
		u_int32_t nibble_word;
 | 
			
		||||
		MSEEDEncoderPacket<Steim2Frame> current_packet;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "steim2.ipp"
 | 
			
		||||
 | 
			
		||||
#endif // __STEIM2_H__
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										241
									
								
								libs/gempa/caps/mseed/steim2.ipp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								libs/gempa/caps/mseed/steim2.ipp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,241 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * steim2.cc
 | 
			
		||||
 *
 | 
			
		||||
 * Steim2 encoder
 | 
			
		||||
 *
 | 
			
		||||
 * (c) 2004 Andres Heinloo, GFZ Potsdam
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify it
 | 
			
		||||
 * under the terms of the GNU General Public License as published by the
 | 
			
		||||
 * Free Software Foundation; either version 2, or (at your option) any later
 | 
			
		||||
 * version. For more information, see http://www.gnu.org/
 | 
			
		||||
 *
 | 
			
		||||
 * ================
 | 
			
		||||
 * Change log
 | 
			
		||||
 * ===============
 | 
			
		||||
 *
 | 
			
		||||
 * 01.01.2013 Adapted code to CAPS client library requirements (gempa GmbH)
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "../log.h"
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iomanip>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Gempa {
 | 
			
		||||
namespace CAPS {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T> Steim2Encoder<T>::~Steim2Encoder() {
 | 
			
		||||
	if ( format != NULL ) delete format;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim2Encoder<T>::update_spw(int bp) {
 | 
			
		||||
	assert(bp < 7);
 | 
			
		||||
 | 
			
		||||
	if(buf[bp] < -536870912) {
 | 
			
		||||
		CAPS_WARNING("%s.%s.%s.%s: value %d is too large for Steim2 encoding",
 | 
			
		||||
		             format->networkCode.c_str(), format->stationCode.c_str(),
 | 
			
		||||
		             format->locationCode.c_str(), format->channelCode.c_str(),
 | 
			
		||||
		             buf[bp]);
 | 
			
		||||
		buf[bp] = -536870912;
 | 
			
		||||
		spw = 1;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(buf[bp] > 536870911) {
 | 
			
		||||
		CAPS_WARNING("%s.%s.%s.%s: value %d is too large for Steim2 encoding",
 | 
			
		||||
		             format->networkCode.c_str(), format->stationCode.c_str(),
 | 
			
		||||
		             format->locationCode.c_str(), format->channelCode.c_str(),
 | 
			
		||||
		             buf[bp]);
 | 
			
		||||
		buf[bp] = 536870911;
 | 
			
		||||
		spw = 1;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int spw1 = 7;
 | 
			
		||||
	if(buf[bp] < -16384 || buf[bp] > 16383) spw1 = 1;
 | 
			
		||||
	else if(buf[bp] < -512 || buf[bp] > 511) spw1 = 2;
 | 
			
		||||
	else if(buf[bp] < -128 || buf[bp] > 127) spw1 = 3;
 | 
			
		||||
	else if(buf[bp] < -32 || buf[bp] > 31) spw1 = 4;
 | 
			
		||||
	else if(buf[bp] < -16 || buf[bp] > 15) spw1 = 5;
 | 
			
		||||
	else if(buf[bp] < -8  || buf[bp] > 7) spw1 = 6;
 | 
			
		||||
	if(spw1 < spw) spw = spw1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim2Encoder<T>::store(int32_t value) {
 | 
			
		||||
	assert(bp < 7);
 | 
			
		||||
	buf[bp] = value - last_sample;
 | 
			
		||||
	last_sample = value;
 | 
			
		||||
	update_spw(bp);
 | 
			
		||||
	++bp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim2Encoder<T>::init_packet() {
 | 
			
		||||
	int i;
 | 
			
		||||
	int32_t begin_sample = last_sample;
 | 
			
		||||
 | 
			
		||||
	for(i = 1; i < bp; ++i) {
 | 
			
		||||
		begin_sample -= buf[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	reset();
 | 
			
		||||
	current_packet.data[0].sample_word[0] = htonl(begin_sample);
 | 
			
		||||
	frame_count = 0;
 | 
			
		||||
	nibble_word = 0;
 | 
			
		||||
	fp = 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim2Encoder<T>::finish_packet() {
 | 
			
		||||
	int i;
 | 
			
		||||
	int32_t end_sample = last_sample;
 | 
			
		||||
 | 
			
		||||
	for(i = 0; i < bp; ++i) {
 | 
			
		||||
		end_sample -= buf[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	current_packet.data[0].sample_word[1] = htonl(end_sample);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim2Encoder<T>::update_packet() {
 | 
			
		||||
	unsigned int nibble = 0;
 | 
			
		||||
	u_int32_t sample_word = 0;
 | 
			
		||||
 | 
			
		||||
	assert(bp < 8);
 | 
			
		||||
 | 
			
		||||
	int used = bp;
 | 
			
		||||
 | 
			
		||||
	while(used > spw) {
 | 
			
		||||
		--used;
 | 
			
		||||
		spw = 7;
 | 
			
		||||
		for(int i = 0; i < used; ++i) update_spw(i);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	spw = used;
 | 
			
		||||
 | 
			
		||||
	switch(spw) {
 | 
			
		||||
		case 7:
 | 
			
		||||
			nibble = 3;
 | 
			
		||||
			sample_word = (2U << 30) | ((buf[0] & 0xf) << 24) |
 | 
			
		||||
				((buf[1] & 0xf) << 20) | ((buf[2] & 0xf) << 16) |
 | 
			
		||||
				((buf[3] & 0xf) << 12) | ((buf[4] & 0xf) << 8) |
 | 
			
		||||
				((buf[5] & 0xf) << 4) | (buf[6] & 0xf);
 | 
			
		||||
			break;
 | 
			
		||||
		case 6:
 | 
			
		||||
			nibble = 3;
 | 
			
		||||
			sample_word = (1U << 30) | ((buf[0] & 0x1f) << 25) |
 | 
			
		||||
				((buf[1] & 0x1f) << 20) | ((buf[2] & 0x1f) << 15) |
 | 
			
		||||
				((buf[3] & 0x1f) << 10) | ((buf[4] & 0x1f) << 5) |
 | 
			
		||||
				(buf[5] & 0x1f);
 | 
			
		||||
			break;
 | 
			
		||||
		case 5:
 | 
			
		||||
			nibble = 3;
 | 
			
		||||
			sample_word = ((buf[0] & 0x3f) << 24) | ((buf[1] & 0x3f) << 18) |
 | 
			
		||||
				((buf[2] & 0x3f) << 12) | ((buf[3] & 0x3f) << 6) |
 | 
			
		||||
				(buf[4] & 0x3f);
 | 
			
		||||
			break;
 | 
			
		||||
		case 4:
 | 
			
		||||
			nibble = 1;
 | 
			
		||||
			sample_word = ((buf[0] & 0xff) << 24) | ((buf[1] & 0xff) << 16) |
 | 
			
		||||
				((buf[2] & 0xff) <<  8) | (buf[3] & 0xff);
 | 
			
		||||
			break;
 | 
			
		||||
		case 3:
 | 
			
		||||
			nibble = 2;
 | 
			
		||||
			sample_word = (3U << 30) | ((buf[0] & 0x3ff) << 20) |
 | 
			
		||||
				((buf[1] & 0x3ff) << 10) | (buf[2] & 0x3ff);
 | 
			
		||||
			break;
 | 
			
		||||
		case 2:
 | 
			
		||||
			nibble = 2;
 | 
			
		||||
			sample_word = (2U << 30) | ((buf[0] & 0x7fff) << 15) |
 | 
			
		||||
				(buf[1] & 0x7fff);
 | 
			
		||||
			break;
 | 
			
		||||
		case 1:
 | 
			
		||||
			nibble = 2;
 | 
			
		||||
			sample_word = (1U << 30) | (buf[0] & 0x3fffffff);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			assert(0);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	nibble_word |= (nibble << (30 - ((fp + 1) << 1)));
 | 
			
		||||
 | 
			
		||||
	spw = 7;
 | 
			
		||||
	for(int i = 0; i < bp - used; ++i) {
 | 
			
		||||
		buf[i] = buf[i + used];
 | 
			
		||||
		update_spw(i);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bp -= used;
 | 
			
		||||
	_sampleCount += used;
 | 
			
		||||
 | 
			
		||||
	current_packet.data[frame_count].nibble_word = htonl(nibble_word);
 | 
			
		||||
	current_packet.data[frame_count].sample_word[fp] = htonl(sample_word);
 | 
			
		||||
	if(++fp < 15) return;
 | 
			
		||||
 | 
			
		||||
	nibble_word = 0;
 | 
			
		||||
	fp = 0;
 | 
			
		||||
	++frame_count;
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim2Encoder<T>::queue_packet(MSEEDEncoderPacket<Steim2Frame> &pckt) {
 | 
			
		||||
	format->updateBuffer(pckt.record, _sampleCount, frame_count + (fp > 0));
 | 
			
		||||
 | 
			
		||||
	Packet *packet = new Packet(DataRecordPtr(pckt.record), format->networkCode, format->stationCode,
 | 
			
		||||
	                            format->locationCode, format->channelCode);
 | 
			
		||||
	_packetQueue.push_back(PacketPtr(packet));
 | 
			
		||||
	pckt.reset();
 | 
			
		||||
	reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim2Encoder<T>::push(void *value) {
 | 
			
		||||
	int32_t sample_val = *static_cast<T*>(value);
 | 
			
		||||
	store(sample_val);
 | 
			
		||||
	_clk.tick();
 | 
			
		||||
 | 
			
		||||
	while ( bp >= spw ) {
 | 
			
		||||
		if( !current_packet.valid() ) {
 | 
			
		||||
			current_packet = get_packet();
 | 
			
		||||
			init_packet();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		update_packet();
 | 
			
		||||
		if ( frame_count == number_of_frames(current_packet) ) {
 | 
			
		||||
			finish_packet();
 | 
			
		||||
			queue_packet(current_packet);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T> void Steim2Encoder<T>::flush() {
 | 
			
		||||
	while ( bp ) {
 | 
			
		||||
		if ( !current_packet.valid() ) {
 | 
			
		||||
			current_packet = get_packet();
 | 
			
		||||
			init_packet();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		update_packet();
 | 
			
		||||
		if( frame_count == number_of_frames(current_packet) ) {
 | 
			
		||||
			finish_packet();
 | 
			
		||||
			queue_packet(current_packet);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ( current_packet.valid() ) {
 | 
			
		||||
		finish_packet();
 | 
			
		||||
		queue_packet(current_packet);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										84
									
								
								libs/gempa/caps/mseed/uncompressed.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								libs/gempa/caps/mseed/uncompressed.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,84 @@
 | 
			
		||||
/***************************************************************************
 | 
			
		||||
 * Copyright (C) 2013 by gempa GmbH                                        *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 * All Rights Reserved.                                                    *
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 * NOTICE: All information contained herein is, and remains                *
 | 
			
		||||
 * the property of gempa GmbH and its suppliers, if any. The intellectual  *
 | 
			
		||||
 * and technical concepts contained herein are proprietary to gempa GmbH   *
 | 
			
		||||
 * and its suppliers.                                                      *
 | 
			
		||||
 * Dissemination of this information or reproduction of this material      *
 | 
			
		||||
 * is strictly forbidden unless prior written permission is obtained       *
 | 
			
		||||
 * from gempa GmbH.                                                        *
 | 
			
		||||
 ***************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef CAPS_MSEED_UNCOMPRESSED_H
 | 
			
		||||
#define CAPS_MSEED_UNCOMPRESSED_H
 | 
			
		||||
 | 
			
		||||
#include "encoder.h"
 | 
			
		||||
#include "mseed.h"
 | 
			
		||||
 | 
			
		||||
#include <gempa/caps/endianess.h>
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
 | 
			
		||||
namespace Gempa {
 | 
			
		||||
namespace CAPS {
 | 
			
		||||
 | 
			
		||||
template<typename T> class UncompressedMSEED : public Encoder {
 | 
			
		||||
	MSEEDEncoderPacket<T> get_packet() {
 | 
			
		||||
		return _format->get_packet<T>(_clk.get_time(-_bp),
 | 
			
		||||
		                              _clk.correction(), _timingQuality);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void queue_packet(MSEEDEncoderPacket<T> &pckt) {
 | 
			
		||||
		_format->updateBuffer(pckt.record, _sampleCount, 1);
 | 
			
		||||
 | 
			
		||||
		Packet *packet = new Packet(DataRecordPtr(pckt.record), _format->networkCode, _format->stationCode,
 | 
			
		||||
		                            _format->locationCode, _format->channelCode);
 | 
			
		||||
		_packetQueue.push_back(PacketPtr(packet));
 | 
			
		||||
		pckt.reset();
 | 
			
		||||
		reset();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		UncompressedMSEED(MSEEDFormat *format, int freqn, int freqd)
 | 
			
		||||
		    : Encoder(freqn, freqd),
 | 
			
		||||
		      _format(format), _bp(0) {
 | 
			
		||||
		}
 | 
			
		||||
		virtual ~UncompressedMSEED() { if ( _format ) delete _format; }
 | 
			
		||||
		virtual void flush() {
 | 
			
		||||
			if ( _current_packet.valid() ) {
 | 
			
		||||
				queue_packet(_current_packet);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual void push(void *value) {
 | 
			
		||||
			if ( !_current_packet.valid() )
 | 
			
		||||
				_current_packet = get_packet();
 | 
			
		||||
			else if ( _sampleCount * sizeof(T) >= _current_packet.datalen ) {
 | 
			
		||||
				flush();
 | 
			
		||||
				_current_packet = get_packet();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			_current_packet.data[_sampleCount] =
 | 
			
		||||
			    Gempa::CAPS::Endianess::Converter::ToBigEndian<T>(*(T*)value);
 | 
			
		||||
			++_sampleCount;
 | 
			
		||||
			++_bp;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual int type() const { return _format->packType; }
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		MSEEDFormat               *_format;
 | 
			
		||||
		MSEEDEncoderPacket<T>      _current_packet;
 | 
			
		||||
		int                        _bp;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // __STEIM1_H__
 | 
			
		||||
		Reference in New Issue
	
	Block a user