| 1 | /**************************************************************************** |
|---|
| 2 | |
|---|
| 3 | Copyright 2006 Virginia Polytechnic Institute and State University |
|---|
| 4 | |
|---|
| 5 | This file is part of the OSSIE AutomaticGainControl. |
|---|
| 6 | |
|---|
| 7 | OSSIE AutomaticGainControl is free software; you can redistribute it and/or modify |
|---|
| 8 | it under the terms of the GNU General Public License as published by |
|---|
| 9 | the Free Software Foundation; either version 2 of the License, or |
|---|
| 10 | (at your option) any later version. |
|---|
| 11 | |
|---|
| 12 | OSSIE AutomaticGainControl is distributed in the hope that it will be useful, |
|---|
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 15 | GNU General Public License for more details. |
|---|
| 16 | |
|---|
| 17 | You should have received a copy of the GNU General Public License |
|---|
| 18 | along with OSSIE AutomaticGainControl; if not, write to the Free Software |
|---|
| 19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 20 | |
|---|
| 21 | ****************************************************************************/ |
|---|
| 22 | |
|---|
| 23 | |
|---|
| 24 | #include <string> |
|---|
| 25 | #include <iostream> |
|---|
| 26 | #include "AutomaticGainControl.h" |
|---|
| 27 | |
|---|
| 28 | #undef VERBOSE |
|---|
| 29 | |
|---|
| 30 | AutomaticGainControl_i::AutomaticGainControl_i(const char *uuid, omni_condition *condition) : Resource_impl(uuid), component_running(condition) |
|---|
| 31 | { |
|---|
| 32 | dataOut_0 = new standardInterfaces_i::complexShort_u("data_out"); |
|---|
| 33 | dataIn_0 = new standardInterfaces_i::complexShort_p("data_in"); |
|---|
| 34 | |
|---|
| 35 | // set initial values |
|---|
| 36 | // these particular values are good for 8kHz audio |
|---|
| 37 | energy_lo = 4000.0f; |
|---|
| 38 | energy_hi = 8000.0f; |
|---|
| 39 | k_attack = 0.002f; |
|---|
| 40 | k_release = 0.0005f; |
|---|
| 41 | g_min = 1.0f; |
|---|
| 42 | g_max = 100.0f; |
|---|
| 43 | |
|---|
| 44 | //Create the thread for the writer's processing function |
|---|
| 45 | processing_thread = new omni_thread(run, (void *) this); |
|---|
| 46 | |
|---|
| 47 | //Start the thread containing the writer's processing function |
|---|
| 48 | processing_thread->start(); |
|---|
| 49 | } |
|---|
| 50 | |
|---|
| 51 | AutomaticGainControl_i::~AutomaticGainControl_i(void) |
|---|
| 52 | { |
|---|
| 53 | delete dataOut_0; |
|---|
| 54 | delete dataIn_0; |
|---|
| 55 | } |
|---|
| 56 | |
|---|
| 57 | void AutomaticGainControl_i::run(void * data) |
|---|
| 58 | { |
|---|
| 59 | ((AutomaticGainControl_i*) data)->run_loop(); |
|---|
| 60 | } |
|---|
| 61 | |
|---|
| 62 | CORBA::Object_ptr AutomaticGainControl_i::getPort( const char* portName ) throw (CORBA::SystemException, CF::PortSupplier::UnknownPort) |
|---|
| 63 | { |
|---|
| 64 | std::cout << "AutomaticGainControl_i getPort called with : " << portName << std::endl; |
|---|
| 65 | |
|---|
| 66 | CORBA::Object_var p; |
|---|
| 67 | |
|---|
| 68 | p = dataOut_0->getPort(portName); |
|---|
| 69 | |
|---|
| 70 | if (!CORBA::is_nil(p)) |
|---|
| 71 | return p._retn(); |
|---|
| 72 | |
|---|
| 73 | p = dataIn_0->getPort(portName); |
|---|
| 74 | |
|---|
| 75 | if (!CORBA::is_nil(p)) |
|---|
| 76 | return p._retn(); |
|---|
| 77 | |
|---|
| 78 | /*exception*/ |
|---|
| 79 | throw CF::PortSupplier::UnknownPort(); |
|---|
| 80 | } |
|---|
| 81 | |
|---|
| 82 | void AutomaticGainControl_i::start() throw (CORBA::SystemException, CF::Resource::StartError) |
|---|
| 83 | { |
|---|
| 84 | std::cout << "start called on AutomaticGainControl" << std::endl; |
|---|
| 85 | } |
|---|
| 86 | |
|---|
| 87 | void AutomaticGainControl_i::stop() throw (CORBA::SystemException, CF::Resource::StopError) |
|---|
| 88 | { |
|---|
| 89 | std::cout << "stop called on AutomaticGainControl" << std::endl; |
|---|
| 90 | } |
|---|
| 91 | |
|---|
| 92 | void AutomaticGainControl_i::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) |
|---|
| 93 | { |
|---|
| 94 | std::cout << "releaseObject called on AutomaticGainControl" << std::endl; |
|---|
| 95 | |
|---|
| 96 | component_running->signal(); |
|---|
| 97 | } |
|---|
| 98 | |
|---|
| 99 | void AutomaticGainControl_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemException) |
|---|
| 100 | { |
|---|
| 101 | std::cout << "initialize called on AutomaticGainControl" << std::endl; |
|---|
| 102 | } |
|---|
| 103 | |
|---|
| 104 | void AutomaticGainControl_i::configure(const CF::Properties& props) throw (CORBA::SystemException, CF::PropertySet::InvalidConfiguration, CF::PropertySet::PartialConfiguration) |
|---|
| 105 | { |
|---|
| 106 | CORBA::Float simple_temp; |
|---|
| 107 | |
|---|
| 108 | std::cout << "configure called on AutomaticGainControl" << std::endl; |
|---|
| 109 | |
|---|
| 110 | std::cout << "props length : " << props.length() << std::endl; |
|---|
| 111 | |
|---|
| 112 | for (unsigned int i = 0; i <props.length(); i++) |
|---|
| 113 | { |
|---|
| 114 | std::cout << "Property id : " << props[i].id << std::endl; |
|---|
| 115 | |
|---|
| 116 | if (strcmp(props[i].id, "DCE:aaf97fa0-d184-4d88-9954-3a1334c73d6d") == 0) |
|---|
| 117 | { |
|---|
| 118 | // energy_lo |
|---|
| 119 | props[i].value >>= simple_temp; |
|---|
| 120 | omni_mutex_lock oml(accessPrivateData); |
|---|
| 121 | energy_lo = simple_temp; |
|---|
| 122 | #ifdef VERBOSE |
|---|
| 123 | std::cout << "AGC prop (energy_lo): " << simple_temp << std::endl; |
|---|
| 124 | #endif |
|---|
| 125 | } |
|---|
| 126 | |
|---|
| 127 | if (strcmp(props[i].id, "DCE:346e17c9-6678-483a-bffb-1909c64bddc0") == 0) |
|---|
| 128 | { |
|---|
| 129 | // energy_hi |
|---|
| 130 | props[i].value >>= simple_temp; |
|---|
| 131 | omni_mutex_lock oml(accessPrivateData); |
|---|
| 132 | energy_hi = simple_temp; |
|---|
| 133 | #ifdef VERBOSE |
|---|
| 134 | std::cout << "AGC prop (energy_hi): " << simple_temp << std::endl; |
|---|
| 135 | #endif |
|---|
| 136 | |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | if (strcmp(props[i].id, "DCE:4608b943-4fe2-49df-91fb-afa287b609d4") == 0) |
|---|
| 140 | { |
|---|
| 141 | // k_attack |
|---|
| 142 | props[i].value >>= simple_temp; |
|---|
| 143 | omni_mutex_lock oml(accessPrivateData); |
|---|
| 144 | k_attack = simple_temp; |
|---|
| 145 | #ifdef VERBOSE |
|---|
| 146 | std::cout << "AGC prop (k_attack): " << simple_temp << std::endl; |
|---|
| 147 | #endif |
|---|
| 148 | } |
|---|
| 149 | |
|---|
| 150 | if (strcmp(props[i].id, "DCE:491ec3de-ed45-48af-a6fc-ca2d6465e136") == 0) |
|---|
| 151 | { |
|---|
| 152 | // k_release |
|---|
| 153 | props[i].value >>= simple_temp; |
|---|
| 154 | omni_mutex_lock oml(accessPrivateData); |
|---|
| 155 | k_release = simple_temp; |
|---|
| 156 | #ifdef VERBOSE |
|---|
| 157 | std::cout << "AGC prop (k_release): " << simple_temp << std::endl; |
|---|
| 158 | #endif |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | if (strcmp(props[i].id, "DCE:312f63fe-709a-4217-933b-c584c8d6a9bb") == 0) |
|---|
| 162 | { |
|---|
| 163 | // g_min |
|---|
| 164 | props[i].value >>= simple_temp; |
|---|
| 165 | omni_mutex_lock oml(accessPrivateData); |
|---|
| 166 | g_min = simple_temp; |
|---|
| 167 | #ifdef VERBOSE |
|---|
| 168 | std::cout << "AGC prop (g_min): " << simple_temp << std::endl; |
|---|
| 169 | #endif |
|---|
| 170 | } |
|---|
| 171 | |
|---|
| 172 | if (strcmp(props[i].id, "DCE:8357ee0d-2417-46d9-8475-2e5778d797e4") == 0) |
|---|
| 173 | { |
|---|
| 174 | // g_max |
|---|
| 175 | props[i].value >>= simple_temp; |
|---|
| 176 | omni_mutex_lock oml(accessPrivateData); |
|---|
| 177 | g_max = simple_temp; |
|---|
| 178 | #ifdef VERBOSE |
|---|
| 179 | std::cout << "AGC prop (g_max): " << simple_temp << std::endl; |
|---|
| 180 | #endif |
|---|
| 181 | } |
|---|
| 182 | |
|---|
| 183 | } |
|---|
| 184 | } |
|---|
| 185 | |
|---|
| 186 | |
|---|
| 187 | void AutomaticGainControl_i::run_loop() |
|---|
| 188 | { |
|---|
| 189 | std::cout << "AutomaticGainControl's process_data thread started" << std::endl; |
|---|
| 190 | |
|---|
| 191 | PortTypes::ShortSequence I_out, Q_out; |
|---|
| 192 | |
|---|
| 193 | PortTypes::ShortSequence *I_in(NULL), *Q_in(NULL); |
|---|
| 194 | //CORBA::UShort I_in_length, Q_in_length; |
|---|
| 195 | |
|---|
| 196 | unsigned int i, N; |
|---|
| 197 | short I, Q; |
|---|
| 198 | |
|---|
| 199 | SigProc::agc * agc; |
|---|
| 200 | |
|---|
| 201 | agc = new SigProc::agc(); |
|---|
| 202 | agc->set_values( |
|---|
| 203 | energy_lo, |
|---|
| 204 | energy_hi, |
|---|
| 205 | k_attack, |
|---|
| 206 | k_release, |
|---|
| 207 | g_min, |
|---|
| 208 | g_max |
|---|
| 209 | ); |
|---|
| 210 | |
|---|
| 211 | while( true ) |
|---|
| 212 | { |
|---|
| 213 | dataIn_0->getData(I_in, Q_in); |
|---|
| 214 | |
|---|
| 215 | // overwrite agc values with properties |
|---|
| 216 | // lock mutex for asynchronous configure() invocation |
|---|
| 217 | { |
|---|
| 218 | omni_mutex_lock oml(accessPrivateData); |
|---|
| 219 | agc->set_values( |
|---|
| 220 | energy_lo, |
|---|
| 221 | energy_hi, |
|---|
| 222 | k_attack, |
|---|
| 223 | k_release, |
|---|
| 224 | g_min, |
|---|
| 225 | g_max |
|---|
| 226 | ); |
|---|
| 227 | } |
|---|
| 228 | |
|---|
| 229 | N = I_in->length(); |
|---|
| 230 | |
|---|
| 231 | I_out.length(N); // define output length |
|---|
| 232 | Q_out.length(N); // define output length |
|---|
| 233 | |
|---|
| 234 | for (i=0; i<N; i++) |
|---|
| 235 | { |
|---|
| 236 | I = (*I_in)[i]; |
|---|
| 237 | Q = (*Q_in)[i]; |
|---|
| 238 | agc->do_work(I, Q); |
|---|
| 239 | I_out[i] = I; |
|---|
| 240 | Q_out[i] = Q; |
|---|
| 241 | } |
|---|
| 242 | #ifdef VERBOSE |
|---|
| 243 | float gain(0.0f), energy(0.0f); |
|---|
| 244 | agc->get_status(gain, energy); |
|---|
| 245 | std::cout << "AutomaticGainControl: gain: " << gain |
|---|
| 246 | << ", energy: " << energy << std::endl; |
|---|
| 247 | #endif |
|---|
| 248 | |
|---|
| 249 | dataIn_0->bufferEmptied(); |
|---|
| 250 | dataOut_0->pushPacket(I_out, Q_out); |
|---|
| 251 | } |
|---|
| 252 | } |
|---|
| 253 | |
|---|
| 254 | |
|---|