annotate src/Modules/Output/OSCOutput.cc @ 611:0fbaf443ec82

Carfac C++ revision 3, indluding more style improvements. The output structs are now classes again, and have separate storage methods for each output structure along with flags in the Run and RunSegment methods to allow for only storing NAPs if desired.
author alexbrandmeyer
date Fri, 17 May 2013 19:52:45 +0000
parents 0284d2152e17
children
rev   line source
tomwalters@509 1 // Copyright 2012, Tom Walters
tomwalters@509 2 //
tomwalters@509 3 // AIM-C: A C++ implementation of the Auditory Image Model
tomwalters@509 4 // http://www.acousticscale.org/AIMC
tomwalters@509 5 //
tomwalters@509 6 // Licensed under the Apache License, Version 2.0 (the "License");
tomwalters@509 7 // you may not use this file except in compliance with the License.
tomwalters@509 8 // You may obtain a copy of the License at
tomwalters@509 9 //
tomwalters@509 10 // http://www.apache.org/licenses/LICENSE-2.0
tomwalters@509 11 //
tomwalters@509 12 // Unless required by applicable law or agreed to in writing, software
tomwalters@509 13 // distributed under the License is distributed on an "AS IS" BASIS,
tomwalters@509 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
tomwalters@509 15 // See the License for the specific language governing permissions and
tomwalters@509 16 // limitations under the License.
tomwalters@509 17
tomwalters@509 18 /*!
tomwalters@509 19 * \author Tom Walters <tom@acousticscale.org>
tomwalters@509 20 * \date created 2012/02/17
tomwalters@509 21 * \version \$Id$
tomwalters@509 22 */
tomwalters@509 23
tomwalters@509 24 #include "Modules/Output/OSCOutput.h"
tomwalters@509 25
tomwalters@509 26 namespace aimc {
tomwalters@509 27 OSCOutput::OSCOutput(Parameters *params) : Module(params) {
tomwalters@509 28 module_description_ = "OSC output";
tomwalters@509 29 module_identifier_ = "osc_out";
tomwalters@509 30 module_type_ = "output";
tomwalters@509 31 module_version_ = "$Id$";
tomwalters@509 32
tomwalters@509 33 // Read parameter values from the parameter store. Setting any default
tomwalters@509 34 // values as necessary. The module should set defaults for all parameters
tomwalters@509 35 // that is uses here. The parameters_->DefaultType() methods look for a
tomwalters@509 36 // parameter with a given name. If it already exists in the parameter
tomwalters@509 37 // store, they return the current value. If the parameter doesn't already
tomwalters@509 38 // exist, it is added, set to the default value given, and that value is
tomwalters@509 39 // returned.
tomwalters@509 40 // Examples:
tomwalters@509 41 // integer_param_ = parameters_->DefaultInt("module.param_name", 4);
tomwalters@509 42 // boolean_param_ = parameters_->DefaultBool("module.param_name", true);
tomwalters@509 43 // float_param_ = parameters_->DefaultFloat("module.param_name", 4.4f);
tomwalters@509 44
tomwalters@509 45 address_ = parameters_->DefaultString("osc.send_address", "127.0.0.1");
tomwalters@509 46 port_ = parameters_->DefaultInt("osc.send_port", 6448);
tomwalters@509 47 output_buffer_size_ = parameters_->DefaultInt("osc.output_min_buffer_size", 1024);
tomwalters@509 48 }
tomwalters@509 49
tomwalters@509 50 OSCOutput::~OSCOutput() {
tomwalters@509 51 }
tomwalters@509 52
tomwalters@509 53 bool OSCOutput::InitializeInternal(const SignalBank &input) {
tomwalters@509 54 // Copy the parameters of the input signal bank into internal variables, so
tomwalters@509 55 // that they can be checked later.
tomwalters@509 56 sample_rate_ = input.sample_rate();
tomwalters@509 57 buffer_length_ = input.buffer_length();
tomwalters@509 58 channel_count_ = input.channel_count();
tomwalters@509 59
tomwalters@509 60 int output_byte_count = buffer_length_ * channel_count_ * 4 + 2048; // TODO(tom) Find out what the real byte overhead is.
tomwalters@509 61 if (output_buffer_size_ < output_byte_count) {
tomwalters@509 62 output_buffer_size_ = output_byte_count;
tomwalters@509 63 }
tomwalters@509 64 LOG_INFO("Output buffer size is %d", output_buffer_size_);
tomwalters@509 65 LOG_INFO("Feature count is %d", buffer_length_ * channel_count_);
tomwalters@509 66 transmit_socket_ = new UdpTransmitSocket(IpEndpointName(address_.c_str(), port_));
tomwalters@509 67 buffer_ = new char[output_buffer_size_];
tomwalters@509 68 packet_stream_ = new osc::OutboundPacketStream(buffer_, output_buffer_size_);
tomwalters@509 69
tomwalters@509 70 // If this module produces any output, then the output signal bank needs to
tomwalters@509 71 // be initialized here.
tomwalters@509 72 // Example:
tomwalters@509 73 // output_.Initialize(channel_count, buffer_length, sample_rate);
tomwalters@509 74 return true;
tomwalters@509 75 }
tomwalters@509 76
tomwalters@509 77 void OSCOutput::ResetInternal() {
tomwalters@509 78 // Reset any internal state variables to their default values here. After a
tomwalters@509 79 // call to ResetInternal(), the module should be in the same state as it is
tomwalters@509 80 // just after a call to InitializeInternal().
tomwalters@509 81 }
tomwalters@509 82
tomwalters@509 83 void OSCOutput::Process(const SignalBank &input) {
tomwalters@509 84 // Check to see if the module has been initialized. If not, processing
tomwalters@509 85 // should not continue.
tomwalters@509 86 if (!initialized_) {
tomwalters@509 87 LOG_ERROR(_T("Module %s not initialized."), module_identifier_.c_str());
tomwalters@509 88 return;
tomwalters@509 89 }
tomwalters@509 90
tomwalters@509 91 // Check that ths input this time is the same as the input passed to
tomwalters@509 92 // Initialize()
tomwalters@509 93 if (buffer_length_ != input.buffer_length()
tomwalters@509 94 || channel_count_ != input.channel_count()) {
tomwalters@509 95 LOG_ERROR(_T("Mismatch between input to Initialize() and input to "
tomwalters@509 96 "Process() in module %s."), module_identifier_.c_str());
tomwalters@509 97 return;
tomwalters@509 98 }
tomwalters@509 99
tomwalters@509 100 // Input is read from the input signal bank using calls like
tomwalters@509 101 // float value = input_.sample(channel_number, sample_index);
tomwalters@509 102
tomwalters@509 103 (*packet_stream_) << osc::BeginMessage( "/oscCustomFeatures" );
tomwalters@509 104 for (int ch = 0; ch < input.channel_count(); ch++) {
tomwalters@509 105 for (int i = 0; i < input.buffer_length(); i++) {
tomwalters@509 106 float s = input.sample(ch, i);
tomwalters@509 107 (*packet_stream_) << s;
tomwalters@509 108 }
tomwalters@509 109 }
tomwalters@509 110 (*packet_stream_) << osc::EndMessage;
tomwalters@509 111 transmit_socket_->Send(packet_stream_->Data(), packet_stream_->Size());
tomwalters@509 112 packet_stream_->Clear();
tomwalters@509 113
tomwalters@509 114 // Output is fed into the output signal bank (assuming that it was
tomwalters@509 115 // initialized during the call to InitializeInternal()) like this:
tomwalters@509 116 // output_.set_sample(channel_number, sample_index, sample_value);
tomwalters@509 117
tomwalters@509 118 // If the output bank is set up, a call to PushOutput() will pass the output
tomwalters@509 119 // on to all the target modules of this module. PushOutput() can be called
tomwalters@509 120 // multiple times within each call to Process().
tomwalters@509 121 // Example:
tomwalters@509 122 // PushOutput();
tomwalters@509 123 }
tomwalters@509 124 } // namespace aimc
tomwalters@509 125