Локальные TCP-сокеты Boost.Asio в не могут писать успешно более одного раза?

Я пытаюсь создать аудио плагин, который может подключаться к локальному серверу Java и отправлять ему данные через сокет (TCP). Поскольку я услышал много хороших вещей об этом, я использую библиотеку ASIO Boost, чтобы сделать работу.

У меня довольно странная ошибка в моем коде: мой клиент AudioUnit C ++ (который я использую изнутри DAW, я тестирую с Ableton Live и Logic Pro) может нормально подключаться к моему Java-серверу, но когда я делаю запись операция, кажется, моя запись выполняется правильно только один раз (например, я могу контролировать любое входящее сообщение на моем Java-сервере, и только первое сообщение видно)

Я использую следующий код:

— Внутри заголовка:

boost::asio::io_service io_service;
boost::asio::ip::tcp::socket mySocket(io_service);
boost::asio::ip::tcp::endpoint myEndpoint(boost::asio::ip::address::from_string("127.0.0.1"), 9001);
boost::system::error_code ignored_error;

— Внутри конструктора моего плагина

mySocket.connect(myEndpoint);

— И когда я пытаюсь отправить:

boost::asio::write(mySocket, boost::asio::buffer(datastring), ignored_error);

(вы заметите, что я не закрываю свою розетку, потому что я хотел бы, чтобы она жила вечно)

Я не думаю, что проблема исходит от моего Java-сервера (хотя я могу ошибаться!), Потому что я нашел способ заставить мой плагин C ++ «работать правильно» и отправлять все сообщения, которые я хочу:
Если я не открываю свой сокет после инициализации моего плагина, но непосредственно при попытке отправить сообщение, каждое сообщение получает мой удаленный сервер. Т.е. каждый раз, когда я вызываю sendMessage (), я делаю следующее:

try {
// Connect to the Java application
mySocket.connect(myEndpoint);
// Write the data
boost::asio::write(mySocket, boost::asio::buffer(datastring), ignored_error);
// Disconnect
mySocket.close();
} catch (const std::exception & e) {std::cout << "Couldn't initialize socket\n";}

Тем не менее, я не слишком доволен этим кодом: мне приходится отправлять около 1000 сообщений в секунду — хотя это может быть не слишком много, но я не думаю, что открытие сокета и подключение к конечной точке всегда эффективны (это операция блокировки тоже)

Любая информация, которая может привести меня в правильном направлении, будет принята с благодарностью!

Для получения дополнительной информации, вот мой код в немного более полной версии (с бесполезными вещами, сокращенными, чтобы сделать его коротким)

#include <cstdlib>
#include <fstream>
#include "PluginProcessor.h"#include "PluginEditor.h"#include "SignalMessages.pb.h"using boost::asio::local::stream_protocol;

//==============================================================================
// Default parameter values
const int defaultAveragingBufferSize = 256;
const int defaultMode = 0;
const float defaultInputSensitivity = 1.0;
const int defaultChannel = 1;
const int defaultMonoStereo = 1;        //Mono processing//==============================================================================

// Variables used by the audio algorithm
int nbBufValProcessed = 0;
float signalSum = 0;
// Used for beat detection
float signalAverageEnergy = 0;
float signalInstantEnergy = 0;
const int thresholdFactor = 5;
const int averageEnergyBufferSize = 11025;                      //0.25 seconds

//==============================================================================

// Socket used to forward data to the Processing application, and the variables associated with it
boost::asio::io_service io_service;
boost::asio::ip::tcp::socket mySocket(io_service);
boost::asio::ip::tcp::endpoint myEndpoint(boost::asio::ip::address::from_string("127.0.0.1"), 9001);
boost::system::error_code ignored_error;

//==============================================================================

SignalProcessorAudioProcessor::SignalProcessorAudioProcessor()
{
averagingBufferSize             = defaultAveragingBufferSize;
inputSensitivity                = defaultInputSensitivity;
mode                            = defaultMode;
monoStereo                      = defaultMonoStereo;
channel                         = defaultChannel;// Connect to the remote server
// Note for stack overflow : this is where I'd like connect to my server !
mySocket.connect(myEndpoint);

}

SignalProcessorAudioProcessor::~SignalProcessorAudioProcessor()
{
}//==============================================================================void SignalProcessorAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{

// In case we have more outputs than inputs, clear any output
// channels that doesn't contain input data
for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i)
buffer.clear (i, 0, buffer.getNumSamples());

//////////////////////////////////////////////////////////////////
// This is the most important part of my code, audio processing takes place here !
// Note for stack overflow : this shouldn't be very interesting, as it is not related to my current problem

for (int channel = 0; channel < std::getNumInputChannels(); ++channel)
{
const float* channelData = buffer.getReadPointer (channel);
for (int i=0; i<buffer.getNumSamples(); i++) {
signalSum += std::abs(channelData[i]);
signalAverageEnergy = ((signalAverageEnergy * (averageEnergyBufferSize-1)) + std::abs(channelData[i])) / averageEnergyBufferSize;
}

}

nbBufValProcessed += buffer.getNumSamples();
if (nbBufValProcessed >= averagingBufferSize) {

signalInstantEnergy = signalSum / (averagingBufferSize * monoStereo);

// If the instant signal energy is thresholdFactor times greater than the average energy, consider that a beat is detected
if (signalInstantEnergy > signalAverageEnergy*thresholdFactor) {
//Set the new signal Average Energy to the value of the instant energy, to avoid having bursts of false beat detections
signalAverageEnergy = signalInstantEnergy;

//Create an impulse signal - note for stack overflow : these are Google Protocol buffer messages, serialization is faster this way
Impulse impulse;
impulse.set_signalid(channel);
std::string datastringImpulse;
impulse.SerializeToString(&datastringImpulse);
sendMessage(datastringImpulse);
}

nbBufValProcessed = 0;
signalSum = 0;
}
}

//==============================================================================

void SignalProcessorAudioProcessor::sendMessage(std::string datastring) {

try {
// Write the data
boost::asio::write(mySocket, boost::asio::buffer(datastring), ignored_error);

} catch (const std::exception & e) {
std::cout << "Caught an error while trying to initialize the socket - the Java server might not be ready\n";
std::cerr << e.what();
}
}//==============================================================================

// This creates new instances of the plugin..
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
{
return new SignalProcessorAudioProcessor();
}

0

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]