From 0ab62b7493a2396f2f2eaf0e66aa07102f81a9c0 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Fri, 22 Mar 2013 20:42:56 -0600 Subject: [PATCH 1/2] Stream injector --- CMakeLists.txt | 3 +- injector/CMakeLists.txt | 17 ++++ injector/src/injector.cpp | 194 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 injector/CMakeLists.txt create mode 100644 injector/src/injector.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cd284ff3e4..5fd99276c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,4 +6,5 @@ add_subdirectory(space) add_subdirectory(domain) add_subdirectory(mixer) add_subdirectory(voxel) -add_subdirectory(interface) \ No newline at end of file +add_subdirectory(interface) +add_subdirectory(injector) diff --git a/injector/CMakeLists.txt b/injector/CMakeLists.txt new file mode 100644 index 0000000000..e85116e90f --- /dev/null +++ b/injector/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 2.8) + +project(injector) + +# grab the implemenation and header files +file(GLOB INJECTOR_SRCS src/*.cpp src/*.h) + +# add the mixer executable +add_executable(injector ${INJECTOR_SRCS}) + +# link the shared hifi library +include(../LinkHifiShared.cmake) +link_hifi_shared_library(injector) + +# link the threads library +find_package(Threads REQUIRED) +target_link_libraries(injector ${CMAKE_THREAD_LIBS_INIT}) diff --git a/injector/src/injector.cpp b/injector/src/injector.cpp new file mode 100644 index 0000000000..3824949182 --- /dev/null +++ b/injector/src/injector.cpp @@ -0,0 +1,194 @@ +// +// main.cpp +// AudioInjector2 +// +// Created by Leonardo Murillo on 3/5/13. +// Copyright (c) 2013 Leonardo Murillo. All rights reserved. +// + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "UDPSocket.h" +#include "UDPSocket.cpp" +#include + +char EC2_WEST_AUDIO_SERVER[] = "54.241.92.53"; +const int AUDIO_UDP_LISTEN_PORT = 55443; +const int BUFFER_LENGTH_BYTES = 512; +const int BUFFER_LENGTH_SAMPLES = BUFFER_LENGTH_BYTES / sizeof(int16_t); +const float SAMPLE_RATE = 22050.0; +const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES / SAMPLE_RATE) * 1000000; + +// Command line parameter defaults +bool loopAudio = true; +float sleepIntervalMin = 1.00; +float sleepIntervalMax = 2.00; +float positionInUniverse[] = {0, 0, 0, 0}; +char attenuationModifier[] = {0}; +char *sourceAudioFile; +const char *allowedParameters = ":rb::t::c::a::f:"; + +char *charBuffer; +int16_t *buffer; +long length; + +UDPSocket *streamSocket; + +void printBinaryValue(char element) { + std::bitset<8> x(element); + std::cout << "Printing binary value: " << x << std::endl; +} + +float randomFloat(float a, float b) { + float random = ((float) rand()) / (float) RAND_MAX; + float diff = b - a; + float r = random * diff; + return a + r; +} + +void usage(void) +{ + std::cout << "High Fidelity - Interface audio injector" << std::endl; + std::cout << " -r Random sleep mode. If not specified will default to constant loop." << std::endl; + std::cout << " -b FLOAT Min. number of seconds to sleep. Only valid in random sleep mode. Default 1.0" << std::endl; + std::cout << " -t FLOAT Max. number of seconds to sleep. Only valid in random sleep mode. Default 2.0" << std::endl; + std::cout << " -c FLOAT,FLOAT,FLOAT,FLOAT X,Y,Z,YAW position in universe where audio will be originating from and direction. Defaults to 0,0,0,0" << std::endl; + std::cout << " -a 0-255 Attenuation curve modifier, defaults to 0" << std::endl; + std::cout << " -f FILENAME Name of audio source file. Required - RAW format, 22050hz 16bit signed mono" << std::endl; +}; + +bool processParameters(int parameterCount, char* parameterData[]) +{ + int p; + while ((p = getopt(parameterCount, parameterData, allowedParameters)) != -1) { + switch (p) { + case 'r': + loopAudio = false; + std::cout << "[DEBUG] Random sleep mode enabled" << std::endl; + break; + case 'b': + sleepIntervalMin = atof(optarg); + std::cout << "[DEBUG] Min delay between plays " << sleepIntervalMin << "sec" << std::endl; + break; + case 't': + sleepIntervalMax = atof(optarg); + std::cout << "[DEBUG] Max delay between plays " << sleepIntervalMax << "sec" << std::endl; + break; + case 'f': + sourceAudioFile = optarg; + std::cout << "[DEBUG] Opening file: " << sourceAudioFile << std::endl; + break; + case 'c': + { + std::istringstream ss(optarg); + std::string token; + + int i = 0; + while (std::getline(ss, token, ',')) { + positionInUniverse[i] = atof(token.c_str()); + ++i; + if (i == 4) { + break; + } + } + + break; + } + case 'a': + attenuationModifier[0] = atoi(optarg); + std::cout << "[DEBUG] Attenuation modifier: " << optarg << std::endl; + break; + default: + usage(); + return false; + } + } + return true; +}; + +void loadFile(void) { + std::fstream sourceFile; + sourceFile.open(sourceAudioFile, std::ios::in | std::ios::binary); + sourceFile.seekg(0, std::ios::end); + length = sourceFile.tellg(); + sourceFile.seekg(0, std::ios::beg); + long sizeOfShortArray = length / 2; + buffer = new int16_t[sizeOfShortArray]; + sourceFile.read((char *)buffer, length); +} + +void stream(void) +{ + timeval startTime; + + int leadingBytes = 1 + (sizeof(float) * 4); + unsigned char dataPacket[BUFFER_LENGTH_BYTES + leadingBytes]; + + dataPacket[0] = 'I'; + unsigned char *currentPacketPtr = dataPacket + 1; + + for (int p = 0; p < 4; p++) { + memcpy(currentPacketPtr, &positionInUniverse[p], sizeof(float)); + currentPacketPtr += sizeof(float); + } + + memcpy(currentPacketPtr, &attenuationModifier[0], sizeof(char)); + currentPacketPtr += sizeof(char); + + for (int i = 0; i < length; i += BUFFER_LENGTH_SAMPLES) { + gettimeofday(&startTime, NULL); + memcpy(currentPacketPtr, &buffer[i], BUFFER_LENGTH_BYTES); + streamSocket->send(EC2_WEST_AUDIO_SERVER, AUDIO_UDP_LISTEN_PORT, dataPacket, sizeof(dataPacket)); + double usecToSleep = usecTimestamp(&startTime) + BUFFER_SEND_INTERVAL_USECS - usecTimestampNow(); + usleep(usecToSleep); + } +}; + +int main(int argc, char* argv[]) +{ + + srand(time(0)); + int AUDIO_UDP_SEND_PORT = 1500 + (rand() % (int)(1500 - 2000 + 1)); + + UDPSocket *streamSocket = new UDPSocket(AUDIO_UDP_SEND_PORT); + + if (processParameters(argc, argv)) { + if (sourceAudioFile) { + loadFile(); + } else { + std::cout << "[FATAL] Source audio file not specified" << std::endl; + exit(-1); + } + + for (int i = 0; i < sizeof(positionInUniverse)/sizeof(positionInUniverse[0]); ++i) { + std::cout << "Position " << positionInUniverse[i] << std::endl; + } + + float delay; + int usecDelay; + while (1) { + stream(); + + if (loopAudio) { + delay = 0; + } else { + delay = randomFloat(sleepIntervalMin, sleepIntervalMax); + } + usecDelay = delay * 1000 * 1000; + usleep(usecDelay); + } + } + return 0; +} + + From 0917cafd4e5e9a9cd8dd9a75d2e37659c987c559 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 25 Mar 2013 16:25:25 -0600 Subject: [PATCH 2/2] Using shared utils and changing modifier data type --- injector/CMakeLists.txt | 2 +- injector/src/injector.cpp | 31 +++++++++---------------------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/injector/CMakeLists.txt b/injector/CMakeLists.txt index e85116e90f..ffb352124b 100644 --- a/injector/CMakeLists.txt +++ b/injector/CMakeLists.txt @@ -5,7 +5,7 @@ project(injector) # grab the implemenation and header files file(GLOB INJECTOR_SRCS src/*.cpp src/*.h) -# add the mixer executable +# add the executable add_executable(injector ${INJECTOR_SRCS}) # link the shared hifi library diff --git a/injector/src/injector.cpp b/injector/src/injector.cpp index 3824949182..e33398370e 100644 --- a/injector/src/injector.cpp +++ b/injector/src/injector.cpp @@ -1,6 +1,6 @@ // -// main.cpp -// AudioInjector2 +// injector.cpp +// Audio Injector // // Created by Leonardo Murillo on 3/5/13. // Copyright (c) 2013 Leonardo Murillo. All rights reserved. @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -34,7 +33,7 @@ bool loopAudio = true; float sleepIntervalMin = 1.00; float sleepIntervalMax = 2.00; float positionInUniverse[] = {0, 0, 0, 0}; -char attenuationModifier[] = {0}; +unsigned char attenuationModifier = 255; char *sourceAudioFile; const char *allowedParameters = ":rb::t::c::a::f:"; @@ -44,18 +43,6 @@ long length; UDPSocket *streamSocket; -void printBinaryValue(char element) { - std::bitset<8> x(element); - std::cout << "Printing binary value: " << x << std::endl; -} - -float randomFloat(float a, float b) { - float random = ((float) rand()) / (float) RAND_MAX; - float diff = b - a; - float r = random * diff; - return a + r; -} - void usage(void) { std::cout << "High Fidelity - Interface audio injector" << std::endl; @@ -63,7 +50,7 @@ void usage(void) std::cout << " -b FLOAT Min. number of seconds to sleep. Only valid in random sleep mode. Default 1.0" << std::endl; std::cout << " -t FLOAT Max. number of seconds to sleep. Only valid in random sleep mode. Default 2.0" << std::endl; std::cout << " -c FLOAT,FLOAT,FLOAT,FLOAT X,Y,Z,YAW position in universe where audio will be originating from and direction. Defaults to 0,0,0,0" << std::endl; - std::cout << " -a 0-255 Attenuation curve modifier, defaults to 0" << std::endl; + std::cout << " -a 0-255 Attenuation curve modifier, defaults to 255" << std::endl; std::cout << " -f FILENAME Name of audio source file. Required - RAW format, 22050hz 16bit signed mono" << std::endl; }; @@ -105,7 +92,7 @@ bool processParameters(int parameterCount, char* parameterData[]) break; } case 'a': - attenuationModifier[0] = atoi(optarg); + attenuationModifier = atoi(optarg); std::cout << "[DEBUG] Attenuation modifier: " << optarg << std::endl; break; default: @@ -142,8 +129,8 @@ void stream(void) currentPacketPtr += sizeof(float); } - memcpy(currentPacketPtr, &attenuationModifier[0], sizeof(char)); - currentPacketPtr += sizeof(char); + *currentPacketPtr = attenuationModifier; + currentPacketPtr++; for (int i = 0; i < length; i += BUFFER_LENGTH_SAMPLES) { gettimeofday(&startTime, NULL); @@ -176,13 +163,13 @@ int main(int argc, char* argv[]) float delay; int usecDelay; - while (1) { + while (true) { stream(); if (loopAudio) { delay = 0; } else { - delay = randomFloat(sleepIntervalMin, sleepIntervalMax); + delay = randFloatInRange(sleepIntervalMin, sleepIntervalMax); } usecDelay = delay * 1000 * 1000; usleep(usecDelay);