001 package edu.nrao.sss.electronics; 002 003 import javax.xml.bind.annotation.XmlElement; 004 005 import edu.nrao.sss.astronomy.PolarizationType; 006 import edu.nrao.sss.measure.Frequency; 007 import edu.nrao.sss.measure.FrequencyRange; 008 import edu.nrao.sss.util.StringUtil; 009 010 /** 011 * A {@link Signal frequency signal} that has been digitized. 012 * <p> 013 * <b>Version Info:</b> 014 * <table style="margin-left:2em"> 015 * <tr><td>$Revision: 1707 $</td></tr> 016 * <tr><td>$Date: 2008-11-14 10:23:59 -0700 (Fri, 14 Nov 2008) $</td></tr> 017 * <tr><td>$Author: dharland $ (last person to modify)</td></tr> 018 * </table></p> 019 * 020 * @author David M. Harland 021 * @since 2007-10-24 022 */ 023 public class DigitalSignal 024 extends Signal 025 { 026 @XmlElement private Frequency samplingRate; 027 @XmlElement private int bitDepth; 028 029 /** 030 * Creates a new digital signal with the given attributes. 031 * 032 * @param originalRange 033 * the frequency range of this signal. If this value is <i>null</i> 034 * a {@link NullPointerException} will be thrown. 035 * 036 * @param polarization 037 * the polarization of this signal. If this value is <i>null</i> 038 * it will be converted to {@link PolarizationType#UNSPECIFIED}. 039 * 040 * @param samplingRate 041 * the number of samples taken per second. 042 * 043 * @param bitsPerSample 044 * the number of bits per sample. If this value is less than one 045 * an {@link IllegalArgumentException} will be thrown. 046 */ 047 public DigitalSignal(FrequencyRange originalRange, 048 PolarizationType polarization, 049 Frequency samplingRate, 050 int bitsPerSample) 051 { 052 super(originalRange, polarization); 053 init(samplingRate, bitsPerSample); 054 } 055 056 /** 057 * Creates a new digital signal from another signal. 058 * 059 * @param analogSignal 060 * another signal, usually analog, whose properties will 061 * be copied into this signal. 062 * 063 * @param samplingRate 064 * the number of samples taken per second. 065 * 066 * @param bitsPerSample 067 * the number of bits per sample. If this value is less than one 068 * an {@link IllegalArgumentException} will be thrown. 069 */ 070 public DigitalSignal(Signal analogSignal, 071 Frequency samplingRate, 072 int bitsPerSample) 073 { 074 super(analogSignal); 075 init(samplingRate, bitsPerSample); 076 } 077 078 //This method is here only for frameworks such 079 //as JAXB and Hibernate that need no-arg constructors. 080 @SuppressWarnings("unused") 081 private DigitalSignal() 082 { 083 super(); 084 samplingRate = new Frequency(); 085 bitDepth = 0; 086 } 087 088 /** Does the work for the constructors. */ 089 private void init(Frequency rate, int bits) 090 { 091 if (bits < 1) 092 throw new IllegalArgumentException("bitsPerSample may not be " + 093 bits + ", it must be greater than zero."); 094 095 samplingRate = rate.clone(); 096 bitDepth = bits; 097 } 098 099 /** 100 * Returns the rate at which this signal was sampled. 101 * @return the rate at which this signal was sampled. 102 */ 103 public Frequency getSamplingRate() 104 { 105 return samplingRate; 106 } 107 108 /** 109 * Returns the number of bits per sample. 110 * @return the number of bits per sample. 111 */ 112 public int getBitDepth() 113 { 114 return bitDepth; 115 } 116 117 /** 118 * Returns a text representation of this signal. 119 */ 120 @Override 121 public String toString() 122 { 123 final String EOL = StringUtil.EOL; 124 125 StringBuilder buff = new StringBuilder(super.toString()); 126 127 buff.append("Bits per Sample....").append(bitDepth).append(EOL); 128 buff.append("Sampling Rate......").append(samplingRate).append(EOL); 129 130 return buff.toString(); 131 } 132 133 /** 134 * Creates and returns a copy of this signal. 135 * <p> 136 * If anything goes wrong during the cloning procedure, 137 * a {@link RuntimeException} will be thrown.</p> 138 */ 139 @Override 140 public DigitalSignal clone() 141 { 142 DigitalSignal clone = null; 143 144 try 145 { 146 clone = (DigitalSignal)super.clone(); 147 148 clone.samplingRate = this.samplingRate.clone(); 149 } 150 catch (Exception ex) 151 { 152 throw new RuntimeException(ex); 153 } 154 155 return clone; 156 } 157 158 /** Returns <i>true</i> if {@code o} is equal to this signal. */ 159 @Override 160 public boolean equals(Object o) 161 { 162 //Quick exit if o is this 163 if (o == this) 164 return true; 165 166 //Quick exit if super class finds difference 167 if (!super.equals(o)) 168 return false; 169 170 //A safe cast if we got this far 171 DigitalSignal other = (DigitalSignal)o; 172 173 //Intentionally not comparing slope, intercept, and mappingUnits 174 return 175 other.samplingRate.equals(this.samplingRate) && 176 other.bitDepth == this.bitDepth; 177 } 178 179 /** Returns a hash code value for this signal. */ 180 @Override 181 public int hashCode() 182 { 183 //Taken from the Effective Java book by Joshua Bloch. 184 //The constants 17 & 37 are arbitrary & carry no meaning. 185 int result = super.hashCode(); 186 187 //You MUST keep this method in sync w/ the equals method 188 189 result = 37 * result + samplingRate.hashCode(); 190 result = 37 * result + bitDepth; 191 192 return result; 193 } 194 }