From b47103776333dc8cbd7f5653ba0693248a9aaf9f Mon Sep 17 00:00:00 2001 From: Clortox <45907232+Clortox@users.noreply.github.com> Date: Fri, 8 Nov 2019 12:54:18 -0500 Subject: [PATCH] Add files via upload --- wave.hpp | 322 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 wave.hpp diff --git a/wave.hpp b/wave.hpp new file mode 100644 index 0000000..7e370a5 --- /dev/null +++ b/wave.hpp @@ -0,0 +1,322 @@ +////////////////////////////////////////////////////////////////////////// +//wave.hpp +//load a .wav file into memeory and play at will +//MUST ADD winmm TO YOUR LINKER SETTINGS ELSE THIS WILL NOT WORK +// +//Free to use, modify, publish, etc. +//if you're feeling nice, mention me :D +// +////////////////////////////////////////////////////////// +//Date: 11-5-19 // +//Author: Tyler Perkins // +//Pseudonym: Clortox // +//modified from the code provided by: // +//Chervil on the c++ fourms // +//Use with care :) // +////////////////////////////////////////////////////////// +//Interface: // +//wave::Wave(std::string) provide file path to a // +// .wav file, else will be // +// empty // +//------------------------------------------------------// +//wave::isOk() returns weather the wav // +// is ready to be played, // +// like ifstream::good() // +//------------------------------------------------------// +//wave::play(bool) plays wave file, will not// +// if !isOk().bool is async // +// async=true,pause and play// +// async=false,open new // +// thread to play on // +//------------------------------------------------------// +//wave::resign(std::string) load new wav file into // +// memory // +//------------------------------------------------------// +//wave::dumpbuffer() returns a string with // +// the file buffer in it // +// really only for debug // +//------------------------------------------------------// +//wave::isWave(std::string) returns true if is wave // +// file, checks magic bytes // +////////////////////////////////////////////////////////// +#ifndef _WAVE_HPP_ +#define _WAVE_HPP_ + +#include +#include +#include +#include +#include + +class wave{ +public: + wave (); //def ctor + wave (std::string&); //ctor with path + + //rule of three + wave (const wave&); //copy ctor + ~wave (); //dtor + wave& operator= (wave&); //assignment operator + + void swap (wave&); //swap + + bool isOk () const; //check if ready to run + void play (bool); //play loaded file + void resign (std::string&); //load new file into memory + + ////DEBUG//// + std::string dumpbuffer() const; //send back the buffer in a string + +private: + bool isWave(std::string&) const; //check if file is a wave file via magic bytes + + char *buffer; + HINSTANCE HInstance; + bool isok; + int buffsize; +}; + +///////////////////////////////////////////////// +//defualt ctor (WORKS) +//will set everything to blank so it is ready to role +wave::wave(){ + isok = false; + buffer = 0; + buffsize = 0; +} + +///////////////////////////////////////////////// +//preffered ctor the user use (WORKS) +//will just load file into memory, throw error if not working +wave::wave(std::string &path){ + isok = false; + try{ + if(path == ""){ + throw 15; + } + std::ifstream infile(path.c_str()); + if(!infile.good()){ + throw 10; + } + if(!isWave(path)){ + throw 20; + } + } + catch(int e){ + if(e == 10){ + std::cerr << "wave::wave(std::string&); file either was moved or does not exist\nEXITING\n"; + return; + } + if(e == 15){ + std::cerr << "wave::wave(std::string&); file either was moved or does not exist\nEXITING\n"; + return; + } + if(e == 20){ + std::cerr << "wave::wave(std::string&); file is not a .wav file\nEXITING\n"; + return; + } + } + buffer = 0; + HInstance = GetModuleHandle(0); + std::ifstream infile(path,std::ios::binary); + + infile.seekg(0,std::ios::end); + buffsize = infile.tellg(); + buffer = new char[buffsize]; + infile.seekg(0,std::ios::beg); + infile.read(buffer,buffsize); + + infile.close(); + isok = true; +} + +///////////////////////////////////////////////// +//copy ctor (WORKS) +//just moves copies the buffer over +wave::wave(const wave &rhs){ + isok = false; + HInstance = rhs.HInstance; + buffsize = rhs.buffsize; + buffer = new char[buffsize]; //the point of this is so that if the other wave goes out of scope, + //this one is still useable + for(int i=0;i<=buffsize-1;i++){ //copy data over + buffer[i] = rhs.buffer[i]; + } + isok = rhs.isOk(); +} + +///////////////////////////////////////////////// +//dtor (WORKS) +//just dealloc the buffer +wave::~wave(){ + PlaySound(NULL,0,0); //stop the sound + delete[] buffer; +} + +///////////////////////////////////////////////// +//assignment operator (WORKS) +// +wave& wave::operator=(wave &rhs){ + swap(rhs); + return *this; +} + +///////////////////////////////////////////////// +//swap func (WORKS) +//swaps all the private elements +void wave::swap(wave &rhs){ + char* temp = rhs.buffer; + rhs.buffer = buffer; + buffer = temp; + + int tempbuf = rhs.buffsize; + rhs.buffsize = buffsize; + buffsize = tempbuf; + + bool tempok = rhs.isok; + rhs.isok = isok; + isok = tempok; + + HINSTANCE tempinst = rhs.HInstance; + rhs.HInstance = HInstance; + HInstance = tempinst; + return; +} + +///////////////////////////////////////////////// +//returns isok (WORKS) +//useful for checking if the file is working +bool wave::isOk() const{ + return isok; +} + +///////////////////////////////////////////////// +//the star of the show (WORKS) +//play the file using winapi +void wave::play(bool async){ + try{ + if(!isOk()){ + throw 12; + } + } + catch(int e){ + if(e == 12){ + std::cerr << "wave::play(bool); cannot play file\nEXITING\n"; + return; + } + } + if(async){ + PlaySound(buffer, HInstance, SND_MEMORY | SND_ASYNC); + }else{ + PlaySound(buffer, HInstance, SND_MEMORY); + } + return; +} + +///////////////////////////////////////////////// +//almost the std::string ctor but not quite +//just load a new path into memory +void wave::resign(std::string &path){ + isok = false; + try{ + std::ifstream infile(path.c_str()); + if(!infile.good()){ + throw 10; + } + if(!isWave(path)){ + throw 19; + } + } + catch(int e){ + if(e == 10){ + std::cerr << "wave::resign(std::string&); file either was moved or does not exist\nEXITING\n"; + return; + } + if(e == 19){ + std::cerr << "wave::resign(std::string&); file is not a .wav file\nEXITING\n"; + return; + } + } + delete[] buffer; + buffer = 0; + buffsize = 0; + HInstance = GetModuleHandle(0); + std::ifstream infile(path,std::ios::binary); + + infile.seekg(0,std::ios::end); + buffsize = infile.tellg(); + buffer = new char[buffsize]; + infile.seekg(0,std::ios::beg); + infile.read(buffer,buffsize); + + infile.close(); + isok = true; + return; +} + +///////////////////////////////////////////////// +//send back a string with everything in it +//expect a lot of garbage +std::string wave::dumpbuffer() const{ + std::string resultant; + for(int i=0;i<=buffsize-1;i++){ + resultant += buffer[i]; + } + return resultant; +} + +///////////////////////////////////////////////// +//check if the file is a wav file +//below is the definition of the magic bytes +bool wave::isWave(std::string &path) const{ + try{ + if(path == ""){ + throw 18; + } + std::ifstream infile(path.c_str()); + if(!infile.good()){ + throw 16; + } + } + catch(int e){ + if(e == 16){ + std::cerr << "wave::isWave(std::string&); file either was moved or does not exist\nEXITING\n"; + return false; + } + if(e == 18){ + std::cerr << "wave::isWave(std::string&); path is empty!\nEXITING\n"; + return false; + } + } + + std::ifstream infile(path.c_str(),std::ios_base::binary); + char ch; + std::string temp = ""; + std::cout << "wav head: " << std::endl; + for(int i=0;i<=11;i++){ + infile.get(ch); + temp += ch; + } + + try{ + std::string first = "RIFF"; //i know these are magic numbers, + std::string last = "WAVE"; //but these are standards, theyre not changing + //or i hope so + if(!(temp.substr(0,4) == first)){ + throw 17; + } + if(!(temp.substr(8,4) == last)){ + throw 17; + } + } + catch(int e){ + if(e == 17){ + std::cout << "wave::isWave(std::string&); file is not formatted as a .wav\nEXITING\n"; + return false; + } + } + return true; + +} + +#endif // _WAVE_HPP_