//############################################################################ // // LaserBoy !!! // // by James Lehman // Extra Stimulus Inc. // james@akrobiz.com // // began: October 2003 // // Copyright 2003 to 2024 James Lehman. // This source is distributed under the terms of the GNU General Public License. // // LaserBoy_wav.hpp is part of LaserBoy. // // LaserBoy is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // LaserBoy is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with LaserBoy. If not, see . // //############################################################################ #ifndef __LASERBOY_WAVE_DEFINITIONS__ #define __LASERBOY_WAVE_DEFINITIONS__ //############################################################################ #include "LaserBoy_common.hpp" //############################################################################ class LaserBoy_wav_optimization_parameters { public: LaserBoy_wav_optimization_parameters() : lit_dwell_overhang (-1), // -1 indicates undefined lit_delta_max (-1), blank_delta_max (-1), max_dwell_microsec (-1), max_wag_microsec (-1), insignificant_distance (-1), insignificant_angle (-1), frames_per_second (-1) {} //------------------------------------------------------------------------ LaserBoy_wav_optimization_parameters(const LaserBoy_wav_optimization_parameters& parms) : lit_dwell_overhang (parms.lit_dwell_overhang ), lit_delta_max (parms.lit_delta_max ), blank_delta_max (parms.blank_delta_max ), max_dwell_microsec (parms.max_dwell_microsec ), max_wag_microsec (parms.max_wag_microsec ), insignificant_distance (parms.insignificant_distance), insignificant_angle (parms.insignificant_angle ), frames_per_second (parms.frames_per_second ) {} //------------------------------------------------------------------------ ~LaserBoy_wav_optimization_parameters() {} //------------------------------------------------------------------------ int lit_dwell_overhang; float lit_delta_max, blank_delta_max, max_dwell_microsec, max_wag_microsec, insignificant_distance, insignificant_angle, frames_per_second; }; //############################################################################ class LaserBoy_wav_header { public: LaserBoy_wav_header() : num_channels ( 0), bits_per_sample (16), sample_rate ( 0), num_samples ( 0), num_frames ( 0), header_size ( 0), LaserBoy_wav_mode (LASERBOY_WAVE_NO_MODE), version ("!LaserBoy!"), file_name ( ), channel_map ( ), parms ( ) { u_int i; for(i = 0; i < 8; i++) { offset [i] = 0; signal_id [i] = LASERBOY_SIGNAL_UNDEFINED; LSB_tag [i] = LASERBOY_LSB_NOT_USED; resolution [i] = 16; } for(i = 0; i < 256; i++) { color_rescale_r[i] = color_rescale_g[i] = color_rescale_b[i] = color_rescale_i[i] = i; } } //------------------------------------------------------------------------ LaserBoy_wav_header(const LaserBoy_wav_header& header); //------------------------------------------------------------------------ ~LaserBoy_wav_header() {} //------------------------------------------------------------------------ u_int lboy_chunk_size () const; //------------------------------------------------------------------------ bool from_fstream_wav (std::fstream& in, const string& file); void to_fstream_wav (std::fstream& out); //------------------------------------------------------------------------ void tell (string label = "") const; //------------------------------------------------------------------------ // data //------------------------------------------------------------------------ u_short num_channels , bits_per_sample; u_int sample_rate, num_samples, num_frames , header_size, LaserBoy_wav_mode; // up to 32 bit flags; u_short color_rescale_r [256], color_rescale_g [256], color_rescale_b [256], color_rescale_i [256], LSB_tag [ 8]; int offset [ 8]; short signal_id [ 8]; u_char resolution [ 8]; string version, file_name, channel_map; LaserBoy_wav_optimization_parameters parms; }; //############################################################################ class LaserBoy_wav_sample { public: LaserBoy_wav_sample(u_int n) : channel (new short[n]), num_channels (n ) { memset((void*)channel, 0x00, num_channels * sizeof(short)); } //------------------------------------------------------------------------ LaserBoy_wav_sample(const LaserBoy_wav_sample& sample) : channel (new short[sample.num_channels]), num_channels (sample.num_channels) { memcpy((void*)channel, (void*)sample.channel, num_channels * sizeof(short)); } //------------------------------------------------------------------------ ~LaserBoy_wav_sample() { delete channel; } //------------------------------------------------------------------------ bool from_fstream_wav(std::fstream& in) { if(in.good()) { in.read((char*)channel, num_channels * sizeof(signed short)); return true; } return false; // returns false if EOF } //------------------------------------------------------------------------ bool from_fstream_wav_inverted(std::fstream& in) { if(in.good()) { in.read((char*)channel, num_channels * sizeof(signed short)); negate(); return true; } return false; // returns false if EOF } //------------------------------------------------------------------------ bool from_fstream_wav_polarity(std::fstream& in, int polarity[8]) { if(in.good()) { in.read((char*)channel, num_channels * sizeof(signed short)); for(u_int i = 0; i < num_channels; i++) if(polarity[i] == 1) // invert { if(channel[i] >= LASERBOY_MIN_SHORT) channel[i] = -channel[i]; else channel[i] = LASERBOY_MAX_SHORT; // there is no +32768! } return true; } return false; // returns false if EOF } //------------------------------------------------------------------------ bool from_fstream_wav_bit_resolution(std::fstream& in, u_int bit_mask[8]) { if(in.good()) { in.read((char*)channel, num_channels * sizeof(signed short)); for(u_int i = 0; i < num_channels; i++) channel[i] &= bit_mask[i]; return true; } return false; // returns false if EOF } //------------------------------------------------------------------------ void to_fstream_wav(std::fstream& out, LaserBoy_wav_header& header) { out.write((char*)channel, num_channels * sizeof(signed short)); header.num_samples++; return; } //------------------------------------------------------------------------ void to_fstream_wav_inverted(std::fstream& out, LaserBoy_wav_header& header) { negate(); out.write((char*)channel, num_channels * sizeof(signed short)); negate(); header.num_samples++; return; } //------------------------------------------------------------------------ LaserBoy_wav_sample& operator = (const LaserBoy_wav_sample& sample) { delete channel; num_channels = sample.num_channels; channel = new short[num_channels]; memcpy((void*)channel, (void*)sample.channel, num_channels * sizeof(short)); return *this; } //------------------------------------------------------------------------ void negate() { for(u_int i = 0; i < num_channels; i++) { if(channel[i] >= LASERBOY_MIN_SHORT) channel[i] = -channel[i]; else channel[i] = LASERBOY_MAX_SHORT; // there is no +32768! } return; } //------------------------------------------------------------------------ LaserBoy_wav_sample operator + (const LaserBoy_wav_sample& s) // side-by-side as tracks { LaserBoy_wav_sample sum(num_channels + s.num_channels); memcpy( (void*)sum.channel, (void*)channel, num_channels * sizeof(short) ); memcpy( (void*)(sum.channel + num_channels), // pointer math! (void*)s.channel, s.num_channels * sizeof(short) ); return sum; } //------------------------------------------------------------------------ signed short *channel ; u_int num_channels; }; //############################################################################ typedef LaserBoy_wav_sample* LaserBoy_wav_sample_pointer; //############################################################################ #endif //############################################################################ ////////////////////////////////////////////////////////////////////////////// //############################################################################