samplebrain/brain/src/window.cpp

137 lines
4.0 KiB
C++
Raw Normal View History

2022-09-08 08:21:53 -03:00
// Copyright (C) 2022 Then Try This
2015-07-21 10:58:13 -03:00
//
// This program 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 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2015-07-18 20:34:56 -03:00
#include "window.h"
#include <cmath>
#include <iostream>
using namespace std;
using namespace spiralcore;
2016-09-24 06:41:10 -03:00
#ifndef M_PI
#define M_PI 3.141592653589
#endif
2015-07-18 20:34:56 -03:00
window::window() :
m_current_type(RECTANGLE)
{
}
void window::clear() {
for (vector<sample*>::iterator i=m_windows.begin(); i!=m_windows.end(); ++i) {
delete *i;
}
m_windows.clear();
}
void window::init(u32 size) {
clear();
for (u32 i=0; i<MAX_TYPES; i++) {
window::type t = (window::type)i;
sample *s = new sample(size);
switch(t) {
case DODGY: {
u32 start=size/6;
u32 end=size/6;
for (u32 n=0; n<size; ++n) {
(*s)[n] = 1;
}
for(u32 i=0; i<start; ++i) {
(*s)[i]=i/(float)start;
}
for(u32 i=0; i<end; ++i) {
(*s)[(size-1)-i]=i/(float)end;
}
} break;
case BARTLETT: {
for (u32 n=0; n<size; ++n) {
(*s)[n]=1.0 - (2.0 * fabs(n - (size - 1) / 2.0)) / (double(size - 1));
}
} break;
case BLACKMAN: {
for (u32 n=0; n<size; ++n) {
(*s)[n]= 0.42 - 0.5 * cos(2.0 * M_PI * n / double(size - 1)) +
0.08 * cos(4.0 * M_PI * n / double(size - 1));
}
} break;
case FLAT_TOP: {
for (u32 n=0; n<size; ++n) {
(*s)[n]=
1.0 - 1.93 * cos(2.0 * M_PI * n / double(size - 1)) +
1.29 * cos(4.0 * M_PI * n / double(size - 1)) -
0.388 * cos(6.0 * M_PI * n / double(size - 1)) +
0.0322 * cos(8.0 * M_PI * n / double(size - 1));
}
} break;
case GAUSSIAN: {
float sigma=0.5;
for (u32 n=0; n<size; ++n) {
(*s)[n]= exp((-0.5) * pow((n - (size - 1.0) / 2.0)/(sigma * (size - 1.0) / 2.0), 2.0));
}
} break;
case HAMMING : {
for (u32 n=0; n<size; ++n) {
(*s)[n]= 0.53836 - 0.46164 * cos(2.0 * M_PI * n / double(size - 1));
}
} break;
case HANN : {
for (u32 n=0; n<size; ++n) {
(*s)[n]= 0.5 * (1.0 - cos(2.0 * M_PI * n / double(size - 1)));
}
} break;
case RECTANGLE : {
for (u32 n=0; n<size; ++n) {
(*s)[n] = 1;
}
} break;
default: assert(0);
}
m_windows.push_back(s);
}
}
void window::run(const sample &input) const {
//assert(input.get_length()==m_windows[0]->get_length());
for (u32 n=0; n<input.get_length(); ++n) {
input[n]*=(*m_windows[m_current_type])[n];
}
}
2015-08-03 05:18:20 -03:00
ios &spiralcore::operator||(ios &s, window &b) {
u32 version=0;
string id("window");
s||id||version;
s||b.m_current_type;
std::ofstream *pos=dynamic_cast<std::ofstream*>(&s);
if (pos!=NULL) {
u32 size=0;
// get the size from the first window
if (b.m_windows.size()>0) {
size=b.m_windows[0]->get_length();
}
s||size;
} else {
u32 size=0;
s||size;
// reinit using size if we are reading in
b.init(size);
}
return s;
}