ScreamingHot/main.cpp

145 lines
4.3 KiB
C++
Raw Normal View History

#include <iostream>
#include <fstream>
#include <thread>
#include <chrono>
#include <SFML/Audio.hpp>
#include <SFML/Window.hpp>
// Program constants
int minRange = 35000;
int maxRange = 50000;
int sampleCount = 20;
std::string tempPath = "/sys/class/thermal/thermal_zone2/temp";
void printUsage()
{
std::cout << "Make your computer scream when it gets hot !" << std::endl;
std::cout << "Usage :" << std::endl;
std::cout << "\tNo arguments : defaults to " << minRange/1000 << "-" << maxRange/1000 << "°C, "
<< sampleCount << " samples and temperature is read from " << "\n\t\t" << tempPath << std::endl;
std::cout << "\t2 arguments : minTemp maxTemp" << std::endl;
std::cout << "\t3 arguments : minTemp maxTemp sampleCount" << std::endl;
std::cout << "\t4 arguments : minTemp maxTemp sampleCount temperatureFile" << std::endl << std::endl;
std::cout << "Temperatures are in integer °C, sampleCount is integer > 0, "
"temperatureFile is the full path to the file to read" << std::endl << std::endl;
}
int main(int argc, char** argv)
{
switch (argc)
{
case 5:
tempPath = argv[4];
case 4:
try {
sampleCount = std::stoi(argv[3]);
} catch (std::exception&) {
std::cerr << "Could not convert sample count from input." << std::endl << std::endl;
printUsage();
return -1;
}
case 3:
try {
minRange = std::stoi(argv[1])*1000;
maxRange = std::stoi(argv[2])*1000;
} catch (std::exception&) {
std::cerr << "Could not convert temperatures from input." << std::endl << std::endl;
printUsage();
return -1;
}
case 1:
break;
default:
std::cerr << "Invalid argument count" << std::endl << std::endl;
printUsage();
return -1;
}
sf::SoundBuffer buffer;
if (!buffer.loadFromFile("scream.ogg"))
{
std::cerr << "Failed to open scream.ogg" << std::endl;
return -1;
}
std::ifstream tempFile(tempPath,std::ios_base::in);
if (!tempFile.is_open())
{
std::cerr << "Failed to open temperature data file at " << tempPath << std::endl;
return -1;
}
// Set up the scream
sf::Sound playingSound;
playingSound.setBuffer(buffer);
playingSound.setLoop(true);
// Set up variables
bool looping = true;
// Initialize array to min range
int tempSamples[sampleCount];
for (int& tempSample : tempSamples)
{
tempSample = minRange;
}
int currentSample = 0;
int currentTemp;
std::cout << "Starting ear damage..." << std::endl;
playingSound.play();
while (looping)
{
// Apparently unnecessary
// tempFile.sync();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// Rewind to read the new value
tempFile.seekg(std::istream::beg);
tempFile >> tempSamples[currentSample];
// Advance the index and rollover at the end of the array
currentSample = currentSample < sampleCount - 1 ? currentSample + 1 : 0;
// Compute a rolling average
currentTemp = 0;
for (int tempSample : tempSamples)
{
currentTemp += tempSample/(float)sampleCount;
}
// Relative position of the temperature between min and max
float heatStrength = (currentTemp - minRange)/(float)(maxRange - minRange);
// Stop the sound if low enough, restart if inside the range
if (heatStrength <= 0)
{
playingSound.stop();
playingSound.setPitch(1);
std::cout << "Too cold, pausing ear damage." << std::endl;
continue;
} else if (playingSound.getStatus() == sf::Sound::Stopped) {
playingSound.play();
std::cout << "Getting hot, resuming ear damage." << std::endl;
}
playingSound.setPitch(1+0.5f*heatStrength);
playingSound.setVolume(20+80*heatStrength);
std::cout << "Temp is " << currentTemp/1000.0 << "°C at pitch " << 1+0.5*heatStrength << " and volume " << 20+80*heatStrength << std::endl;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) looping = false;
}
std::cout << "Ear damage stopped." << std::endl;
tempFile.close();
return 0;
}