| 1 | /**************************************************************************** |
|---|
| 2 | |
|---|
| 3 | Copyright 2009 by your_name_or_organization, all rights reserved. |
|---|
| 4 | |
|---|
| 5 | ****************************************************************************/ |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | #include <string> |
|---|
| 9 | #include <iostream> |
|---|
| 10 | #include "MIMODec.h" |
|---|
| 11 | |
|---|
| 12 | using namespace arma; |
|---|
| 13 | |
|---|
| 14 | MIMODec_i::MIMODec_i(const char *uuid, omni_condition *condition) : |
|---|
| 15 | Resource_impl(uuid), component_running(condition) { |
|---|
| 16 | dataOut = new standardInterfaces_i::complexShort_u("Symbols_OUT"); |
|---|
| 17 | dataIn = new standardInterfaces_i::complexShort_p("MUX_MIMO_Symbols_IN"); |
|---|
| 18 | Mr=1; |
|---|
| 19 | Nt=1; |
|---|
| 20 | MIMOmethod=0; |
|---|
| 21 | Modmethod="BPSK"; |
|---|
| 22 | |
|---|
| 23 | //Create the thread for the writer's processing function |
|---|
| 24 | processing_thread = new omni_thread(Run, (void *) this); |
|---|
| 25 | |
|---|
| 26 | //Start the thread containing the writer's processing function |
|---|
| 27 | processing_thread->start(); |
|---|
| 28 | |
|---|
| 29 | } |
|---|
| 30 | |
|---|
| 31 | MIMODec_i::~MIMODec_i(void) { |
|---|
| 32 | delete dataOut; |
|---|
| 33 | delete dataIn; |
|---|
| 34 | } |
|---|
| 35 | |
|---|
| 36 | // Static function for omni thread |
|---|
| 37 | void MIMODec_i::Run( void * data ) { |
|---|
| 38 | ((MIMODec_i*)data)->ProcessData(); |
|---|
| 39 | } |
|---|
| 40 | |
|---|
| 41 | CORBA::Object_ptr MIMODec_i::getPort( const char* portName ) throw ( |
|---|
| 42 | CORBA::SystemException, CF::PortSupplier::UnknownPort) { |
|---|
| 43 | DEBUG(3, MIMODec, "getPort() invoked with " << portName) |
|---|
| 44 | |
|---|
| 45 | CORBA::Object_var p; |
|---|
| 46 | |
|---|
| 47 | p = dataOut->getPort(portName); |
|---|
| 48 | |
|---|
| 49 | if (!CORBA::is_nil(p)) |
|---|
| 50 | return p._retn(); |
|---|
| 51 | |
|---|
| 52 | p = dataIn->getPort(portName); |
|---|
| 53 | |
|---|
| 54 | if (!CORBA::is_nil(p)) |
|---|
| 55 | return p._retn(); |
|---|
| 56 | |
|---|
| 57 | /*exception*/ |
|---|
| 58 | throw CF::PortSupplier::UnknownPort(); |
|---|
| 59 | } |
|---|
| 60 | |
|---|
| 61 | void MIMODec_i::start() throw (CORBA::SystemException, |
|---|
| 62 | CF::Resource::StartError) { |
|---|
| 63 | DEBUG(3, MIMODec, "start() invoked") |
|---|
| 64 | } |
|---|
| 65 | |
|---|
| 66 | void MIMODec_i::stop() throw (CORBA::SystemException, CF::Resource::StopError) { |
|---|
| 67 | DEBUG(3, MIMODec, "stop() invoked") |
|---|
| 68 | } |
|---|
| 69 | |
|---|
| 70 | void MIMODec_i::releaseObject() throw (CORBA::SystemException, |
|---|
| 71 | CF::LifeCycle::ReleaseError) { |
|---|
| 72 | DEBUG(3, MIMODec, "releaseObject() invoked") |
|---|
| 73 | |
|---|
| 74 | component_running->signal(); |
|---|
| 75 | } |
|---|
| 76 | |
|---|
| 77 | void MIMODec_i::initialize() throw (CF::LifeCycle::InitializeError, |
|---|
| 78 | CORBA::SystemException) { |
|---|
| 79 | DEBUG(3, MIMODec, "initialize() invoked") |
|---|
| 80 | } |
|---|
| 81 | |
|---|
| 82 | void MIMODec_i::configure(const CF::Properties& props) |
|---|
| 83 | throw (CORBA::SystemException, |
|---|
| 84 | CF::PropertySet::InvalidConfiguration, |
|---|
| 85 | CF::PropertySet::PartialConfiguration) { |
|---|
| 86 | DEBUG(3, MIMODec, "configure() invoked") |
|---|
| 87 | |
|---|
| 88 | std::cout << "props length : " << props.length() << std::endl; |
|---|
| 89 | |
|---|
| 90 | for (unsigned int i = 0; i <props.length(); i++) { |
|---|
| 91 | std::cout << "Property id : " << props[i].id << std::endl; |
|---|
| 92 | |
|---|
| 93 | if (strcmp(props[i].id, "DCE:4c5f385e-3b3e-11de-b7e0-0000e80014f9") == 0) { |
|---|
| 94 | CORBA::Short simple_temp; |
|---|
| 95 | props[i].value >>= simple_temp; |
|---|
| 96 | Nt = simple_temp; |
|---|
| 97 | } |
|---|
| 98 | |
|---|
| 99 | if (strcmp(props[i].id, "DCE:74a38a7c-3b3e-11de-b7e0-0000e80014f9") == 0) { |
|---|
| 100 | const char * prop_str; |
|---|
| 101 | //string prop_str; |
|---|
| 102 | props[i].value >>= prop_str; |
|---|
| 103 | //prop_str=prop_char; |
|---|
| 104 | |
|---|
| 105 | if (strcmp(prop_str,"MRC")) { |
|---|
| 106 | MIMOmethod=0; |
|---|
| 107 | |
|---|
| 108 | } else if (strcmp(prop_str,"STBC")) { |
|---|
| 109 | MIMOmethod=1; |
|---|
| 110 | |
|---|
| 111 | } else if (strcmp(prop_str,"VBLAST")) { |
|---|
| 112 | MIMOmethod=2; |
|---|
| 113 | }; |
|---|
| 114 | } |
|---|
| 115 | |
|---|
| 116 | if (strcmp(props[i].id, "DCE:a1026f5c-3b3e-11de-b7e0-0000e80014f9") == 0) { |
|---|
| 117 | CORBA::Short simple_temp; |
|---|
| 118 | props[i].value >>= simple_temp; |
|---|
| 119 | Mr = simple_temp; |
|---|
| 120 | } |
|---|
| 121 | |
|---|
| 122 | if (strcmp(props[i].id, "DCE:17cabf40-3b3f-11de-b7e0-0000e80014f9") == 0) { |
|---|
| 123 | const char * prop_str; |
|---|
| 124 | props[i].value >>= prop_str; |
|---|
| 125 | Modmethod=prop_str; |
|---|
| 126 | } |
|---|
| 127 | } |
|---|
| 128 | } |
|---|
| 129 | |
|---|
| 130 | void MIMODec_i::ProcessData() { |
|---|
| 131 | DEBUG(3, MIMODec, "ProcessData() invoked") |
|---|
| 132 | |
|---|
| 133 | PortTypes::ShortSequence I_out, Q_out; |
|---|
| 134 | |
|---|
| 135 | |
|---|
| 136 | PortTypes::ShortSequence *I_in(NULL), *Q_in(NULL); |
|---|
| 137 | CORBA::UShort Data_length; |
|---|
| 138 | short int NH; |
|---|
| 139 | |
|---|
| 140 | while (1) { |
|---|
| 141 | // Mr=4; |
|---|
| 142 | // Nt=1; |
|---|
| 143 | |
|---|
| 144 | |
|---|
| 145 | dataIn->getData(I_in, Q_in); |
|---|
| 146 | |
|---|
| 147 | Data_length = I_in->length(); |
|---|
| 148 | |
|---|
| 149 | NH=Mr*Nt; |
|---|
| 150 | std::cout<<"NH:"<<NH<<std::endl; |
|---|
| 151 | |
|---|
| 152 | |
|---|
| 153 | I_out.length((Data_length-NH)/Mr); //must define length of output |
|---|
| 154 | Q_out.length((Data_length-NH)/Mr); //must define length of output |
|---|
| 155 | |
|---|
| 156 | /*insert code here to do work*/ |
|---|
| 157 | |
|---|
| 158 | |
|---|
| 159 | cx_mat H(Mr,Nt); |
|---|
| 160 | MIMOmethod=0; |
|---|
| 161 | std::cout<<NH<<","<<Mr<<"X"<<Nt<<" M:"<< MIMOmethod<<" DL:"<<Data_length<<std::endl; |
|---|
| 162 | for (int i=0;i<Mr;i++) { |
|---|
| 163 | for (int j=0;j<Nt;j++) { |
|---|
| 164 | H(i,j)=cx_double((*I_in)[i*Mr+j],(*Q_in)[i*Mr+j])/10000.0; |
|---|
| 165 | //std::cout<<"Iin:"<<(*I_in)[i*2+j]<<" "; |
|---|
| 166 | // std::cout<<"H("<<i<<","<<j<<")="<<H(i,j)<<" "; |
|---|
| 167 | } |
|---|
| 168 | } |
|---|
| 169 | // std::cout<<std::endl; |
|---|
| 170 | |
|---|
| 171 | cx_double r1; |
|---|
| 172 | cx_double r2; |
|---|
| 173 | cx_mat rx_symbols(((Data_length-NH)/Mr),1); |
|---|
| 174 | short int j=0; |
|---|
| 175 | |
|---|
| 176 | switch (MIMOmethod) { |
|---|
| 177 | case 0: |
|---|
| 178 | j=0; |
|---|
| 179 | |
|---|
| 180 | for (short int i=NH; i<Data_length;i+=Mr) { |
|---|
| 181 | // std::cout<<i<<","<<j; |
|---|
| 182 | rx_symbols(j,0)=0; |
|---|
| 183 | |
|---|
| 184 | for (short int k=0;k<Mr;k++) { |
|---|
| 185 | r1=cx_double((*I_in)[i+k],(*Q_in)[i+k]); |
|---|
| 186 | rx_symbols(j,0)+=r1*conj(H(k,0)); |
|---|
| 187 | // std::cout<<","<<k; |
|---|
| 188 | } |
|---|
| 189 | //std::cout<<std::endl; |
|---|
| 190 | |
|---|
| 191 | j+=1; |
|---|
| 192 | } |
|---|
| 193 | |
|---|
| 194 | break; |
|---|
| 195 | case 1: |
|---|
| 196 | //std::cout<<std::endl; |
|---|
| 197 | |
|---|
| 198 | /*Alamouti |
|---|
| 199 | for i=1:2:length(RX_symbols1), |
|---|
| 200 | r1=RX_symbols1(i); |
|---|
| 201 | r2=RX_symbols1(i+1); |
|---|
| 202 | RX_symbols(i)=r1*conj(H(1,1))+conj(r2)*H(1,2); |
|---|
| 203 | RX_symbols(i+1)=r1*conj(H(1,2))-conj(r2)*H(1,1); |
|---|
| 204 | end; |
|---|
| 205 | */ |
|---|
| 206 | |
|---|
| 207 | |
|---|
| 208 | |
|---|
| 209 | j=0; |
|---|
| 210 | //std::cout<<"Decode"<<std::endl; |
|---|
| 211 | //std::cout<<"Hdec="<<H; |
|---|
| 212 | |
|---|
| 213 | for (short int i=NH; i<Data_length;i+=2*Mr) { |
|---|
| 214 | rx_symbols(j,0)=0; |
|---|
| 215 | rx_symbols(j+1,0)=0; |
|---|
| 216 | |
|---|
| 217 | for (short int k=0;k<Mr;k++) { |
|---|
| 218 | r1=cx_double((*I_in)[i+k],(*Q_in)[i+k]); |
|---|
| 219 | r2=cx_double((*I_in)[i+Mr+k],(*Q_in)[i+Mr+k]); |
|---|
| 220 | rx_symbols(j,0)+=r1*conj(H(k,0))+conj(r2)*H(k,1); |
|---|
| 221 | rx_symbols(j+1,0)+=r1*conj(H(k,1))-conj(r2)*H(k,0); |
|---|
| 222 | |
|---|
| 223 | } |
|---|
| 224 | |
|---|
| 225 | j+=2; |
|---|
| 226 | } |
|---|
| 227 | |
|---|
| 228 | break; |
|---|
| 229 | case 2: |
|---|
| 230 | break; |
|---|
| 231 | } |
|---|
| 232 | |
|---|
| 233 | double scale=1; |
|---|
| 234 | for (short int i=0; i<((Data_length-NH)/Mr);i++) { |
|---|
| 235 | |
|---|
| 236 | if ( (real(rx_symbols(i,0))>30000)||(imag(rx_symbols(i,0))>30000)) |
|---|
| 237 | scale=20; |
|---|
| 238 | else |
|---|
| 239 | scale=1; |
|---|
| 240 | |
|---|
| 241 | |
|---|
| 242 | I_out[i]=(CORBA::Short)(real(rx_symbols(i,0))/scale); |
|---|
| 243 | Q_out[i]=(CORBA::Short)(imag(rx_symbols(i,0))/scale); |
|---|
| 244 | //std::cout<<"Symbol"<<rx_symbols(i,0)<<std::endl; |
|---|
| 245 | //std::cout<<"("<<i<<")"<<"I:"<<I_out[i]<<"Q:"<<Q_out[i]<<std::endl; |
|---|
| 246 | } |
|---|
| 247 | |
|---|
| 248 | dataIn->bufferEmptied(); |
|---|
| 249 | dataOut->pushPacket(I_out, Q_out); |
|---|
| 250 | } |
|---|
| 251 | } |
|---|
| 252 | |
|---|
| 253 | |
|---|