Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* SampleGenerator.h
|
||||
* -----------------
|
||||
* Purpose: Generate samples from math formulas using muParser
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openmpt/all/BuildSettings.hpp"
|
||||
|
||||
#ifdef MPT_DISABLED_CODE
|
||||
|
||||
#include "Mptrack.h"
|
||||
#include "Mainfrm.h"
|
||||
#include "Sndfile.h"
|
||||
#include "../muParser/include/muParser.h"
|
||||
|
||||
// sample length
|
||||
#define SMPGEN_MINLENGTH 1
|
||||
#define SMPGEN_MAXLENGTH MAX_SAMPLE_LENGTH
|
||||
// sample frequency
|
||||
#define SMPGEN_MINFREQ 1
|
||||
#define SMPGEN_MAXFREQ 96000 // MAX_SAMPLE_RATE
|
||||
// 16-bit sample quality - when changing this, also change CSampleGenerator::sampling_type and 16-bit flags in SampleGenerator.cpp!
|
||||
#define SMPGEN_MIXBYTES 2
|
||||
|
||||
enum smpgen_clip_methods
|
||||
{
|
||||
smpgen_clip,
|
||||
smpgen_overflow,
|
||||
smpgen_normalize,
|
||||
};
|
||||
|
||||
class CSampleGenerator
|
||||
{
|
||||
protected:
|
||||
|
||||
// sample parameters
|
||||
static int sample_frequency;
|
||||
static int sample_length;
|
||||
static mu::string_type expression;
|
||||
static smpgen_clip_methods sample_clipping;
|
||||
|
||||
// rendering helper variables (they're here for the callback functions)
|
||||
static mu::value_type *sample_buffer;
|
||||
static size_t samples_written;
|
||||
|
||||
typedef int16 sampling_type; // has to match SMPGEN_MIXBYTES!
|
||||
static constexpr sampling_type sample_maxvalue = (1 << ((SMPGEN_MIXBYTES << 3) - 1)) - 1;
|
||||
|
||||
// muParser object for parsing the expression
|
||||
mu::Parser muParser;
|
||||
|
||||
// Rendering callback functions
|
||||
// functions
|
||||
static mu::value_type ClipCallback(mu::value_type val, mu::value_type min, mu::value_type max) { return Clamp(val, min, max); };
|
||||
static mu::value_type PWMCallback(mu::value_type pos, mu::value_type duty, mu::value_type width) { if(width == 0) return 0; else return (fmod(pos, width) < ((duty / 100) * width)) ? 1 : -1; };
|
||||
static mu::value_type RndCallback(mu::value_type v) { return v * std::rand() / (mu::value_type)(RAND_MAX + 1.0); };
|
||||
static mu::value_type SampleDataCallback(mu::value_type v);
|
||||
static mu::value_type TriangleCallback(mu::value_type pos, mu::value_type width) { if((int)width == 0) return 0; else return std::abs(((int)pos % (int)(width)) - width / 2) / (width / 4) - 1; };
|
||||
|
||||
// binary operators
|
||||
static mu::value_type ModuloCallback(mu::value_type x, mu::value_type y) { if(y == 0) return 0; else return fmod(x , y); };
|
||||
|
||||
void ShowError(mu::Parser::exception_type *e);
|
||||
|
||||
public:
|
||||
|
||||
bool ShowDialog();
|
||||
bool TestExpression();
|
||||
bool CanRenderSample() const;
|
||||
bool RenderSample(CSoundFile *pSndFile, SAMPLEINDEX nSample);
|
||||
|
||||
CSampleGenerator();
|
||||
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Sample Generator Formula Preset implementation
|
||||
|
||||
|
||||
struct samplegen_expression
|
||||
{
|
||||
std::string description; // e.g. "Pulse"
|
||||
mu::string_type expression; // e.g. "pwm(x,y,z)" - empty if this is a sub menu
|
||||
};
|
||||
#define MAX_SAMPLEGEN_PRESETS 100
|
||||
|
||||
|
||||
class CSmpGenPresets
|
||||
{
|
||||
protected:
|
||||
vector<samplegen_expression> presets;
|
||||
|
||||
public:
|
||||
bool AddPreset(samplegen_expression new_preset) { if(GetNumPresets() >= MAX_SAMPLEGEN_PRESETS) return false; presets.push_back(new_preset); return true;};
|
||||
bool RemovePreset(size_t which) { if(which < GetNumPresets()) { presets.erase(presets.begin() + which); return true; } else return false; };
|
||||
samplegen_expression *GetPreset(size_t which) { if(which < GetNumPresets()) return &presets[which]; else return nullptr; };
|
||||
size_t GetNumPresets() { return presets.size(); };
|
||||
void Clear() { presets.clear(); };
|
||||
|
||||
CSmpGenPresets() { Clear(); }
|
||||
~CSmpGenPresets() { Clear(); }
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Sample Generator Dialog implementation
|
||||
|
||||
|
||||
class CSmpGenDialog: public CDialog
|
||||
{
|
||||
protected:
|
||||
|
||||
// sample parameters
|
||||
int sample_frequency;
|
||||
int sample_length;
|
||||
double sample_seconds;
|
||||
mu::string_type expression;
|
||||
smpgen_clip_methods sample_clipping;
|
||||
// pressed "OK"?
|
||||
bool apply;
|
||||
// preset slots
|
||||
CSmpGenPresets presets;
|
||||
|
||||
HFONT hButtonFont; // "Marlett" font for "dropdown" button
|
||||
|
||||
void RecalcParameters(bool secondsChanged, bool forceRefresh = false);
|
||||
|
||||
// function presets
|
||||
void CreateDefaultPresets();
|
||||
|
||||
public:
|
||||
|
||||
const int GetFrequency() { return sample_frequency; };
|
||||
const int GetLength() { return sample_length; };
|
||||
const smpgen_clip_methods GetClipping() { return sample_clipping; }
|
||||
const mu::string_type GetExpression() { return expression; };
|
||||
bool CanApply() { return apply; };
|
||||
|
||||
CSmpGenDialog(int freq, int len, smpgen_clip_methods clipping, mu::string_type expr):CDialog(IDD_SAMPLE_GENERATOR, CMainFrame::GetMainFrame())
|
||||
{
|
||||
sample_frequency = freq;
|
||||
sample_length = len;
|
||||
sample_clipping = clipping;
|
||||
expression = expr;
|
||||
apply = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
virtual void OnCancel();
|
||||
|
||||
afx_msg void OnSampleLengthChanged();
|
||||
afx_msg void OnSampleSecondsChanged();
|
||||
afx_msg void OnSampleFreqChanged();
|
||||
afx_msg void OnExpressionChanged();
|
||||
afx_msg void OnShowExpressions();
|
||||
afx_msg void OnShowPresets();
|
||||
afx_msg void OnInsertExpression(UINT nId);
|
||||
afx_msg void OnSelectPreset(UINT nId);
|
||||
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Sample Generator Preset Dialog implementation
|
||||
|
||||
|
||||
class CSmpGenPresetDlg: public CDialog
|
||||
{
|
||||
protected:
|
||||
CSmpGenPresets *presets;
|
||||
size_t currentItem; // first item is actually 1!
|
||||
|
||||
void RefreshList();
|
||||
|
||||
public:
|
||||
CSmpGenPresetDlg(CSmpGenPresets *pPresets):CDialog(IDD_SAMPLE_GENERATOR_PRESETS, CMainFrame::GetMainFrame())
|
||||
{
|
||||
presets = pPresets;
|
||||
currentItem = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
|
||||
afx_msg void OnListSelChange();
|
||||
|
||||
afx_msg void OnTextChanged();
|
||||
afx_msg void OnExpressionChanged();
|
||||
|
||||
afx_msg void OnAddPreset();
|
||||
afx_msg void OnRemovePreset();
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
#endif // MPT_DISABLED_CODE
|
Loading…
Add table
Add a link
Reference in a new issue