Basic functionnality and configuration posssible

This commit is contained in:
Teo-CD 2021-04-17 19:09:06 +01:00
commit 5e17568bbb
5 changed files with 191 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
**/.idea
**/cmake-build*/
scream.mp3

15
CMakeLists.txt Normal file
View file

@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.17)
project(ScreamingHot)
set(CMAKE_CXX_STANDARD 17)
find_package(SFML COMPONENTS window audio REQUIRED)
if(NOT SFML_FOUND)
message(FATAL_ERROR "SFML could not be found")
endif()
add_executable(ScreamingHot main.cpp)
target_link_libraries(ScreamingHot
sfml-window
sfml-audio)

29
README.md Normal file
View file

@ -0,0 +1,29 @@
# Screaming Hot
Make your computer scream when it gets hot !
# Limitations
This only handles temperature reading for Linux, as it is exposed by a simple file. Not tested on MacOS.
# Usage
Running the program without arguments will use default values set in code.
The two first arguments set the minimum and maximum temperature of the range, the third sets the number of samples for
averaging it temperature readings and the fourth the file where temperature should be read from.
Any other number of arguments or a number that cannot be parsed will print out the usage details.
Pressing `Escape` will quit the application.
# Building
## Dependencies
- SFML
- Audio
- Window
- System
## Sources
`scream.ogg` is a short extract from Rick and Morty, © Adult Swim.

144
main.cpp Normal file
View file

@ -0,0 +1,144 @@
#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;
}

BIN
scream.ogg Normal file

Binary file not shown.