//############################################################################ // // LaserBoy !!! // // by James Lehman // Extra Stimulus Inc. // james@akrobiz.com // // began: October 2003 // // Copyright 2003 to 2025 James Lehman. // This source is distributed under the terms of the GNU General Public License. // // LaserBoy_wav.cpp 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 . // //############################################################################ #include "LaserBoy_wav.hpp" //############################################################################ LaserBoy_wav_header::LaserBoy_wav_header(const LaserBoy_wav_header& header) : num_channels (header.num_channels ), bits_per_sample (header.bits_per_sample ), sample_rate (header.sample_rate ), num_samples (header.num_samples ), num_frames (header.num_frames ), header_size (header.header_size ), LaserBoy_wav_mode (header.LaserBoy_wav_mode), version (header.version ), file_name (header.file_name ), channel_map (header.channel_map ), parms (header.parms ) { memcpy((void*)offset , (void*)header.offset , sizeof(int) * header.num_channels); memcpy((void*)resolution , (void*)header.resolution , sizeof(u_char) * header.num_channels); memcpy((void*)signal_id , (void*)header.signal_id , sizeof(short) * header.num_channels); memcpy((void*)LSB_tag , (void*)header.LSB_tag , sizeof(short) * header.num_channels); memcpy((void*)color_rescale_r, (void*)header.color_rescale_r, sizeof(short) * 256); memcpy((void*)color_rescale_g, (void*)header.color_rescale_g, sizeof(short) * 256); memcpy((void*)color_rescale_b, (void*)header.color_rescale_b, sizeof(short) * 256); memcpy((void*)color_rescale_i, (void*)header.color_rescale_i, sizeof(short) * 256); } //############################################################################ u_int LaserBoy_wav_header::lboy_chunk_size() const { u_int LB_header_bytes = 20; if(LaserBoy_wav_mode & LASERBOY_WAVE_OFFSETS) LB_header_bytes += (4 * num_channels); if(LaserBoy_wav_mode & LASERBOY_WAVE_OPTIMIZED) LB_header_bytes += 32; if(LaserBoy_wav_mode & LASERBOY_WAVE_SIGNAL_MATRIX) LB_header_bytes += (4 * num_channels); if(LaserBoy_wav_mode & LASERBOY_SIGNAL_BIT_RESOLUTION) LB_header_bytes += (2 * num_channels); if(LaserBoy_wav_mode & LASERBOY_WAVE_NUM_FRAMES) LB_header_bytes += 4; if(LaserBoy_wav_mode & LASERBOY_COLOR_RESCALE_R) LB_header_bytes += 512; if(LaserBoy_wav_mode & LASERBOY_COLOR_RESCALE_G) LB_header_bytes += 512; if(LaserBoy_wav_mode & LASERBOY_COLOR_RESCALE_B) LB_header_bytes += 512; if(LaserBoy_wav_mode & LASERBOY_COLOR_RESCALE_I) LB_header_bytes += 512; return LB_header_bytes; } //############################################################################ bool LaserBoy_wav_header::from_fstream_wav(std::fstream& in, const string& file) { char a, b, c, d; short audio_format, block_align; u_int i, chunk_size = 0, sub_chunk_1_size = 0, sub_chunk_2_size = 0, sub_chunk_3_size = 0, LaserBoy_chunk_size = 0, byte_rate; string temp_string, version_guess; //------------------------------------------------------------------------ file_name = file; version = "!LaserBoy!"; // assume the worst! version_guess = "!LaserBoy!"; LaserBoy_wav_mode = LASERBOY_WAVE_POSITIVE; //------------------------------------------------------------------------ in.get(a); if(a != 'R') return false; in.get(a); if(a != 'I') return false; in.get(a); if(a != 'F') return false; in.get(a); if(a != 'F') return false; //------------------------------------------------------------------------ in.get(a); in.get(b); in.get(c); in.get(d); chunk_size = ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); //------------------------------------------------------------------------ in.get(a); if(a != 'W') return false; in.get(a); if(a != 'A') return false; in.get(a); if(a != 'V') return false; in.get(a); if(a != 'E') return false; //------------------------------------------------------------------------ in.get(a); if(a == 'f') { in.get(a); if(a != 'm') return false; in.get(a); if(a != 't') return false; in.get(a); if(a != ' ') return false; } else if(a == 'L') { in.get(a); if(a != 'I') return false; in.get(a); if(a != 'S') return false; in.get(a); if(a != 'T') return false; in.get(a); in.get(b); in.get(c); in.get(d); sub_chunk_3_size = ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.seekg(sub_chunk_3_size, ios::cur); // jump over the whole LIST chunk! in.get(a); if(a != 'f') return false; in.get(a); if(a != 'm') return false; in.get(a); if(a != 't') return false; in.get(a); if(a != ' ') return false; } else return false; //------------------------------------------------------------------------ in.get(a); in.get(b); in.get(c); in.get(d); sub_chunk_1_size = ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); //------------------------------------------------------------------------ in.get(a); in.get(b); audio_format = ((b & 0x00ff) << 8 | (a & 0x00ff)); if(audio_format != 1) return false; //------------------------------------------------------------------------ in.get(a); in.get(b); num_channels = ((b & 0x00ff) << 8 | (a & 0x00ff)); if(num_channels < 2) return false; //------------------------------------------------------------------------ in.get(a); in.get(b); in.get(c); in.get(d); sample_rate = ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); //------------------------------------------------------------------------ in.get(a); in.get(b); in.get(c); in.get(d); byte_rate = ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); //------------------------------------------------------------------------ in.get(a); in.get(b); block_align = ((b & 0x00ff) << 8 | (a & 0x00ff)); //------------------------------------------------------------------------ in.get(a); in.get(b); bits_per_sample = ((b & 0x00ff) << 8 | (a & 0x00ff)); if(bits_per_sample != 16) return false; //------------------------------------------------------------------------ if(byte_rate != (sample_rate * num_channels * (bits_per_sample / 8))) return false; //------------------------------------------------------------------------ if(block_align != (num_channels * (bits_per_sample / 8))) return false; //------------------------------------------------------------------------ // look for LaserBoy //------------------------------------------------------------------------ in.get(a); temp_string.push_back(a); in.get(a); temp_string.push_back(a); in.get(a); temp_string.push_back(a); in.get(a); temp_string.push_back(a); //------------------------------------------------------------------------ if(temp_string == "LBoy") { //-------------------------------------------------------------------- in.get(a); in.get(b); in.get(c); in.get(d); LaserBoy_chunk_size = ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); //-------------------------------------------------------------------- temp_string.clear(); in.get(a); temp_string.push_back(a); // L in.get(a); temp_string.push_back(a); // a in.get(a); temp_string.push_back(a); // s in.get(a); temp_string.push_back(a); // e in.get(a); temp_string.push_back(a); // r in.get(a); temp_string.push_back(a); // B in.get(a); temp_string.push_back(a); // o in.get(a); temp_string.push_back(a); // y } else if(temp_string == "Lase") { in.get(a); temp_string.push_back(a); // r in.get(a); temp_string.push_back(a); // B in.get(a); temp_string.push_back(a); // o in.get(a); temp_string.push_back(a); // y } else in.seekg(-4, ios::cur); // Oops! put it back! //------------------------------------------------------------------------ if(temp_string == "LaserBoy") { in.get(a); temp_string.push_back(a); in.get(a); temp_string.push_back(a); in.get(a); temp_string.push_back(a); in.get(a); temp_string.push_back(a); in.get(a); temp_string.push_back(a); in.get(a); temp_string.push_back(a); in.get(a); temp_string.push_back(a); in.get(a); temp_string.push_back(a); //---------------------------------------------------------------- if( temp_string != "LaserBoy06072008" && temp_string != "LaserBoy07132008" && temp_string != "LaserBoy10102008" && temp_string != "LaserBoy11112008" && temp_string != "LaserBoy12082009" && temp_string != "LaserBoy06282010" // 13.5 years ago! && temp_string != LASERBOY_WAVE_VERSION // "LaserBoy20231223" ) return false; //---------------------------------------------------------------- version_guess = temp_string; //---------------------------------------------------------------- in.get(a); in.get(b); in.get(c); in.get(d); LaserBoy_wav_mode = ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); //---------------------------------------------------------------- if(LaserBoy_wav_mode & LASERBOY_WAVE_OFFSETS) { for(i = 0; i < num_channels; i++) { in.get(a); in.get(b); in.get(c); in.get(d); offset[i] = ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); } } // end if(LaserBoy_wav_mode & LASERBOY_WAVE_OFFSETS) //---------------------------------------------------------------- if(LaserBoy_wav_mode & LASERBOY_WAVE_OPTIMIZED) { in.get(a); in.get(b); in.get(c); in.get(d); parms.lit_dwell_overhang = ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); //---------------------------------------------------------------- if(version_guess == "LaserBoy06072008") { // floats were stored backwards. Oops! in.get(a); in.get(b); in.get(c); in.get(d); parms.lit_delta_max = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); parms.blank_delta_max = parms.lit_delta_max; in.get(a); in.get(b); in.get(c); in.get(d); parms.max_dwell_microsec = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(a); in.get(b); in.get(c); in.get(d); parms.insignificant_distance = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(a); in.get(b); in.get(c); in.get(d); parms.insignificant_angle = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(a); in.get(b); in.get(c); in.get(d); parms.frames_per_second = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); } // end if(version_guess == "LaserBoy06072008") //---------------------------------------------------------------- else if(version_guess == "LaserBoy10102008") { in.get(d); in.get(c); in.get(b); in.get(a); parms.lit_delta_max = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); parms.blank_delta_max = parms.lit_delta_max; in.get(d); in.get(c); in.get(b); in.get(a); parms.max_dwell_microsec = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.insignificant_distance = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.insignificant_angle = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.frames_per_second = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); } // end else if(version_guess == "LaserBoy10102008") //---------------------------------------------------------------- else if( version_guess == "LaserBoy11112008" || version_guess == "LaserBoy12082009" ) { in.get(d); in.get(c); in.get(b); in.get(a); parms.lit_delta_max = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.blank_delta_max = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.max_dwell_microsec = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.insignificant_distance = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.insignificant_angle = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.frames_per_second = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); } // end else if(version_guess == "LaserBoy11112008" || "LaserBoy12082009") //---------------------------------------------------------------- else // since "LaserBoy06282010" { in.get(d); in.get(c); in.get(b); in.get(a); parms.lit_delta_max = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.blank_delta_max = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.max_dwell_microsec = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.max_wag_microsec = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.insignificant_distance = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.insignificant_angle = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); in.get(d); in.get(c); in.get(b); in.get(a); parms.frames_per_second = (float) ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); } } // end if(LaserBoy_wav_mode & LASERBOY_WAVE_OPTIMIZED) //---------------------------------------------------------------- if(LaserBoy_wav_mode & LASERBOY_WAVE_SIGNAL_MATRIX) { for(i = 0; i < num_channels; i++) { in.get(a); in.get(b); signal_id[i] = ((b & 0x00ff) << 8 | (a & 0x00ff)); in.get(a); in.get(b); LSB_tag [i] = ((b & 0x00ff) << 8 | (a & 0x00ff)); } } // end if(LaserBoy_wav_mode & LASERBOY_WAVE_SIGNAL_MATRIX) else if(num_channels >= 6) { signal_id[0] = LASERBOY_SIGNAL_X_POSITION; signal_id[1] = LASERBOY_SIGNAL_Y_POSITION; signal_id[2] = LASERBOY_SIGNAL_RED_ANALOG; signal_id[3] = LASERBOY_SIGNAL_GREEN_ANALOG; signal_id[4] = LASERBOY_SIGNAL_BLUE_ANALOG; if(offset[5] == 0) signal_id[5] = LASERBOY_SIGNAL_Z_POSITION; LSB_tag [2] = LASERBOY_LSB_END_OF_FRAME; LSB_tag [3] = LASERBOY_LSB_UNIQUE_FRAME; } //---------------------------------------------------------------- if( temp_string != "LaserBoy06072008" && temp_string != "LaserBoy07132008" && temp_string != "LaserBoy10102008" && temp_string != "LaserBoy11112008" && temp_string != "LaserBoy12082009" && temp_string != "LaserBoy06282010" // 13.5 years ago! ) { // it is later than "LaserBoy06282010" if(LaserBoy_wav_mode & LASERBOY_SIGNAL_BIT_RESOLUTION) for(i = 0; i < num_channels; i++) { in.get(a); in.get(b); // 16 bits! resolution[i] = (u_char)a; } } // end later than "LaserBoy06282010" else // "LaserBoy06282010" or before { if(LaserBoy_wav_mode & LASERBOY_SIGNAL_BIT_RESOLUTION) for(i = 0; i < num_channels; i++) { in.get(a); resolution[i] = (u_char)a; } } // end "LaserBoy06282010" or before //---------------------------------------------------------------- if(LaserBoy_wav_mode & LASERBOY_WAVE_NUM_FRAMES) { in.get(a); in.get(b); in.get(c); in.get(d); num_frames = ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); } // end if(LaserBoy_wav_mode & LASERBOY_WAVE_NUM_FRAMES) //---------------------------------------------------------------- if(LaserBoy_wav_mode & LASERBOY_COLOR_RESCALE_R && in.good()) in.read((char*)color_rescale_r, 256 * sizeof(signed short)); //---------------------------------------------------------------- if(LaserBoy_wav_mode & LASERBOY_COLOR_RESCALE_G && in.good()) in.read((char*)color_rescale_g, 256 * sizeof(signed short)); //---------------------------------------------------------------- if(LaserBoy_wav_mode & LASERBOY_COLOR_RESCALE_B && in.good()) in.read((char*)color_rescale_b, 256 * sizeof(signed short)); //---------------------------------------------------------------- if(LaserBoy_wav_mode & LASERBOY_COLOR_RESCALE_I && in.good()) in.read((char*)color_rescale_i, 256 * sizeof(signed short)); //---------------------------------------------------------------- channel_map.clear(); for(i = 0; i < num_channels; i++) { switch((int)abs(signal_id[i])) { case LASERBOY_SIGNAL_X_POSITION: channel_map.push_back('X'); break; case LASERBOY_SIGNAL_Y_POSITION: channel_map.push_back('Y'); break; case LASERBOY_SIGNAL_Z_POSITION: channel_map.push_back('Z'); break; case LASERBOY_SIGNAL_RED_ANALOG: channel_map.push_back('r'); break; case LASERBOY_SIGNAL_GREEN_ANALOG: channel_map.push_back('g'); break; case LASERBOY_SIGNAL_BLUE_ANALOG: channel_map.push_back('b'); break; case LASERBOY_SIGNAL_MONO_TTL: case LASERBOY_SIGNAL_MONO_OR_ANALOG: case LASERBOY_SIGNAL_MONO_WEIGHTED_ANALOG: case LASERBOY_SIGNAL_MONO_AVG_ANALOG: case LASERBOY_SIGNAL_MONO_O_SCOPE: channel_map.push_back('i'); break; case LASERBOY_NO_SIGNAL: channel_map.push_back('0'); break; default: channel_map.push_back('?'); break; } // end switch((int)abs(signal_id[i])) } // end for(i = 0; i < num_channels; i++) } // end if(temp_string == "LaserBoy") //------------------------------------------------------------------------ temp_string.clear(); in.get(a); temp_string.push_back(a); // d in.get(a); temp_string.push_back(a); // a in.get(a); temp_string.push_back(a); // t in.get(a); temp_string.push_back(a); // a //------------------------------------------------------------------------ if(temp_string != "data") { d = ' '; while(d != 'a' && in.good()) { c = ' '; while(c != 't' && in.good()) { b = ' '; while(b != 'a' && in.good()) { a = ' '; while(a != 'd' && in.good()) in.get(a); in.get(b); } in.get(c); } in.get(d); } } if(!in.good()) return false; //------------------------------------------------------------------------ in.get(a); in.get(b); in.get(c); in.get(d); sub_chunk_2_size = ( (a & 0x000000ff) | (b & 0x000000ff) << 8 | (c & 0x000000ff) << 16 | (d & 0x000000ff) << 24 ); //------------------------------------------------------------------------ header_size = in.tellg(); num_samples = sub_chunk_2_size / (num_channels * (bits_per_sample / 8)); version = version_guess; // Woohoo !!! //------------------------------------------------------------------------ return true; } //############################################################################ void LaserBoy_wav_header::to_fstream_wav(std::fstream& out) { short audio_format = 1, block_align = num_channels * (bits_per_sample / 8); int i, sub_chunk_1_size = 16, // standard wav Subchunk1Size LaserBoy_chunk_size = 0, sub_chunk_2_size = num_samples * num_channels * (bits_per_sample / 8), byte_rate = sample_rate * num_channels * (bits_per_sample / 8), chunk_size = 20 + sub_chunk_1_size + sub_chunk_2_size; //------------------------------------------------------------------------ if(version != "!LaserBoy!") // it is a LaserBoy wav. { LaserBoy_chunk_size = lboy_chunk_size(); chunk_size += ( 4 // sizeof "LBoy" + sizeof(int) // sizeof (int)LaserBoy_chunk_size + LaserBoy_chunk_size ); } //------------------------------------------------------------------------ out.seekp(0, ios::beg); //------------------------------------------------------------------------ out.put('R'); out.put('I'); out.put('F'); out.put('F'); out.put((char) (chunk_size & 0x000000ff) ); out.put((char)((chunk_size & 0x0000ff00) >> 8 )); out.put((char)((chunk_size & 0x00ff0000) >> 16)); out.put((char)((chunk_size & 0xff000000) >> 24)); out.put('W'); out.put('A'); out.put('V'); out.put('E'); out.put('f'); out.put('m'); out.put('t'); out.put(' '); out.put((char) (sub_chunk_1_size & 0x000000ff) ); out.put((char)((sub_chunk_1_size & 0x0000ff00) >> 8 )); out.put((char)((sub_chunk_1_size & 0x00ff0000) >> 16)); out.put((char)((sub_chunk_1_size & 0xff000000) >> 24)); out.put((char) (audio_format & 0x00ff) ); out.put((char)((audio_format & 0xff00) >> 8)); // 2 out.put((char) (num_channels & 0x00ff) ); out.put((char)((num_channels & 0xff00) >> 8)); // 4 out.put((char) (sample_rate & 0x000000ff) ); out.put((char)((sample_rate & 0x0000ff00) >> 8 )); out.put((char)((sample_rate & 0x00ff0000) >> 16)); out.put((char)((sample_rate & 0xff000000) >> 24)); // 8 out.put((char) (byte_rate & 0x000000ff) ); out.put((char)((byte_rate & 0x0000ff00) >> 8 )); out.put((char)((byte_rate & 0x00ff0000) >> 16)); out.put((char)((byte_rate & 0xff000000) >> 24)); // 12 out.put((char) (block_align & 0x00ff) ); out.put((char)((block_align & 0xff00) >> 8)); // 14 out.put((char) (bits_per_sample & 0x00ff) ); out.put((char)((bits_per_sample & 0xff00) >> 8)); // 16 //---------------------------------------------------------------------------- // information added for LaserBoy !!! //---------------------------------------------------------------------------- if(version != "!LaserBoy!") { out.put('L'); out.put('B'); out.put('o'); out.put('y'); out.put((char) (LaserBoy_chunk_size & 0x000000ff) ); out.put((char)((LaserBoy_chunk_size & 0x0000ff00) >> 8 )); out.put((char)((LaserBoy_chunk_size & 0x00ff0000) >> 16)); out.put((char)((LaserBoy_chunk_size & 0xff000000) >> 24)); // 36 out.put(version[ 0]); // L out.put(version[ 1]); // a out.put(version[ 2]); // s out.put(version[ 3]); // e out.put(version[ 4]); // r out.put(version[ 5]); // B out.put(version[ 6]); // o out.put(version[ 7]); // y out.put(version[ 8]); // C out.put(version[ 9]); // C out.put(version[10]); // Y out.put(version[11]); // Y out.put(version[12]); // M out.put(version[13]); // M out.put(version[14]); // D out.put(version[15]); // D out.put((char) (LaserBoy_wav_mode & 0x000000ff) ); out.put((char)((LaserBoy_wav_mode & 0x0000ff00) >> 8 )); out.put((char)((LaserBoy_wav_mode & 0x00ff0000) >> 16)); out.put((char)((LaserBoy_wav_mode & 0xff000000) >> 24)); if(LaserBoy_wav_mode & LASERBOY_WAVE_OFFSETS) { for(i = 0; i < num_channels; i++) { out.put((char)( offset[i] & 0x000000ff) ); out.put((char)((offset[i] & 0x0000ff00) >> 8 )); out.put((char)((offset[i] & 0x00ff0000) >> 16)); out.put((char)((offset[i] & 0xff000000) >> 24)); } } if(LaserBoy_wav_mode & LASERBOY_WAVE_OPTIMIZED) { out.put((char) (parms.lit_dwell_overhang & 0x000000ff) ); // int out.put((char)((parms.lit_dwell_overhang & 0x0000ff00) >> 8 )); out.put((char)((parms.lit_dwell_overhang & 0x00ff0000) >> 16)); out.put((char)((parms.lit_dwell_overhang & 0xff000000) >> 24)); out.put((char)(((int)(parms.lit_delta_max) & 0xff000000) >> 24)); // float out.put((char)(((int)(parms.lit_delta_max) & 0x00ff0000) >> 16)); out.put((char)(((int)(parms.lit_delta_max) & 0x0000ff00) >> 8 )); out.put((char) ((int)(parms.lit_delta_max) & 0x000000ff) ); out.put((char)(((int)(parms.blank_delta_max) & 0xff000000) >> 24)); // float out.put((char)(((int)(parms.blank_delta_max) & 0x00ff0000) >> 16)); out.put((char)(((int)(parms.blank_delta_max) & 0x0000ff00) >> 8 )); out.put((char) ((int)(parms.blank_delta_max) & 0x000000ff) ); out.put((char)(((int)(parms.max_dwell_microsec) & 0xff000000) >> 24)); // float out.put((char)(((int)(parms.max_dwell_microsec) & 0x00ff0000) >> 16)); out.put((char)(((int)(parms.max_dwell_microsec) & 0x0000ff00) >> 8 )); out.put((char) ((int)(parms.max_dwell_microsec) & 0x000000ff) ); out.put((char)(((int)(parms.max_wag_microsec) & 0xff000000) >> 24)); // float out.put((char)(((int)(parms.max_wag_microsec) & 0x00ff0000) >> 16)); out.put((char)(((int)(parms.max_wag_microsec) & 0x0000ff00) >> 8 )); out.put((char) ((int)(parms.max_wag_microsec) & 0x000000ff) ); out.put((char)(((int)(parms.insignificant_distance) & 0xff000000) >> 24)); // float out.put((char)(((int)(parms.insignificant_distance) & 0x00ff0000) >> 16)); out.put((char)(((int)(parms.insignificant_distance) & 0x0000ff00) >> 8 )); out.put((char) ((int)(parms.insignificant_distance) & 0x000000ff) ); out.put((char)(((int)(parms.insignificant_angle) & 0xff000000) >> 24)); // float out.put((char)(((int)(parms.insignificant_angle) & 0x00ff0000) >> 16)); out.put((char)(((int)(parms.insignificant_angle) & 0x0000ff00) >> 8 )); out.put((char) ((int)(parms.insignificant_angle) & 0x000000ff) ); out.put((char)(((int)(parms.frames_per_second) & 0xff000000) >> 24)); // float out.put((char)(((int)(parms.frames_per_second) & 0x00ff0000) >> 16)); out.put((char)(((int)(parms.frames_per_second) & 0x0000ff00) >> 8 )); out.put((char) ((int)(parms.frames_per_second) & 0x000000ff) ); } if(LaserBoy_wav_mode & LASERBOY_WAVE_SIGNAL_MATRIX) for(i = 0; i < num_channels; i++) { out.put((char) (signal_id[i] & 0x00ff) ); out.put((char)((signal_id[i] & 0xff00) >> 8)); out.put((char) (LSB_tag[i] & 0x00ff) ); out.put((char)((LSB_tag[i] & 0xff00) >> 8)); } if(LaserBoy_wav_mode & LASERBOY_SIGNAL_BIT_RESOLUTION) { for(i = 0; i < num_channels; i++) { out.put(resolution[i]); out.put(0x00); // always an even number of bytes. } } if(LaserBoy_wav_mode & LASERBOY_WAVE_NUM_FRAMES) { out.put((char)( num_frames & 0x000000ff) ); out.put((char)((num_frames & 0x0000ff00) >> 8 )); out.put((char)((num_frames & 0x00ff0000) >> 16)); out.put((char)((num_frames & 0xff000000) >> 24)); } if(LaserBoy_wav_mode & LASERBOY_COLOR_RESCALE_R) out.write((char*)color_rescale_r, 256 * sizeof(signed short)); if(LaserBoy_wav_mode & LASERBOY_COLOR_RESCALE_G) out.write((char*)color_rescale_g, 256 * sizeof(signed short)); if(LaserBoy_wav_mode & LASERBOY_COLOR_RESCALE_B) out.write((char*)color_rescale_b, 256 * sizeof(signed short)); if(LaserBoy_wav_mode & LASERBOY_COLOR_RESCALE_I) out.write((char*)color_rescale_i, 256 * sizeof(signed short)); } // end if(version != "!LaserBoy!") //---------------------------------------------------------------------------- // end of report information added for LaserBoy !!! //---------------------------------------------------------------------------- // data chunk! //---------------------------------------------------------------------------- out.put('d'); out.put('a'); out.put('t'); out.put('a'); out.put((char) (sub_chunk_2_size & 0x000000ff) ); out.put((char)((sub_chunk_2_size & 0x0000ff00) >> 8 )); out.put((char)((sub_chunk_2_size & 0x00ff0000) >> 16)); out.put((char)((sub_chunk_2_size & 0xff000000) >> 24)); header_size = out.tellp(); return; } //############################################################################ void LaserBoy_wav_header::tell(string label) const { cout << "----------------------------------------------------------" << ENDL; cout << "-- " << label << ENDL << ENDL; cout << " file_name : " << file_name << ENDL; cout << " header_size : " << header_size << ENDL; cout << " num_samples : " << num_samples << ENDL; cout << " sample_rate : " << sample_rate << ENDL; cout << " channel_map : " << channel_map << ENDL; //------------------------------------------------------------------------ if(version != "!LaserBoy!") { cout << " LaserBoy_wav_mode : "; if(LaserBoy_wav_mode & LASERBOY_WAVE_POSITIVE ) cout << "LASERBOY_WAVE_POSITIVE" << ENDL; else cout << "LASERBOY_WAVE_NEGATIVE" << ENDL; if(LaserBoy_wav_mode & LASERBOY_WAVE_END_OF_FRAME ) cout << " LASERBOY_WAVE_END_OF_FRAME" << ENDL; if(LaserBoy_wav_mode & LASERBOY_WAVE_UNIQUE_FRAME ) cout << " LASERBOY_WAVE_UNIQUE_FRAME" << ENDL; if(LaserBoy_wav_mode & LASERBOY_WAVE_UNIQUE_VERTEX ) cout << " LASERBOY_WAVE_UNIQUE_VERTEX" << ENDL; if(LaserBoy_wav_mode & LASERBOY_WAVE_OFFSETS ) cout << " LASERBOY_WAVE_OFFSETS" << ENDL; if(LaserBoy_wav_mode & LASERBOY_WAVE_OPTIMIZED ) cout << " LASERBOY_WAVE_OPTIMIZED" << ENDL; else cout << " --- no optimization ----" << ENDL; if(LaserBoy_wav_mode & LASERBOY_WAVE_SIGNAL_MATRIX ) cout << " LASERBOY_WAVE_SIGNAL_MATRIX" << ENDL; if(LaserBoy_wav_mode & LASERBOY_SIGNAL_BIT_RESOLUTION) cout << " LASERBOY_SIGNAL_BIT_RESOLUTION" << ENDL; //---------------------------------------------------------------- cout << " num_channels : " << num_channels << ENDL; cout << " bits_per_sample : " << bits_per_sample << ENDL; cout << " version : " << version << ENDL << ENDL; //---------------------------------------------------------------- cout << " ch. :offset: bits : : signal name : LSB tag" << ENDL; cout << "-----:------:------:-----:--------------:-----------------" << ENDL; for(int i = 0; i < num_channels; i++) { cout << setw(4) << i << " : "; if(LaserBoy_wav_mode & LASERBOY_WAVE_OFFSETS) cout << setw(4) << (int)offset[i]; else cout << " na "; cout << " : "; if(LaserBoy_wav_mode & LASERBOY_SIGNAL_BIT_RESOLUTION) cout << setw(4) << (int)resolution[i]; else cout << " "; if(LaserBoy_wav_mode & LASERBOY_WAVE_SIGNAL_MATRIX) cout << " : " << ((signal_id[i] >= 0) ? ("pos") : ("neg")) << " : " << wav_signal_id_to_name(signal_id[i]) << " : " << wav_LSB_tag_to_name(LSB_tag[i]) << ENDL; else cout << ENDL; } //---------------------------------------------------------------- if(LaserBoy_wav_mode & LASERBOY_WAVE_OPTIMIZED) { cout << ENDL; cout << " lit_dwell_overhang : " << parms.lit_dwell_overhang << ENDL; cout << " lit_delta_max : " << parms.lit_delta_max << ENDL; cout << " blank_delta_max : " << parms.blank_delta_max << ENDL; cout << " max_dwell_microsec : " << parms.max_dwell_microsec << ENDL; cout << " max_wag_microsec : " << parms.max_wag_microsec << ENDL; cout << "insignificant_distance : " << parms.insignificant_distance << ENDL; cout << " insignificant_angle : " << parms.insignificant_angle * one_radian << ENDL; cout << " frames_per_second : " << parms.frames_per_second << ENDL; } } else { cout << "not a LaserBoy wav" << ENDL; } cout << "----------------------------------------------------------" << ENDL; return; } //############################################################################ ////////////////////////////////////////////////////////////////////////////// //############################################################################