Basic functionnality and configuration posssible
This commit is contained in:
commit
5e17568bbb
5 changed files with 191 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
**/.idea
|
||||
**/cmake-build*/
|
||||
scream.mp3
|
15
CMakeLists.txt
Normal file
15
CMakeLists.txt
Normal 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
29
README.md
Normal 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
144
main.cpp
Normal 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
BIN
scream.ogg
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue