vibrating_string.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * vibrating_sring.h - model of a vibrating string lifted from pluckedSynth
  3. *
  4. * Copyright (c) 2006-2008 Danny McRae <khjklujn/at/yahoo/com>
  5. *
  6. * This file is part of LMMS - https://lmms.io
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public
  19. * License along with this program (see COPYING); if not, write to the
  20. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  21. * Boston, MA 02110-1301 USA.
  22. *
  23. */
  24. #include <math.h>
  25. #include "vibrating_string.h"
  26. #include "templates.h"
  27. #include "interpolation.h"
  28. #include "Mixer.h"
  29. #include "Engine.h"
  30. vibratingString::vibratingString( float _pitch,
  31. float _pick,
  32. float _pickup,
  33. float * _impulse,
  34. int _len,
  35. sample_rate_t _sample_rate,
  36. int _oversample,
  37. float _randomize,
  38. float _string_loss,
  39. float _detune,
  40. bool _state ) :
  41. m_oversample( 2 * _oversample / (int)( _sample_rate /
  42. Engine::mixer()->baseSampleRate() ) ),
  43. m_randomize( _randomize ),
  44. m_stringLoss( 1.0f - _string_loss ),
  45. m_state( 0.1f )
  46. {
  47. m_outsamp = new sample_t[m_oversample];
  48. int string_length;
  49. string_length = static_cast<int>( m_oversample * _sample_rate /
  50. _pitch ) + 1;
  51. string_length += static_cast<int>( string_length * -_detune );
  52. int pick = static_cast<int>( ceil( string_length * _pick ) );
  53. if( not _state )
  54. {
  55. m_impulse = new float[string_length];
  56. resample( _impulse, _len, string_length );
  57. }
  58. else
  59. {
  60. m_impulse = new float[_len];
  61. for( int i = 0; i < _len; i++ )
  62. {
  63. m_impulse[i] = _impulse[i];
  64. }
  65. }
  66. m_toBridge = vibratingString::initDelayLine( string_length, pick );
  67. m_fromBridge = vibratingString::initDelayLine( string_length, pick );
  68. vibratingString::setDelayLine( m_toBridge, pick,
  69. m_impulse, _len, 0.5f,
  70. _state );
  71. vibratingString::setDelayLine( m_fromBridge, pick,
  72. m_impulse, _len, 0.5f,
  73. _state);
  74. m_choice = static_cast<int>( m_oversample *
  75. static_cast<float>( rand() ) / RAND_MAX );
  76. m_pickupLoc = static_cast<int>( _pickup * string_length );
  77. }
  78. vibratingString::delayLine * vibratingString::initDelayLine( int _len,
  79. int _pick )
  80. {
  81. delayLine * dl = new vibratingString::delayLine[_len];
  82. dl->length = _len;
  83. if( _len > 0 )
  84. {
  85. dl->data = new sample_t[_len];
  86. float r;
  87. float offset = 0.0f;
  88. for( int i = 0; i < dl->length; i++ )
  89. {
  90. r = static_cast<float>( rand() ) /
  91. RAND_MAX;
  92. offset = ( m_randomize / 2.0f -
  93. m_randomize ) * r;
  94. dl->data[i] = offset;
  95. }
  96. }
  97. else
  98. {
  99. dl->data = NULL;
  100. }
  101. dl->pointer = dl->data;
  102. dl->end = dl->data + _len - 1;
  103. return( dl );
  104. }
  105. void vibratingString::freeDelayLine( delayLine * _dl )
  106. {
  107. if( _dl )
  108. {
  109. delete[] _dl->data;
  110. delete[] _dl;
  111. }
  112. }
  113. void vibratingString::resample( float *_src, f_cnt_t _src_frames,
  114. f_cnt_t _dst_frames )
  115. {
  116. for( f_cnt_t frame = 0; frame < _dst_frames; ++frame )
  117. {
  118. const float src_frame_float = frame *
  119. (float) _src_frames /
  120. _dst_frames;
  121. const float frac_pos = src_frame_float -
  122. static_cast<f_cnt_t>( src_frame_float );
  123. const f_cnt_t src_frame = tLimit<f_cnt_t>(
  124. static_cast<f_cnt_t>( src_frame_float ),
  125. 1, _src_frames - 3 );
  126. m_impulse[frame] = cubicInterpolate(
  127. _src[src_frame - 1],
  128. _src[src_frame + 0],
  129. _src[src_frame + 1],
  130. _src[src_frame + 2],
  131. frac_pos );
  132. }
  133. }