123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /*
- * 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
|