annotate trunk/src/Modules/Output/OSCOutput.cc @ 706:f8e90b5d85fd tip

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