Compare commits

..

34 Commits

Author SHA1 Message Date
Tobias Doerffel
2ff42ac80b added copy constructor implementation for AtomicInt class - fixes build failure with Qt < 4.4.0, fixed typo
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2074 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-23 22:32:31 +00:00
Tobias Doerffel
640f140ef1 made 0.4.3 release
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2071 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-23 19:57:08 +00:00
Tobias Doerffel
fa7085d80f fixed typos
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2070 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-23 19:55:06 +00:00
Tobias Doerffel
6c7e6571e7 reflect changes in MinGW crosscompiling environment
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2068 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-23 18:55:38 +00:00
Tobias Doerffel
9b533f055a rewrote timing of fading animation for not postponing updates of hidden fadeButton until it becomes visible (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2058 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-19 15:03:23 +00:00
Tobias Doerffel
168b65dfae make sure all buttons in trackOperationsWidget have focus-policy set to Qt::NoFocus in order to make space play song even if you clicked e.g. a mute-button (closes #2486211) (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2057 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-19 15:02:41 +00:00
Tobias Doerffel
625c947d7a move timeLine marker in Piano Roll and autoscroll when recording while playing song (closes #2486334) (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2054 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-19 14:27:42 +00:00
Tobias Doerffel
264ad268ba more record-accompany fixes (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2052 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-19 13:57:22 +00:00
Tobias Doerffel
6b875a9181 coding style fixes, improved handling of shared detuningHelper object (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2050 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-19 13:44:19 +00:00
Tobias Doerffel
4c93249aae coding style fixes, improved handling of shared detuningHelper object (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2049 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-19 13:40:24 +00:00
Tobias Doerffel
c720c1f4c8 stable backport:
fixed various bugs regarding recording:
* once recording has been started, stop it as soon as playMode of song changes or similiar things happen (closes #2486341)
* fixed broken record-accompany in most use-cases other than using record-while-playing-song by also tracking NoteOn events and 
remember current play position to use
the correct note postitions on NoteOff events (play position might have wrapped around in the meantime due to looppoints or end 
of BB track) (closes #2486299, #2486203)



git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2048 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-19 13:39:42 +00:00
Tobias Doerffel
1102f03fde reverted rev 2037 as we have custom changes in this file (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2044 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-14 17:35:24 +00:00
Tobias Doerffel
c5d01d5e0d stable backport:
* added missing slot declaration for abortFreeze(), fixes lockup when freezing pattern (closes #2530320)
* update patternView after freezing
* fixed drawing of frozen pattern



git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2042 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-13 23:36:32 +00:00
Tobias Doerffel
e5dddeffb0 stable backport:
* when resampling whole sampleBuffer, set end_of_input = 1 in libsamplerate data struct - fixes lots of zero samples at the end of output buffer (closes #2531452)
* coding style fixes
* removed obsolete save/restore of EOF-property in libsample rate data struct when resampling successively (always use 0)



git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2040 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-13 16:37:15 +00:00
Tobias Doerffel
ab180ad254 integrated latest libsamplerate (0.1.6) which is both faster and more reliable (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2038 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-13 16:31:01 +00:00
Tobias Doerffel
e867071e43 disable output monitor per default and show click-hint (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2035 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-13 14:55:46 +00:00
Tobias Doerffel
bc2bf0e30b disable output monitor per default and show click-hint (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2034 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-13 14:54:54 +00:00
Tobias Doerffel
4db2ef1f7d reverted some of the changes from 2008-11-10 which caused distorted graphics when running LMMS with Qt 4.5 (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2031 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-13 11:33:04 +00:00
Tobias Doerffel
95df8100a2 various UI related backports from trunk
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2027 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-13 00:07:20 +00:00
Tobias Doerffel
12b07484aa reflect recent changes to MinGW cross compiling environment (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2026 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-12 23:34:20 +00:00
Tobias Doerffel
fa6e5be636 update patch after loading settings (closes #2486372) (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2024 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-12 23:25:49 +00:00
Tobias Doerffel
84f3ecf76b ensure, cursor is never NULL when painting it in paintEvent()
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2021 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-12 22:53:07 +00:00
Tobias Doerffel
a4ba618828 do not load samples bigger than 100 MB (closes #2458375) (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2019 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-12 22:18:07 +00:00
Tobias Doerffel
83ce3c21b4 integrated pitanga's patch to fix unquantized BB dragging in song editor. Changed ctrl modifier to alt to be consistent (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2009 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-05 13:24:19 +00:00
Tobias Doerffel
48990656b9 integrated pitanga's patch to fix unquantized BB dragging in song editor. Changed ctrl modifier to alt to be consistent (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2008 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-05 13:23:32 +00:00
Tobias Doerffel
d3e6f5a348 better workaround for optimizer bug in GCC >= 4.3 (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2006 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-05 13:19:18 +00:00
Tobias Doerffel
0d90ac3176 cleanups (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2005 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-05 13:18:28 +00:00
Tobias Doerffel
48fe96c9ac added missing header for compilation with GCC 4.4
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2004 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-05 13:17:50 +00:00
Tobias Doerffel
1ffe1c0733 simplified formulas for calculating envelope array resulting in about 3x performance with traditional FPU code; loops now can be vectorized by GCC 4.4
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@2003 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-05 13:17:21 +00:00
Tobias Doerffel
aa575bca83 fixed bug: you can use shift+left to move notes past the beginning (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@1997 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-05 09:06:58 +00:00
Tobias Doerffel
b3c9bf011b reworked mixer-threads (synchronization, realization of jobqueue etc.) which results in a much better performance and stability
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@1996 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-02-05 09:03:13 +00:00
Tobias Doerffel
8b3d3f33a7 stable backport of various fixes from trunk
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@1972 0778d3d1-df1d-0410-868b-ea421aaaa00d
2009-01-27 00:21:37 +00:00
Tobias Doerffel
4fefc16f4b fixed plugins/ directory when updating localization file (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@1967 0778d3d1-df1d-0410-868b-ea421aaaa00d
2008-12-22 17:51:51 +00:00
Tobias Doerffel
e1403ee10b in FL_EffectChannel initialize isMuted member - fixes muted FX channels when importing older FLP files (stable backport)
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms/stable-0.4@1965 0778d3d1-df1d-0410-868b-ea421aaaa00d
2008-12-22 16:44:36 +00:00
49 changed files with 1731 additions and 592 deletions

View File

@@ -15,7 +15,7 @@ INCLUDE(FindPkgConfig)
SET(VERSION_MAJOR "0")
SET(VERSION_MINOR "4")
SET(VERSION_PATCH "2")
SET(VERSION_PATCH "3")
#SET(VERSION_SUFFIX "")
SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
IF(VERSION_SUFFIX)
@@ -29,7 +29,7 @@ INCLUDE(DetectMachine)
IF(LMMS_HOST_X86_64)
SET(STRIP /opt/mingw64/bin/x86_64-pc-mingw32-strip)
ELSE(LMMS_HOST_X86_64)
SET(STRIP /opt/mingw/bin/i586-mingw32-strip)
SET(STRIP /opt/mingw32/bin/i586-pc-mingw32-strip)
ENDIF(LMMS_HOST_X86_64)
OPTION(WANT_ALSA "Include ALSA (Advanced Linux Sound Architecture) support" ON)
@@ -95,6 +95,14 @@ SET(QT_MIN_VERSION "4.3.0")
FIND_PACKAGE(Qt4 REQUIRED)
SET(QT_USE_QTXML 1)
EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_TRANSLATIONS" OUTPUT_VARIABLE QT_TRANSLATIONS_DIR)
IF(LMMS_BUILD_WIN32)
SET(QT_TRANSLATIONS_DIR "/opt/mingw32/share/qt4/translations/")
# hack to allow making moc.exe a symlink to native moc-binary in compatible version
SET(QT_MOC_EXECUTABLE ${QT_BINARY_DIR}/moc.exe)
ENDIF(LMMS_BUILD_WIN32)
IF(LMMS_BUILD_WIN64)
SET(QT_TRANSLATIONS_DIR "/opt/mingw64/share/qt4/translations/")
ENDIF(LMMS_BUILD_WIN64)
IF(EXISTS "${QT_TRANSLATIONS_DIR}")
MESSAGE("-- Found Qt translations in ${QT_TRANSLATIONS_DIR}")
ADD_DEFINITIONS(-D'QT_TRANSLATIONS_DIR="${QT_TRANSLATIONS_DIR}"')
@@ -148,7 +156,7 @@ IF(WANT_SDL)
SET(STATUS_SDL "OK")
ELSE(SDL_FOUND)
SET(STATUS_SDL "not found, please install libsdl1.2-dev (or similiar) "
"if your require SDL support")
"if you require SDL support")
ENDIF(SDL_FOUND)
ENDIF(WANT_SDL)
IF(NOT LMMS_HAVE_SDL)
@@ -169,7 +177,7 @@ IF(WANT_STK)
ELSE(STK_FOUND)
SET(STK_INCLUDE_DIR "")
SET(STATUS_STK "not found, please install libstk0-dev (or similiar) "
"if your require the Vibed Instrument")
"if you require the Vibed Instrument")
ENDIF(STK_FOUND)
ENDIF(WANT_STK)
@@ -182,7 +190,7 @@ ENDIF(WANT_STK)
# SET(STATUS_PORTAUDIO "OK")
# ELSE(PORTAUDIO_FOUND)
# SET(STATUS_PORTAUDIO "not found, please install libportaudio-dev (or similiar, version >= 1.8) "
# "if your require Portaudio support")
# "if you require Portaudio support")
# ENDIF(PORTAUDIO_FOUND)
#ENDIF(WANT_PORTAUDIO)
IF(NOT LMMS_HAVE_PORTAUDIO)
@@ -199,7 +207,7 @@ IF(WANT_PULSEAUDIO)
SET(STATUS_PULSEAUDIO "OK")
ELSE(PULSEAUDIO_FOUND)
SET(STATUS_PULSEAUDIO "not found, please install libpulse-dev (or similiar) "
"if your require PulseAudio support")
"if you require PulseAudio support")
ENDIF(PULSEAUDIO_FOUND)
ENDIF(WANT_PULSEAUDIO)
IF(NOT LMMS_HAVE_PULSEAUDIO)
@@ -317,7 +325,7 @@ ENDIF(LMMS_BUILD_WIN32)
# check for libsamplerate
IF(WANT_SYSTEM_SR)
PKG_CHECK_MODULES(SAMPLERATE samplerate>=0.1.3)
PKG_CHECK_MODULES(SAMPLERATE samplerate>=0.1.6)
IF(SAMPLERATE_FOUND)
SET(LMMS_HAVE_SAMPLERATE TRUE)
ENDIF(SAMPLERATE_FOUND)
@@ -392,7 +400,7 @@ IF(WIN32)
IF(LMMS_HOST_X86_64)
SET(WINDRES /opt/mingw64/bin/x86_64-pc-mingw32-windres)
ELSE(LMMS_HOST_X86_64)
SET(WINDRES /opt/mingw/bin/i586-mingw32-windres)
SET(WINDRES /opt/mingw32/bin/i586-pc-mingw32-windres)
ENDIF(LMMS_HOST_X86_64)
ADD_CUSTOM_COMMAND(OUTPUT ${WINRC}
COMMAND ${WINDRES}
@@ -433,7 +441,7 @@ IF(LMMS_BUILD_WIN32)
IF(LMMS_BUILD_WIN64)
INSTALL(FILES /opt/mingw64/bin/QtCore4.dll /opt/mingw64/bin/QtGui4.dll /opt/mingw64/bin/QtXml4.dll /opt/mingw64/bin/libsndfile-1.dll /opt/mingw64/bin/libvorbis-0.dll /opt/mingw64/bin/libvorbisenc-2.dll /opt/mingw64/bin/libvorbisfile-3.dll /opt/mingw64/bin/libogg-0.dll /opt/mingw64/bin/libfluidsynth-1.dll /opt/mingw64/bin/libfftw3f-3.dll /opt/mingw64/bin/SDL.dll DESTINATION .)
ELSE(LMMS_BUILD_WIN64)
INSTALL(FILES /opt/mingw/bin/QtCore4.dll /opt/mingw/bin/QtGui4.dll /opt/mingw/bin/QtXml4.dll /opt/mingw/bin/libz.dll /opt/mingw/bin/libsndfile-1.dll /opt/mingw/bin/libvorbis-0.dll /opt/mingw/bin/libvorbisenc-2.dll /opt/mingw/bin/libvorbisfile-3.dll /opt/mingw/bin/libogg-0.dll /opt/mingw/bin/libfluidsynth-1.dll /opt/mingw/bin/libfftw3f-3.dll /opt/mingw/bin/SDL.dll /opt/mingw/i586-mingw32/bin/mingwm10.dll DESTINATION .)
INSTALL(FILES /opt/mingw32/bin/QtCore4.dll /opt/mingw32/bin/QtGui4.dll /opt/mingw32/bin/QtXml4.dll /opt/mingw32/bin/libz.dll /opt/mingw32/bin/libsndfile-1.dll /opt/mingw32/bin/libvorbis-0.dll /opt/mingw32/bin/libvorbisenc-2.dll /opt/mingw32/bin/libvorbisfile-3.dll /opt/mingw32/bin/libogg-0.dll /opt/mingw32/bin/libfluidsynth-1.dll /opt/mingw32/bin/libfftw3f-3.dll /opt/mingw32/bin/SDL.dll /opt/mingw32/i586-pc-mingw32/bin/mingwm10.dll DESTINATION .)
ENDIF(LMMS_BUILD_WIN64)
ELSE(LMMS_BUILD_WIN32)
INSTALL(TARGETS lmms RUNTIME DESTINATION bin)
@@ -450,7 +458,7 @@ FOREACH(_ts_file ${lmms_LOCALES})
STRING(REPLACE "${CMAKE_SOURCE_DIR}/data/locale/" "" _ts_target "${_ts_file}")
STRING(REPLACE ".ts" ".qm" _qm_file "${_ts_file}")
STRING(REPLACE ".ts" ".qm" _qm_target "${_ts_target}")
ADD_CUSTOM_TARGET(${_ts_target} COMMAND ${QT_LUPDATE_EXECUTABLE} ${lmms_SOURCES} `find plugins/ -type f -name '*.cpp'` -ts ${_ts_file})
ADD_CUSTOM_TARGET(${_ts_target} COMMAND ${QT_LUPDATE_EXECUTABLE} ${lmms_SOURCES} `find ${CMAKE_SOURCE_DIR}/plugins/ -type f -name '*.cpp'` -ts ${_ts_file})
ADD_CUSTOM_TARGET(${_qm_target} COMMAND ${QT_LRELEASE_EXECUTABLE} ${_ts_file} -qm ${_qm_file})
LIST(APPEND ts_targets "${_ts_target}")
LIST(APPEND qm_targets "${_qm_target}")
@@ -519,21 +527,21 @@ ADD_CUSTOM_TARGET(win32-pkg
COMMAND cp plugins/ladspa_effect/caps/caps.dll tmp/lmms/plugins/ladspa/
COMMAND cp plugins/ladspa_effect/tap/tap*.dll tmp/lmms/plugins/ladspa/
COMMAND cd data && make DESTDIR=${CMAKE_BINARY_DIR}/tmp/lmms/ install
COMMAND mv tmp/lmms/opt/mingw/share/lmms/* tmp/lmms/data/ && rm -rf tmp/lmms/opt
COMMAND cp /opt/mingw/bin/QtCore4.dll tmp/lmms
COMMAND cp /opt/mingw/bin/QtGui4.dll tmp/lmms
COMMAND cp /opt/mingw/bin/QtXml4.dll tmp/lmms
COMMAND cp /opt/mingw/bin/libz.dll tmp/lmms
COMMAND cp /opt/mingw/bin/libsndfile-1.dll tmp/lmms
COMMAND cp /opt/mingw/bin/libvorbis*.dll tmp/lmms
COMMAND cp /opt/mingw/bin/libogg-0.dll tmp/lmms
COMMAND cp /opt/mingw/bin/libfluidsynth-1.dll tmp/lmms
COMMAND cp /opt/mingw/bin/libfftw3f-3.dll tmp/lmms
COMMAND cp /opt/mingw/bin/SDL.dll tmp/lmms
COMMAND cp /opt/mingw/i586-mingw32/bin/mingwm10.dll tmp/lmms
COMMAND mv tmp/lmms/opt/mingw32/share/lmms/* tmp/lmms/data/ && rm -rf tmp/lmms/opt
COMMAND cp /opt/mingw32/bin/QtCore4.dll tmp/lmms
COMMAND cp /opt/mingw32/bin/QtGui4.dll tmp/lmms
COMMAND cp /opt/mingw32/bin/QtXml4.dll tmp/lmms
COMMAND cp /opt/mingw32/bin/libz.dll tmp/lmms
COMMAND cp /opt/mingw32/bin/libsndfile-1.dll tmp/lmms
COMMAND cp /opt/mingw32/bin/libvorbis*.dll tmp/lmms
COMMAND cp /opt/mingw32/bin/libogg-0.dll tmp/lmms
COMMAND cp /opt/mingw32/bin/libfluidsynth-1.dll tmp/lmms
COMMAND cp /opt/mingw32/bin/libfftw3f-3.dll tmp/lmms
COMMAND cp /opt/mingw32/bin/SDL.dll tmp/lmms
COMMAND cp /opt/mingw32/i586-mingw32/bin/mingwm10.dll tmp/lmms
COMMAND cp -L ${CMAKE_SOURCE_DIR}/COPYING tmp/lmms/LICENSE.TXT
COMMAND cp -L ${CMAKE_SOURCE_DIR}/README tmp/lmms/README.TXT
COMMAND /opt/mingw/bin/i586-mingw32-strip tmp/lmms/lmms.exe tmp/lmms/plugins/*.dll tmp/lmms/plugins/ladspa/*.dll
COMMAND /opt/mingw32/bin/i586-pc-mingw32-strip tmp/lmms/lmms.exe tmp/lmms/plugins/*.dll tmp/lmms/plugins/ladspa/*.dll
COMMAND mv tmp/lmms tmp/lmms-${VERSION}
COMMAND cd tmp && zip -r -9 ../lmms-${VERSION}-bin-win32.zip lmms-${VERSION}/*
COMMAND rm -rf tmp

169
ChangeLog
View File

@@ -1,3 +1,172 @@
2009-02-23 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* README:
* CMakeLists.txt:
made 0.4.3 release
* include/atomic_int.h:
- fixed typo
- added copy constructor implementation for AtomicInt class - fixes
build failure with Qt < 4.4.0
* CMakeLists.txt:
fixed typos
* cmake/modules/FindSTK.cmake:
* CMakeLists.txt:
reflect changes in MinGW crosscompiling environment
2009-02-19 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* include/fade_button.h:
* src/gui/widgets/fade_button.cpp:
rewrote timing of fading animation for not postponing updates of
hidden fadeButton until it becomes visible
* src/gui/widgets/automatable_button.cpp:
* src/core/track.cpp:
make sure all buttons in trackOperationsWidget have focus-policy
set to Qt::NoFocus in order to make space play song even if you clicked
e.g. a mute-button (closes #2486211)
* include/note.h:
* src/core/note.cpp:
- coding style fixes
- improved handling of shared detuningHelper object
* include/instrument_track.h:
* include/piano_roll.h:
* src/gui/piano_roll.cpp:
* src/gui/song_editor.cpp:
* src/tracks/instrument_track.cpp:
fixed various bugs regarding recording:
- once recording has been started, stop it as soon as playMode of song
changes or similiar things happen (closes #2486341)
- fixed broken record-accompany in most use-cases other than using
record-while-playing-song by also tracking NoteOn events and remember
current play position to use the correct note postitions on NoteOff
events (play position might have wrapped around in the meantime due
to looppoints or end of BB track) (closes #2486299, #2486203)
- move timeLine marker in Piano Roll and autoscroll when recording while
playing song (closes #2486334)
2009-02-14 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* src/3rdparty/samplerate/samplerate.h:
reverted rev 2037 as we have custom changes in this file
2009-02-13 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* include/pattern.h:
* src/tracks/pattern.cpp:
- added missing slot declaration for abortFreeze(), fixes lockup when
freezing pattern (closes #2530320)
- update patternView after freezing
- fixed drawing of frozen pattern
* include/sample_buffer.h:
* src/core/sample_buffer.cpp:
- when resampling whole sampleBuffer, set end_of_input = 1 in
libsamplerate data struct - fixes lots of zero samples at the end
of output buffer (closes #2531452)
- coding style fixes
- removed obsolete save/restore of EOF-property in libsample rate
data struct when resampling successively (always use 0)
* src/3rdparty/samplerate/src_linear.c:
* src/3rdparty/samplerate/samplerate.h:
* src/3rdparty/samplerate/src_sinc.c:
* src/3rdparty/samplerate/src_zoh.c:
* src/3rdparty/samplerate/samplerate.c:
* CMakeLists.txt:
integrated latest libsamplerate which is both faster and more reliable
* src/gui/widgets/visualization_widget.cpp:
disable output monitor per default and show click-hint
2009-02-12 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* include/group_box.h:
* src/gui/widgets/effect_rack_view.cpp:
backport: manage effectRackView with a QVBoxLayout
* src/gui/widgets/controller_rack_view.cpp:
* src/gui/widgets/effect_rack_view.cpp:
backport: prevent Horizontal bars from appearing in some cases
* cmake/modules/Win32Toolchain.cmake:
reflect recent changes to MinGW cross compiling environment
* plugins/sf2_player/sf2_player.cpp:
update patch after loading settings (closes #2486372)
* src/gui/piano_roll.cpp:
ensure, cursor is never NULL when painting it in paintEvent()
* src/core/sample_buffer.cpp:
do not load samples bigger than 100 MB (closes #2458375)
2009-02-05 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* plugins/ladspa_effect/caps/dsp/Eq.h:
better workaround for optimizer bug in GCC >= 4.3
* plugins/sid/sid_instrument.cpp:
* plugins/flp_import/unrtf.cpp:
* src/core/track.cpp:
added missing header for compilation with GCC 4.4
* include/pattern.h:
* src/tracks/pattern.cpp:
cleanups
* src/core/envelope_and_lfo_parameters.cpp:
- simplified formulas for calculating envelope array resulting in about
3x performance with traditional FPU code
- loops now can be vectorized by GCC 4.4
* include/atomic_int.h:
* include/audio_port.h:
* include/mixer.h:
* src/core/mixer.cpp:
reworked mixer-threads (synchronization, realization of jobqueue etc.)
which results in a much better performance and stability
2009-02-04 Andrew Kelley <superjoe30/at/gmail/dot/com>
* src/gui/piano_roll.cpp:
fixed bug: you can use shift+left to move notes past the beginning
2009-02-01 Andrew Kelley <superjoe30/at/gmail/dot/com>
* src/core/track.cpp:
integrated pitanga's patch to fix unquantized BB dragging in
song editor. Changed ctrl modifier to alt to be consistent.
2009-01-25 Paul Giblock <drfaygo/at/gmail/dot/com>
* src/tracks/bb_track.cpp:
Integrate broken BB-clone bug from pitanga
2009-01-25 Paul Giblock <drfaygo/at/gmail/dot/com>
* src/gui/widgets/knob.cpp:
Fix infinite recursion on Mac OSX
* plugins/flp_import/unrtf/html.c:
* plugins/flp_import/unrtf/output.h:
* plugins/flp_import/unrtf/convert.c:
Avoid compile warnings
2008-12-22 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* CMakeLists.txt:
fixed plugins/ directory when updating localization file
* plugins/flp_import/flp_import.cpp:
in FL_EffectChannel initialize isMuted member - fixes muted FX channels
when importing older FLP files
2008-12-19 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* CMakeLists.txt:

4
README
View File

@@ -1,7 +1,7 @@
Linux MultiMedia Studio 0.4.2
Linux MultiMedia Studio 0.4.3
==============================
Copyright (c) 2004-2008 by LMMS-developers
Copyright (c) 2004-2009 by LMMS-developers
This program is free software; you can redistribute it and/or modify

View File

@@ -1,6 +1,6 @@
FIND_PATH(STK_INCLUDE_DIR Stk.h /usr/include/stk /usr/local/include/stk ${CMAKE_INSTALL_PREFIX}/include/stk)
FIND_PATH(STK_INCLUDE_DIR Stk.h /usr/include/stk /usr/local/include/stk ${CMAKE_INSTALL_PREFIX}/include/stk ${CMAKE_FIND_ROOT_PATH}/include/stk)
FIND_LIBRARY(STK_LIBRARY NAMES stk PATH /usr/lib /usr/local/lib ${CMAKE_INSTALL_PREFIX}/lib)
FIND_LIBRARY(STK_LIBRARY NAMES stk PATH /usr/lib /usr/local/lib ${CMAKE_INSTALL_PREFIX}/lib ${CMAKE_FIND_ROOT_PATH}/lib)
IF (STK_INCLUDE_DIR AND STK_LIBRARY)
SET(STK_FOUND TRUE)

View File

@@ -4,16 +4,16 @@ SET(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_SYSTEM_PROCESSOR i686)
SET(CMAKE_INSTALL_PREFIX /opt/mingw)
SET(CMAKE_INSTALL_PREFIX /opt/mingw32)
SET(CC_PREFIX /opt/mingw)
SET(CC_PREFIX /opt/mingw32)
# specify the cross compiler
SET(CMAKE_C_COMPILER ${CC_PREFIX}/bin/i586-mingw32-gcc)
SET(CMAKE_CXX_COMPILER ${CC_PREFIX}/bin/i586-mingw32-g++)
SET(CMAKE_C_COMPILER ${CC_PREFIX}/bin/i586-pc-mingw32-gcc)
SET(CMAKE_CXX_COMPILER ${CC_PREFIX}/bin/i586-pc-mingw32-g++)
# where is the target environment
SET(CMAKE_FIND_ROOT_PATH /opt/mingw)
SET(CMAKE_FIND_ROOT_PATH /opt/mingw32)
SET(QT_BINARY_DIR ${CC_PREFIX}/bin)
SET(QT_LIBRARY_DIR ${CC_PREFIX}/lib)

103
include/atomic_int.h Executable file
View File

@@ -0,0 +1,103 @@
/*
* atomic_int.h - fallback AtomicInt class when Qt is too old
*
* Copyright (c) 2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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 (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef _ATOMIC_INT_H
#define _ATOMIC_INT_H
#include <QtCore/QMutex>
#if QT_VERSION >= 0x040400
typedef QAtomicInt AtomicInt;
#else
// implement our own (slow) QAtomicInt class when on old Qt
class AtomicInt
{
public:
inline AtomicInt( int _value = 0 ) :
m_value( _value ),
m_lock()
{
}
inline AtomicInt( const AtomicInt & _copy ) :
m_value( _copy.m_value ),
m_lock()
{
}
inline int fetchAndStoreOrdered( int _newVal )
{
m_lock.lock();
const int oldVal = m_value;
m_value = _newVal;
m_lock.unlock();
return oldVal;
}
inline int fetchAndAddOrdered( int _add )
{
m_lock.lock();
const int oldVal = m_value;
m_value += _add;
m_lock.unlock();
return oldVal;
}
inline AtomicInt & operator=( const AtomicInt & _copy )
{
m_lock.lock();
m_value = _copy.m_value;
m_lock.unlock();
return *this;
}
inline AtomicInt & operator=( int _value )
{
m_lock.lock();
m_value = _value;
m_lock.unlock();
return *this;
}
inline operator int() const
{
return m_value;
}
private:
volatile int m_value;
QMutex m_lock;
} ;
#endif
#endif

View File

@@ -1,7 +1,7 @@
/*
* audio_port.h - base-class for objects providing sound at a port
*
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -136,7 +136,7 @@ private:
friend class mixer;
friend class mixerWorkerThread;
friend class MixerWorkerThread;
} ;

View File

@@ -1,7 +1,7 @@
/*
* fade_button.h - declaration of class fadeButton
*
* Copyright (c) 2005-2007 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -26,6 +26,7 @@
#ifndef _FADE_BUTTON_H
#define _FADE_BUTTON_H
#include <QtCore/QTime>
#include <QtGui/QAbstractButton>
#include <QtGui/QColor>
@@ -42,7 +43,6 @@ public:
public slots:
void activate( void );
void reset( void );
protected:
@@ -51,7 +51,7 @@ protected:
private:
float m_state;
QTime m_stateTimer;
QColor m_normalColor;
QColor m_activatedColor;

View File

@@ -39,7 +39,7 @@ class groupBox : public QWidget, public boolModelView
{
Q_OBJECT
public:
groupBox( const QString & _caption, QWidget * _parent );
groupBox( const QString & _caption, QWidget * _parent = NULL );
virtual ~groupBox();
virtual void modelChanged( void );

View File

@@ -2,7 +2,7 @@
* instrument_track.h - declaration of class instrumentTrack, a track + window
* which holds an instrument-plugin
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -185,7 +185,8 @@ public:
signals:
void instrumentChanged( void );
void newNote( void );
void noteDone( const note & _n );
void noteOn( const note & _n );
void noteOff( const note & _n );
void nameChanged( void );

View File

@@ -1,7 +1,7 @@
/*
* mixer.h - audio-device-independent mixer for LMMS
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -40,9 +40,9 @@
#include <QtCore/QMutex>
#include <QtCore/QSemaphore>
#include <QtCore/QThread>
#include <QtCore/QVector>
#include <QtCore/QWaitCondition>
#include "lmms_basics.h"
@@ -73,7 +73,7 @@ const Octaves BaseOctave = DefaultOctave;
#include "play_handle.h"
class mixerWorkerThread;
class MixerWorkerThread;
class EXPORT mixer : public QObject
@@ -438,10 +438,9 @@ private:
bool m_newBuffer[SURROUND_CHANNELS];
int m_cpuLoad;
QVector<mixerWorkerThread *> m_workers;
QVector<MixerWorkerThread *> m_workers;
int m_numWorkers;
QSemaphore m_queueReadySem;
QSemaphore m_workersDoneSem;
QWaitCondition m_queueReadyWaitCond;
playHandleVector m_playHandles;
@@ -469,7 +468,7 @@ private:
friend class engine;
friend class mixerWorkerThread;
friend class MixerWorkerThread;
} ;

View File

@@ -2,7 +2,7 @@
* note.h - declaration of class note which contains all informations about a
* note + definitions of several constants and enums
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -119,27 +119,27 @@ public:
// using qSort
return (bool) ((int) ( *lhs ).pos() < (int) ( *rhs ).pos());
}
inline bool selected( void ) const
{
return m_selected;
}
inline int oldKey( void ) const
{
return m_oldKey;
}
inline midiTime oldPos( void ) const
{
return m_oldPos;
}
inline midiTime oldLength( void ) const
{
return m_oldLength;
}
inline bool isPlaying( void ) const
{
return m_isPlaying;
@@ -153,12 +153,12 @@ public:
inline const midiTime & length( void ) const
{
return( m_length );
return m_length;
}
inline const midiTime & pos( void ) const
{
return( m_pos );
return m_pos;
}
inline midiTime pos( midiTime _base_pos ) const
@@ -169,34 +169,34 @@ public:
inline int key( void ) const
{
return( m_key );
return m_key;
}
inline volume getVolume( void ) const
{
return( m_volume );
return m_volume;
}
inline panning getPanning( void ) const
{
return( m_panning );
return m_panning;
}
static QString classNodeName( void )
{
return( "note" );
return "note";
}
inline virtual QString nodeName( void ) const
{
return( classNodeName() );
return classNodeName();
}
static midiTime quantized( const midiTime & _m, const int _q_grid );
detuningHelper * detuning( void ) const
{
return( m_detuning );
return m_detuning;
}
void editDetuningPattern( void );

View File

@@ -2,7 +2,7 @@
* pattern.h - declaration of class pattern, which contains all informations
* about a pattern
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -133,23 +133,18 @@ public:
using model::dataChanged;
void printNotes( void ); // for debugging purposes
protected:
void ensureBeatNotes( void );
void updateBBTrack( void );
void abortFreeze( void );
protected slots:
void clear( void );
void freeze( void );
void unfreeze( void );
void abortFreeze( void );
void changeTimeSignature( void );

View File

@@ -2,7 +2,7 @@
* piano_roll.h - declaration of class pianoRoll which is a window where you
* can set and edit notes in an easy way
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008 Andrew Kelley <superjoe30/at/gmail/dot/com>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
@@ -34,6 +34,7 @@
#include "serializing_object.h"
#include "note.h"
#include "lmms_basics.h"
#include "song.h"
class QPainter;
@@ -56,6 +57,11 @@ class pianoRoll : public QWidget, public serializingObject
public:
void setCurrentPattern( pattern * _new_pattern );
inline void stopRecording( void )
{
m_recording = false;
}
inline bool isRecording( void ) const
{
return m_recording;
@@ -71,6 +77,8 @@ public:
return m_pattern != NULL;
}
song::PlayModes desiredPlayModeForAccompany( void ) const;
int quantization( void ) const;
@@ -110,7 +118,8 @@ protected slots:
void recordAccompany( void );
void stop( void );
void recordNote( const note & _n );
void startRecordNote( const note & _n );
void finishRecordNote( const note & _n );
void horScrolled( int _new_pos );
void verScrolled( int _new_pos );
@@ -126,6 +135,7 @@ protected slots:
void deleteSelectedNotes( void );
void updatePosition( const midiTime & _t );
void updatePositionAccompany( const midiTime & _t );
void zoomingChanged( void );
void quantizeChanged( void );
@@ -175,6 +185,8 @@ private:
pianoRoll( const pianoRoll & );
virtual ~pianoRoll();
void autoScroll( const midiTime & _t );
midiTime newNoteLen( void ) const;
void shiftPos(int amount);
@@ -241,6 +253,7 @@ private:
midiTime m_currentPosition;
bool m_recording;
QList<note> m_recordingNotes;
note * m_currentNote;
actions m_action;

View File

@@ -1,7 +1,7 @@
/*
* sample_buffer.h - container-class sampleBuffer
*
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -57,7 +57,6 @@ public:
f_cnt_t m_frameIndex;
const bool m_varyingPitch;
SRC_STATE * m_resamplingData;
int m_eof;
friend class sampleBuffer;
@@ -86,17 +85,17 @@ public:
inline const QString & audioFile( void ) const
{
return( m_audioFile );
return m_audioFile;
}
inline f_cnt_t startFrame( void ) const
{
return( m_startFrame );
return m_startFrame;
}
inline f_cnt_t endFrame( void ) const
{
return( m_endFrame );
return m_endFrame;
}
void setLoopStartFrame( f_cnt_t _start )
@@ -115,22 +114,22 @@ public:
inline f_cnt_t frames( void ) const
{
return( m_frames );
return m_frames;
}
inline float amplification( void ) const
{
return( m_amplification );
return m_amplification;
}
inline bool reversed( void ) const
{
return( m_reversed );
return m_reversed;
}
inline float frequency( void ) const
{
return( m_frequency );
return m_frequency;
}
inline void setFrequency( float _freq )
@@ -149,7 +148,7 @@ public:
inline const sampleFrame * data( void ) const
{
return( m_data );
return m_data;
}
QString openAudioFile( void ) const;
@@ -166,8 +165,8 @@ public:
const sample_rate_t _src_sr,
const sample_rate_t _dst_sr )
{
return( resample( _buf->m_data, _buf->m_frames, _src_sr,
_dst_sr ) );
return resample( _buf->m_data, _buf->m_frames, _src_sr,
_dst_sr );
}
void normalizeSampleRate( const sample_rate_t _src_sr,
@@ -182,7 +181,7 @@ public:
// sample_t waveSample = linearInterpolate( m_data[f1][0],
// m_data[f2][0],
// fraction( frame ) );
// return( waveSample );
// return waveSample;
// Fast implementation
const float frame = _sample * m_frames;
@@ -191,7 +190,7 @@ public:
{
f1 += m_frames;
}
return( m_data[f1][0] );
return m_data[f1][0];
}
static QString tryToMakeRelative( const QString & _file );

View File

@@ -509,7 +509,8 @@ struct FL_EffectChannel
{
FL_EffectChannel() :
name(),
volume( DefaultVolume )
volume( DefaultVolume ),
isMuted( false )
{
}

View File

@@ -28,6 +28,8 @@
#include <QtCore/QString>
#include <QtCore/QBuffer>
#include <cstdio>
extern "C"
{

View File

@@ -2399,7 +2399,7 @@ static int cmd_ansi (Word *w, int align, char has_param, int param) {
*=======================================================================*/
static int cmd_ansicpg (Word *w, int align, char has_param, int param) {
int i;
unsigned int i;
for (i = 0; i < sizeof(codepages) / sizeof(CodepageInfo); i ++) {
charset_codepage = &codepages[i];
if (charset_codepage->cp == param) {

View File

@@ -877,7 +877,7 @@ static const char* cp850 [] = {
/* 0xff */ "&nbsp;",
};
#if 1 /* daved - 0.20.3 */
static char * Greek[] =
static const char * Greek[] =
{
/* 0x80 */ "&ccedil;",
/* 0x81 */ "&uuml;",

View File

@@ -285,7 +285,7 @@ typedef struct {
#if 1 /* daved 0.20.3 GREEK font support */
short greek_first_char;
short greek_last_char;
char **greek_translation_table;
const char **greek_translation_table;
#endif
char *(*unisymbol_print) (unsigned short);

View File

@@ -84,14 +84,9 @@ class Eq
{
for (int z = 0; z < 2; ++z)
{
// work-around for buggy optimizer in GCC 4.3
for (int i = 0; i < Bands-1; ++i)
y[z][i] = 0;
y[z][Bands-1] = 0;
memset( y[z], 0, Bands*sizeof( eq_sample ) );
x[z] = 0;
}
for (int i = 0; i < 2; ++i)
x[i] = 0;
}
void init (double fs, double Q)

View File

@@ -236,6 +236,7 @@ void sf2Instrument::loadSettings( const QDomElement & _this )
m_chorusSpeed.loadSettings( _this, "chorusSpeed" );
m_chorusDepth.loadSettings( _this, "chorusDepth" );
updatePatch();
updateGain();
}

View File

@@ -26,6 +26,9 @@
#include <QtGui/QPainter>
#include <QtXml/QDomElement>
#include <cstdio>
#include "sid.h"
#include "sid_instrument.h"

View File

@@ -87,7 +87,8 @@ src_callback_new (src_callback_t func, int converter_type, int channels, int *er
if (error != NULL)
*error = 0 ;
src_state = src_new (converter_type, channels, error) ;
if ((src_state = src_new (converter_type, channels, error)) == NULL)
return NULL ;
src_reset (src_state) ;
@@ -132,16 +133,13 @@ src_process (SRC_STATE *state, SRC_DATA *data)
if (data == NULL)
return SRC_ERR_BAD_DATA ;
/* Check src_ratio is in range. */
if (is_bad_src_ratio (data->src_ratio))
return SRC_ERR_BAD_SRC_RATIO ;
/* And that data_in and data_out are valid. */
if (data->data_in == NULL || data->data_out == NULL)
return SRC_ERR_BAD_DATA_PTR ;
if (data->data_in == NULL)
data->input_frames = 0 ;
/* Check src_ratio is in range. */
if (is_bad_src_ratio (data->src_ratio))
return SRC_ERR_BAD_SRC_RATIO ;
if (data->input_frames < 0)
data->input_frames = 0 ;
@@ -224,9 +222,13 @@ src_callback_read (SRC_STATE *state, double src_ratio, long frames, float *data)
output_frames_gen = 0 ;
while (output_frames_gen < frames)
{
{ /* Use a dummy array for the case where the callback function
** returns without setting the ptr.
*/
float dummy [1] ;
if (src_data.input_frames == 0)
{ float *ptr ;
{ float *ptr = dummy ;
src_data.input_frames = psrc->callback_func (psrc->user_callback_data, &ptr) ;
src_data.data_in = ptr ;

View File

@@ -54,42 +54,42 @@ typedef struct
static int
linear_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
{ LINEAR_DATA *linear ;
{ LINEAR_DATA *priv ;
double src_ratio, input_index, rem ;
int ch ;
if (psrc->private_data == NULL)
return SRC_ERR_NO_PRIVATE ;
linear = (LINEAR_DATA*) psrc->private_data ;
priv = (LINEAR_DATA*) psrc->private_data ;
if (linear->reset)
if (priv->reset)
{ /* If we have just been reset, set the last_value data. */
for (ch = 0 ; ch < linear->channels ; ch++)
linear->last_value [ch] = data->data_in [ch] ;
linear->reset = 0 ;
for (ch = 0 ; ch < priv->channels ; ch++)
priv->last_value [ch] = data->data_in [ch] ;
priv->reset = 0 ;
} ;
linear->in_count = data->input_frames * linear->channels ;
linear->out_count = data->output_frames * linear->channels ;
linear->in_used = linear->out_gen = 0 ;
priv->in_count = data->input_frames * priv->channels ;
priv->out_count = data->output_frames * priv->channels ;
priv->in_used = priv->out_gen = 0 ;
src_ratio = psrc->last_ratio ;
input_index = psrc->last_position ;
/* Calculate samples before first sample in input array. */
while (input_index < 1.0 && linear->out_gen < linear->out_count)
while (input_index < 1.0 && priv->out_gen < priv->out_count)
{
if (linear->in_used + linear->channels * input_index > linear->in_count)
if (priv->in_used + priv->channels * (1.0 + input_index) >= priv->in_count)
break ;
if (linear->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
src_ratio = psrc->last_ratio + linear->out_gen * (data->src_ratio - psrc->last_ratio) / linear->out_count ;
if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ;
for (ch = 0 ; ch < linear->channels ; ch++)
{ data->data_out [linear->out_gen] = (float) (linear->last_value [ch] + input_index *
(data->data_in [ch] - linear->last_value [ch])) ;
linear->out_gen ++ ;
for (ch = 0 ; ch < priv->channels ; ch++)
{ data->data_out [priv->out_gen] = (float) (priv->last_value [ch] + input_index *
(data->data_in [ch] - priv->last_value [ch])) ;
priv->out_gen ++ ;
} ;
/* Figure out the next index. */
@@ -97,50 +97,50 @@ linear_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
} ;
rem = fmod_one (input_index) ;
linear->in_used += linear->channels * lrint (input_index - rem) ;
priv->in_used += priv->channels * lrint (input_index - rem) ;
input_index = rem ;
/* Main processing loop. */
while (linear->out_gen < linear->out_count && linear->in_used + linear->channels * input_index <= linear->in_count)
while (priv->out_gen < priv->out_count && priv->in_used + priv->channels * input_index < priv->in_count)
{
if (linear->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
src_ratio = psrc->last_ratio + linear->out_gen * (data->src_ratio - psrc->last_ratio) / linear->out_count ;
if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ;
if (SRC_DEBUG && linear->in_used < linear->channels && input_index < 1.0)
{ printf ("Whoops!!!! in_used : %ld channels : %d input_index : %f\n", linear->in_used, linear->channels, input_index) ;
if (SRC_DEBUG && priv->in_used < priv->channels && input_index < 1.0)
{ printf ("Whoops!!!! in_used : %ld channels : %d input_index : %f\n", priv->in_used, priv->channels, input_index) ;
exit (1) ;
} ;
for (ch = 0 ; ch < linear->channels ; ch++)
{ data->data_out [linear->out_gen] = (float) (data->data_in [linear->in_used - linear->channels + ch] + input_index *
(data->data_in [linear->in_used + ch] - data->data_in [linear->in_used - linear->channels + ch])) ;
linear->out_gen ++ ;
for (ch = 0 ; ch < priv->channels ; ch++)
{ data->data_out [priv->out_gen] = (float) (data->data_in [priv->in_used - priv->channels + ch] + input_index *
(data->data_in [priv->in_used + ch] - data->data_in [priv->in_used - priv->channels + ch])) ;
priv->out_gen ++ ;
} ;
/* Figure out the next index. */
input_index += 1.0 / src_ratio ;
rem = fmod_one (input_index) ;
linear->in_used += linear->channels * lrint (input_index - rem) ;
priv->in_used += priv->channels * lrint (input_index - rem) ;
input_index = rem ;
} ;
if (linear->in_used > linear->in_count)
{ input_index += (linear->in_used - linear->in_count) / linear->channels ;
linear->in_used = linear->in_count ;
if (priv->in_used > priv->in_count)
{ input_index += (priv->in_used - priv->in_count) / priv->channels ;
priv->in_used = priv->in_count ;
} ;
psrc->last_position = input_index ;
if (linear->in_used > 0)
for (ch = 0 ; ch < linear->channels ; ch++)
linear->last_value [ch] = data->data_in [linear->in_used - linear->channels + ch] ;
if (priv->in_used > 0)
for (ch = 0 ; ch < priv->channels ; ch++)
priv->last_value [ch] = data->data_in [priv->in_used - priv->channels + ch] ;
/* Save current ratio rather then target ratio. */
psrc->last_ratio = src_ratio ;
data->input_frames_used = linear->in_used / linear->channels ;
data->output_frames_gen = linear->out_gen / linear->channels ;
data->input_frames_used = priv->in_used / priv->channels ;
data->output_frames_gen = priv->out_gen / priv->channels ;
return SRC_ERR_NO_ERROR ;
} /* linear_vari_process */
@@ -168,28 +168,25 @@ linear_get_description (int src_enum)
int
linear_set_converter (SRC_PRIVATE *psrc, int src_enum)
{ LINEAR_DATA *linear = NULL ;
{ LINEAR_DATA *priv = NULL ;
if (src_enum != SRC_LINEAR)
return SRC_ERR_BAD_CONVERTER ;
if (psrc->private_data != NULL)
{ linear = (LINEAR_DATA*) psrc->private_data ;
if (linear->linear_magic_marker != LINEAR_MAGIC_MARKER)
{ free (psrc->private_data) ;
psrc->private_data = NULL ;
} ;
{ free (psrc->private_data) ;
psrc->private_data = NULL ;
} ;
if (psrc->private_data == NULL)
{ linear = calloc (1, sizeof (*linear) + psrc->channels * sizeof (float)) ;
if (linear == NULL)
{ priv = calloc (1, sizeof (*priv) + psrc->channels * sizeof (float)) ;
if (priv == NULL)
return SRC_ERR_MALLOC_FAILED ;
psrc->private_data = linear ;
psrc->private_data = priv ;
} ;
linear->linear_magic_marker = LINEAR_MAGIC_MARKER ;
linear->channels = psrc->channels ;
priv->linear_magic_marker = LINEAR_MAGIC_MARKER ;
priv->channels = psrc->channels ;
psrc->const_process = linear_vari_process ;
psrc->vari_process = linear_vari_process ;
@@ -205,15 +202,16 @@ linear_set_converter (SRC_PRIVATE *psrc, int src_enum)
static void
linear_reset (SRC_PRIVATE *psrc)
{ LINEAR_DATA *linear = NULL ;
{ LINEAR_DATA *priv = NULL ;
linear = (LINEAR_DATA*) psrc->private_data ;
if (linear == NULL)
priv = (LINEAR_DATA*) psrc->private_data ;
if (priv == NULL)
return ;
linear->channels = psrc->channels ;
linear->reset = 1 ;
priv->channels = psrc->channels ;
priv->reset = 1 ;
memset (priv->last_value, 0, sizeof (priv->last_value [0]) * priv->channels) ;
memset (linear->last_value, 0, sizeof (linear->last_value [0]) * linear->channels) ;
return ;
} /* linear_reset */

View File

@@ -65,12 +65,16 @@ typedef struct
coeff_t const *coeffs ;
int b_current, b_end, b_real_end, b_len ;
float buffer [1] ;
/* C99 struct flexible array. */
float buffer [] ;
} SINC_FILTER ;
static int sinc_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
static double calc_output (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch) ;
static int sinc_multichan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
static int sinc_hex_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
static int sinc_quad_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
static int sinc_stereo_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
static int sinc_mono_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
static void prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len) ;
@@ -78,9 +82,7 @@ static void sinc_reset (SRC_PRIVATE *psrc) ;
static inline increment_t
double_to_fp (double x)
{ if (sizeof (increment_t) == 8)
return (llrint ((x) * FP_ONE)) ;
return (lrint ((x) * FP_ONE)) ;
{ return (lrint ((x) * FP_ONE)) ;
} /* double_to_fp */
static inline increment_t
@@ -157,11 +159,8 @@ sinc_set_converter (SRC_PRIVATE *psrc, int src_enum)
return SRC_ERR_SHIFT_BITS ;
if (psrc->private_data != NULL)
{ filter = (SINC_FILTER*) psrc->private_data ;
if (filter->sinc_magic_marker != SINC_MAGIC_MARKER)
{ free (psrc->private_data) ;
psrc->private_data = NULL ;
} ;
{ free (psrc->private_data) ;
psrc->private_data = NULL ;
} ;
memset (&temp_filter, 0, sizeof (temp_filter)) ;
@@ -169,8 +168,29 @@ sinc_set_converter (SRC_PRIVATE *psrc, int src_enum)
temp_filter.sinc_magic_marker = SINC_MAGIC_MARKER ;
temp_filter.channels = psrc->channels ;
psrc->const_process = sinc_vari_process ;
psrc->vari_process = sinc_vari_process ;
if (psrc->channels == 1)
{ psrc->const_process = sinc_mono_vari_process ;
psrc->vari_process = sinc_mono_vari_process ;
}
else
if (psrc->channels == 2)
{ psrc->const_process = sinc_stereo_vari_process ;
psrc->vari_process = sinc_stereo_vari_process ;
}
else
if (psrc->channels == 4)
{ psrc->const_process = sinc_quad_vari_process ;
psrc->vari_process = sinc_quad_vari_process ;
}
else
if (psrc->channels == 6)
{ psrc->const_process = sinc_hex_vari_process ;
psrc->vari_process = sinc_hex_vari_process ;
}
else
{ psrc->const_process = sinc_multichan_vari_process ;
psrc->vari_process = sinc_multichan_vari_process ;
} ;
psrc->reset = sinc_reset ;
switch (src_enum)
@@ -248,12 +268,64 @@ sinc_reset (SRC_PRIVATE *psrc)
** Beware all ye who dare pass this point. There be dragons here.
*/
static inline double
calc_output_single (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index)
{ double fraction, left, right, icoeff ;
increment_t filter_index, max_filter_index ;
int data_index, coeff_count, indx ;
/* Convert input parameters into fixed point. */
max_filter_index = int_to_fp (filter->coeff_half_len) ;
/* First apply the left half of the filter. */
filter_index = start_filter_index ;
coeff_count = (max_filter_index - filter_index) / increment ;
filter_index = filter_index + coeff_count * increment ;
data_index = filter->b_current - coeff_count ;
left = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
left += icoeff * filter->buffer [data_index] ;
filter_index -= increment ;
data_index = data_index + 1 ;
}
while (filter_index >= MAKE_INCREMENT_T (0)) ;
/* Now apply the right half of the filter. */
filter_index = increment - start_filter_index ;
coeff_count = (max_filter_index - filter_index) / increment ;
filter_index = filter_index + coeff_count * increment ;
data_index = filter->b_current + 1 + coeff_count ;
right = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
right += icoeff * filter->buffer [data_index] ;
filter_index -= increment ;
data_index = data_index - 1 ;
}
while (filter_index > MAKE_INCREMENT_T (0)) ;
return (left + right) ;
} /* calc_output_single */
static int
sinc_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
sinc_mono_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
{ SINC_FILTER *filter ;
double input_index, src_ratio, count, float_increment, terminate, rem ;
increment_t increment, start_filter_index ;
int half_filter_chan_len, samples_in_hand, ch ;
int half_filter_chan_len, samples_in_hand ;
if (psrc->private_data == NULL)
return SRC_ERR_NO_PRIVATE ;
@@ -318,11 +390,9 @@ sinc_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
start_filter_index = double_to_fp (input_index * float_increment) ;
for (ch = 0 ; ch < filter->channels ; ch++)
{ data->data_out [filter->out_gen] = (float) ((float_increment / filter->index_inc) *
calc_output (filter, increment, start_filter_index, ch)) ;
filter->out_gen ++ ;
} ;
data->data_out [filter->out_gen] = (float) ((float_increment / filter->index_inc) *
calc_output_single (filter, increment, start_filter_index)) ;
filter->out_gen ++ ;
/* Figure out the next index. */
input_index += 1.0 / src_ratio ;
@@ -341,7 +411,709 @@ sinc_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
data->output_frames_gen = filter->out_gen / filter->channels ;
return SRC_ERR_NO_ERROR ;
} /* sinc_vari_process */
} /* sinc_mono_vari_process */
static inline void
calc_output_stereo (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, double scale, float * output)
{ double fraction, left [2], right [2], icoeff ;
increment_t filter_index, max_filter_index ;
int data_index, coeff_count, indx ;
/* Convert input parameters into fixed point. */
max_filter_index = int_to_fp (filter->coeff_half_len) ;
/* First apply the left half of the filter. */
filter_index = start_filter_index ;
coeff_count = (max_filter_index - filter_index) / increment ;
filter_index = filter_index + coeff_count * increment ;
data_index = filter->b_current - filter->channels * coeff_count ;
left [0] = left [1] = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
left [0] += icoeff * filter->buffer [data_index] ;
left [1] += icoeff * filter->buffer [data_index + 1] ;
filter_index -= increment ;
data_index = data_index + 2 ;
}
while (filter_index >= MAKE_INCREMENT_T (0)) ;
/* Now apply the right half of the filter. */
filter_index = increment - start_filter_index ;
coeff_count = (max_filter_index - filter_index) / increment ;
filter_index = filter_index + coeff_count * increment ;
data_index = filter->b_current + filter->channels * (1 + coeff_count) ;
right [0] = right [1] = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
right [0] += icoeff * filter->buffer [data_index] ;
right [1] += icoeff * filter->buffer [data_index + 1] ;
filter_index -= increment ;
data_index = data_index - 2 ;
}
while (filter_index > MAKE_INCREMENT_T (0)) ;
output [0] = scale * (left [0] + right [0]) ;
output [1] = scale * (left [1] + right [1]) ;
} /* calc_output_stereo */
static int
sinc_stereo_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
{ SINC_FILTER *filter ;
double input_index, src_ratio, count, float_increment, terminate, rem ;
increment_t increment, start_filter_index ;
int half_filter_chan_len, samples_in_hand ;
if (psrc->private_data == NULL)
return SRC_ERR_NO_PRIVATE ;
filter = (SINC_FILTER*) psrc->private_data ;
/* If there is not a problem, this will be optimised out. */
if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0]))
return SRC_ERR_SIZE_INCOMPATIBILITY ;
filter->in_count = data->input_frames * filter->channels ;
filter->out_count = data->output_frames * filter->channels ;
filter->in_used = filter->out_gen = 0 ;
src_ratio = psrc->last_ratio ;
/* Check the sample rate ratio wrt the buffer len. */
count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
count /= MIN (psrc->last_ratio, data->src_ratio) ;
/* Maximum coefficientson either side of center point. */
half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
input_index = psrc->last_position ;
float_increment = filter->index_inc ;
rem = fmod_one (input_index) ;
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
input_index = rem ;
terminate = 1.0 / src_ratio + 1e-20 ;
/* Main processing loop. */
while (filter->out_gen < filter->out_count)
{
/* Need to reload buffer? */
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
if (samples_in_hand <= half_filter_chan_len)
{ prepare_data (filter, data, half_filter_chan_len) ;
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
if (samples_in_hand <= half_filter_chan_len)
break ;
} ;
/* This is the termination condition. */
if (filter->b_real_end >= 0)
{ if (filter->b_current + input_index + terminate >= filter->b_real_end)
break ;
} ;
if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ;
float_increment = filter->index_inc * 1.0 ;
if (src_ratio < 1.0)
float_increment = filter->index_inc * src_ratio ;
increment = double_to_fp (float_increment) ;
start_filter_index = double_to_fp (input_index * float_increment) ;
calc_output_stereo (filter, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ;
filter->out_gen += 2 ;
/* Figure out the next index. */
input_index += 1.0 / src_ratio ;
rem = fmod_one (input_index) ;
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
input_index = rem ;
} ;
psrc->last_position = input_index ;
/* Save current ratio rather then target ratio. */
psrc->last_ratio = src_ratio ;
data->input_frames_used = filter->in_used / filter->channels ;
data->output_frames_gen = filter->out_gen / filter->channels ;
return SRC_ERR_NO_ERROR ;
} /* sinc_stereo_vari_process */
static inline void
calc_output_quad (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, double scale, float * output)
{ double fraction, left [4], right [4], icoeff ;
increment_t filter_index, max_filter_index ;
int data_index, coeff_count, indx ;
/* Convert input parameters into fixed point. */
max_filter_index = int_to_fp (filter->coeff_half_len) ;
/* First apply the left half of the filter. */
filter_index = start_filter_index ;
coeff_count = (max_filter_index - filter_index) / increment ;
filter_index = filter_index + coeff_count * increment ;
data_index = filter->b_current - filter->channels * coeff_count ;
left [0] = left [1] = left [2] = left [3] = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
left [0] += icoeff * filter->buffer [data_index] ;
left [1] += icoeff * filter->buffer [data_index + 1] ;
left [2] += icoeff * filter->buffer [data_index + 2] ;
left [3] += icoeff * filter->buffer [data_index + 3] ;
filter_index -= increment ;
data_index = data_index + 4 ;
}
while (filter_index >= MAKE_INCREMENT_T (0)) ;
/* Now apply the right half of the filter. */
filter_index = increment - start_filter_index ;
coeff_count = (max_filter_index - filter_index) / increment ;
filter_index = filter_index + coeff_count * increment ;
data_index = filter->b_current + filter->channels * (1 + coeff_count) ;
right [0] = right [1] = right [2] = right [3] = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
right [0] += icoeff * filter->buffer [data_index] ;
right [1] += icoeff * filter->buffer [data_index + 1] ;
right [2] += icoeff * filter->buffer [data_index + 2] ;
right [3] += icoeff * filter->buffer [data_index + 3] ;
filter_index -= increment ;
data_index = data_index - 4 ;
}
while (filter_index > MAKE_INCREMENT_T (0)) ;
output [0] = scale * (left [0] + right [0]) ;
output [1] = scale * (left [1] + right [1]) ;
output [2] = scale * (left [2] + right [2]) ;
output [3] = scale * (left [3] + right [3]) ;
} /* calc_output_quad */
static int
sinc_quad_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
{ SINC_FILTER *filter ;
double input_index, src_ratio, count, float_increment, terminate, rem ;
increment_t increment, start_filter_index ;
int half_filter_chan_len, samples_in_hand ;
if (psrc->private_data == NULL)
return SRC_ERR_NO_PRIVATE ;
filter = (SINC_FILTER*) psrc->private_data ;
/* If there is not a problem, this will be optimised out. */
if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0]))
return SRC_ERR_SIZE_INCOMPATIBILITY ;
filter->in_count = data->input_frames * filter->channels ;
filter->out_count = data->output_frames * filter->channels ;
filter->in_used = filter->out_gen = 0 ;
src_ratio = psrc->last_ratio ;
/* Check the sample rate ratio wrt the buffer len. */
count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
count /= MIN (psrc->last_ratio, data->src_ratio) ;
/* Maximum coefficientson either side of center point. */
half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
input_index = psrc->last_position ;
float_increment = filter->index_inc ;
rem = fmod_one (input_index) ;
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
input_index = rem ;
terminate = 1.0 / src_ratio + 1e-20 ;
/* Main processing loop. */
while (filter->out_gen < filter->out_count)
{
/* Need to reload buffer? */
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
if (samples_in_hand <= half_filter_chan_len)
{ prepare_data (filter, data, half_filter_chan_len) ;
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
if (samples_in_hand <= half_filter_chan_len)
break ;
} ;
/* This is the termination condition. */
if (filter->b_real_end >= 0)
{ if (filter->b_current + input_index + terminate >= filter->b_real_end)
break ;
} ;
if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ;
float_increment = filter->index_inc * 1.0 ;
if (src_ratio < 1.0)
float_increment = filter->index_inc * src_ratio ;
increment = double_to_fp (float_increment) ;
start_filter_index = double_to_fp (input_index * float_increment) ;
calc_output_quad (filter, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ;
filter->out_gen += 4 ;
/* Figure out the next index. */
input_index += 1.0 / src_ratio ;
rem = fmod_one (input_index) ;
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
input_index = rem ;
} ;
psrc->last_position = input_index ;
/* Save current ratio rather then target ratio. */
psrc->last_ratio = src_ratio ;
data->input_frames_used = filter->in_used / filter->channels ;
data->output_frames_gen = filter->out_gen / filter->channels ;
return SRC_ERR_NO_ERROR ;
} /* sinc_quad_vari_process */
static inline void
calc_output_hex (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, double scale, float * output)
{ double fraction, left [6], right [6], icoeff ;
increment_t filter_index, max_filter_index ;
int data_index, coeff_count, indx ;
/* Convert input parameters into fixed point. */
max_filter_index = int_to_fp (filter->coeff_half_len) ;
/* First apply the left half of the filter. */
filter_index = start_filter_index ;
coeff_count = (max_filter_index - filter_index) / increment ;
filter_index = filter_index + coeff_count * increment ;
data_index = filter->b_current - filter->channels * coeff_count ;
left [0] = left [1] = left [2] = left [3] = left [4] = left [5] = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
left [0] += icoeff * filter->buffer [data_index] ;
left [1] += icoeff * filter->buffer [data_index + 1] ;
left [2] += icoeff * filter->buffer [data_index + 2] ;
left [3] += icoeff * filter->buffer [data_index + 3] ;
left [4] += icoeff * filter->buffer [data_index + 4] ;
left [5] += icoeff * filter->buffer [data_index + 5] ;
filter_index -= increment ;
data_index = data_index + 6 ;
}
while (filter_index >= MAKE_INCREMENT_T (0)) ;
/* Now apply the right half of the filter. */
filter_index = increment - start_filter_index ;
coeff_count = (max_filter_index - filter_index) / increment ;
filter_index = filter_index + coeff_count * increment ;
data_index = filter->b_current + filter->channels * (1 + coeff_count) ;
right [0] = right [1] = right [2] = right [3] = right [4] = right [5] = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
right [0] += icoeff * filter->buffer [data_index] ;
right [1] += icoeff * filter->buffer [data_index + 1] ;
right [2] += icoeff * filter->buffer [data_index + 2] ;
right [3] += icoeff * filter->buffer [data_index + 3] ;
right [4] += icoeff * filter->buffer [data_index + 4] ;
right [5] += icoeff * filter->buffer [data_index + 5] ;
filter_index -= increment ;
data_index = data_index - 6 ;
}
while (filter_index > MAKE_INCREMENT_T (0)) ;
output [0] = scale * (left [0] + right [0]) ;
output [1] = scale * (left [1] + right [1]) ;
output [2] = scale * (left [2] + right [2]) ;
output [3] = scale * (left [3] + right [3]) ;
output [4] = scale * (left [4] + right [4]) ;
output [5] = scale * (left [5] + right [5]) ;
} /* calc_output_hex */
static int
sinc_hex_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
{ SINC_FILTER *filter ;
double input_index, src_ratio, count, float_increment, terminate, rem ;
increment_t increment, start_filter_index ;
int half_filter_chan_len, samples_in_hand ;
if (psrc->private_data == NULL)
return SRC_ERR_NO_PRIVATE ;
filter = (SINC_FILTER*) psrc->private_data ;
/* If there is not a problem, this will be optimised out. */
if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0]))
return SRC_ERR_SIZE_INCOMPATIBILITY ;
filter->in_count = data->input_frames * filter->channels ;
filter->out_count = data->output_frames * filter->channels ;
filter->in_used = filter->out_gen = 0 ;
src_ratio = psrc->last_ratio ;
/* Check the sample rate ratio wrt the buffer len. */
count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
count /= MIN (psrc->last_ratio, data->src_ratio) ;
/* Maximum coefficientson either side of center point. */
half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
input_index = psrc->last_position ;
float_increment = filter->index_inc ;
rem = fmod_one (input_index) ;
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
input_index = rem ;
terminate = 1.0 / src_ratio + 1e-20 ;
/* Main processing loop. */
while (filter->out_gen < filter->out_count)
{
/* Need to reload buffer? */
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
if (samples_in_hand <= half_filter_chan_len)
{ prepare_data (filter, data, half_filter_chan_len) ;
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
if (samples_in_hand <= half_filter_chan_len)
break ;
} ;
/* This is the termination condition. */
if (filter->b_real_end >= 0)
{ if (filter->b_current + input_index + terminate >= filter->b_real_end)
break ;
} ;
if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ;
float_increment = filter->index_inc * 1.0 ;
if (src_ratio < 1.0)
float_increment = filter->index_inc * src_ratio ;
increment = double_to_fp (float_increment) ;
start_filter_index = double_to_fp (input_index * float_increment) ;
calc_output_hex (filter, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ;
filter->out_gen += 6 ;
/* Figure out the next index. */
input_index += 1.0 / src_ratio ;
rem = fmod_one (input_index) ;
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
input_index = rem ;
} ;
psrc->last_position = input_index ;
/* Save current ratio rather then target ratio. */
psrc->last_ratio = src_ratio ;
data->input_frames_used = filter->in_used / filter->channels ;
data->output_frames_gen = filter->out_gen / filter->channels ;
return SRC_ERR_NO_ERROR ;
} /* sinc_hex_vari_process */
static inline void
calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int channels, double scale, float * output)
{ double fraction, icoeff ;
/* The following line is 1999 ISO Standard C. If your compiler complains, get a better compiler. */
double left [channels], right [channels] ;
increment_t filter_index, max_filter_index ;
int data_index, coeff_count, indx, ch ;
/* Convert input parameters into fixed point. */
max_filter_index = int_to_fp (filter->coeff_half_len) ;
/* First apply the left half of the filter. */
filter_index = start_filter_index ;
coeff_count = (max_filter_index - filter_index) / increment ;
filter_index = filter_index + coeff_count * increment ;
data_index = filter->b_current - channels * coeff_count ;
memset (left, 0, sizeof (left)) ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
/*
** Duff's Device.
** See : http://en.wikipedia.org/wiki/Duff's_device
*/
ch = channels ;
do
{
switch (ch % 8)
{ default :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
case 7 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
case 6 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
case 5 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
case 4 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
case 3 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
case 2 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
case 1 :
ch -- ;
left [ch] += icoeff * filter->buffer [data_index + ch] ;
} ;
}
while (ch > 0) ;
filter_index -= increment ;
data_index = data_index + channels ;
}
while (filter_index >= MAKE_INCREMENT_T (0)) ;
/* Now apply the right half of the filter. */
filter_index = increment - start_filter_index ;
coeff_count = (max_filter_index - filter_index) / increment ;
filter_index = filter_index + coeff_count * increment ;
data_index = filter->b_current + channels * (1 + coeff_count) ;
memset (right, 0, sizeof (right)) ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
ch = channels ;
do
{
switch (ch % 8)
{ default :
ch -- ;
right [ch] += icoeff * filter->buffer [data_index + ch] ;
case 7 :
ch -- ;
right [ch] += icoeff * filter->buffer [data_index + ch] ;
case 6 :
ch -- ;
right [ch] += icoeff * filter->buffer [data_index + ch] ;
case 5 :
ch -- ;
right [ch] += icoeff * filter->buffer [data_index + ch] ;
case 4 :
ch -- ;
right [ch] += icoeff * filter->buffer [data_index + ch] ;
case 3 :
ch -- ;
right [ch] += icoeff * filter->buffer [data_index + ch] ;
case 2 :
ch -- ;
right [ch] += icoeff * filter->buffer [data_index + ch] ;
case 1 :
ch -- ;
right [ch] += icoeff * filter->buffer [data_index + ch] ;
} ;
}
while (ch > 0) ;
filter_index -= increment ;
data_index = data_index - channels ;
}
while (filter_index > MAKE_INCREMENT_T (0)) ;
ch = channels ;
do
{
switch (ch % 8)
{ default :
ch -- ;
output [ch] = scale * (left [ch] + right [ch]) ;
case 7 :
ch -- ;
output [ch] = scale * (left [ch] + right [ch]) ;
case 6 :
ch -- ;
output [ch] = scale * (left [ch] + right [ch]) ;
case 5 :
ch -- ;
output [ch] = scale * (left [ch] + right [ch]) ;
case 4 :
ch -- ;
output [ch] = scale * (left [ch] + right [ch]) ;
case 3 :
ch -- ;
output [ch] = scale * (left [ch] + right [ch]) ;
case 2 :
ch -- ;
output [ch] = scale * (left [ch] + right [ch]) ;
case 1 :
ch -- ;
output [ch] = scale * (left [ch] + right [ch]) ;
} ;
}
while (ch > 0) ;
return ;
} /* calc_output_multi */
static int
sinc_multichan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
{ SINC_FILTER *filter ;
double input_index, src_ratio, count, float_increment, terminate, rem ;
increment_t increment, start_filter_index ;
int half_filter_chan_len, samples_in_hand ;
if (psrc->private_data == NULL)
return SRC_ERR_NO_PRIVATE ;
filter = (SINC_FILTER*) psrc->private_data ;
/* If there is not a problem, this will be optimised out. */
if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0]))
return SRC_ERR_SIZE_INCOMPATIBILITY ;
filter->in_count = data->input_frames * filter->channels ;
filter->out_count = data->output_frames * filter->channels ;
filter->in_used = filter->out_gen = 0 ;
src_ratio = psrc->last_ratio ;
/* Check the sample rate ratio wrt the buffer len. */
count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
count /= MIN (psrc->last_ratio, data->src_ratio) ;
/* Maximum coefficientson either side of center point. */
half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
input_index = psrc->last_position ;
float_increment = filter->index_inc ;
rem = fmod_one (input_index) ;
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
input_index = rem ;
terminate = 1.0 / src_ratio + 1e-20 ;
/* Main processing loop. */
while (filter->out_gen < filter->out_count)
{
/* Need to reload buffer? */
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
if (samples_in_hand <= half_filter_chan_len)
{ prepare_data (filter, data, half_filter_chan_len) ;
samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
if (samples_in_hand <= half_filter_chan_len)
break ;
} ;
/* This is the termination condition. */
if (filter->b_real_end >= 0)
{ if (filter->b_current + input_index + terminate >= filter->b_real_end)
break ;
} ;
if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ;
float_increment = filter->index_inc * 1.0 ;
if (src_ratio < 1.0)
float_increment = filter->index_inc * src_ratio ;
increment = double_to_fp (float_increment) ;
start_filter_index = double_to_fp (input_index * float_increment) ;
calc_output_multi (filter, increment, start_filter_index, filter->channels, float_increment / filter->index_inc, data->data_out + filter->out_gen) ;
filter->out_gen += psrc->channels ;
/* Figure out the next index. */
input_index += 1.0 / src_ratio ;
rem = fmod_one (input_index) ;
filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
input_index = rem ;
} ;
psrc->last_position = input_index ;
/* Save current ratio rather then target ratio. */
psrc->last_ratio = src_ratio ;
data->input_frames_used = filter->in_used / filter->channels ;
data->output_frames_gen = filter->out_gen / filter->channels ;
return SRC_ERR_NO_ERROR ;
} /* sinc_multichan_vari_process */
/*----------------------------------------------------------------------------------------
*/
@@ -414,55 +1186,3 @@ prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len)
} /* prepare_data */
static double
calc_output (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int ch)
{ double fraction, left, right, icoeff ;
increment_t filter_index, max_filter_index ;
int data_index, coeff_count, indx ;
/* Convert input parameters into fixed point. */
max_filter_index = int_to_fp (filter->coeff_half_len) ;
/* First apply the left half of the filter. */
filter_index = start_filter_index ;
coeff_count = (max_filter_index - filter_index) / increment ;
filter_index = filter_index + coeff_count * increment ;
data_index = filter->b_current - filter->channels * coeff_count + ch ;
left = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
left += icoeff * filter->buffer [data_index] ;
filter_index -= increment ;
data_index = data_index + filter->channels ;
}
while (filter_index >= MAKE_INCREMENT_T (0)) ;
/* Now apply the right half of the filter. */
filter_index = increment - start_filter_index ;
coeff_count = (max_filter_index - filter_index) / increment ;
filter_index = filter_index + coeff_count * increment ;
data_index = filter->b_current + filter->channels * (1 + coeff_count) + ch ;
right = 0.0 ;
do
{ fraction = fp_to_double (filter_index) ;
indx = fp_to_int (filter_index) ;
icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
right += icoeff * filter->buffer [data_index] ;
filter_index -= increment ;
data_index = data_index - filter->channels ;
}
while (filter_index > MAKE_INCREMENT_T (0)) ;
return (left + right) ;
} /* calc_output */

View File

@@ -52,41 +52,41 @@ typedef struct
static int
zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
{ ZOH_DATA *zoh ;
{ ZOH_DATA *priv ;
double src_ratio, input_index, rem ;
int ch ;
if (psrc->private_data == NULL)
return SRC_ERR_NO_PRIVATE ;
zoh = (ZOH_DATA*) psrc->private_data ;
priv = (ZOH_DATA*) psrc->private_data ;
if (zoh->reset)
if (priv->reset)
{ /* If we have just been reset, set the last_value data. */
for (ch = 0 ; ch < zoh->channels ; ch++)
zoh->last_value [ch] = data->data_in [ch] ;
zoh->reset = 0 ;
for (ch = 0 ; ch < priv->channels ; ch++)
priv->last_value [ch] = data->data_in [ch] ;
priv->reset = 0 ;
} ;
zoh->in_count = data->input_frames * zoh->channels ;
zoh->out_count = data->output_frames * zoh->channels ;
zoh->in_used = zoh->out_gen = 0 ;
priv->in_count = data->input_frames * priv->channels ;
priv->out_count = data->output_frames * priv->channels ;
priv->in_used = priv->out_gen = 0 ;
src_ratio = psrc->last_ratio ;
input_index = psrc->last_position ;
/* Calculate samples before first sample in input array. */
while (input_index < 1.0 && zoh->out_gen < zoh->out_count)
while (input_index < 1.0 && priv->out_gen < priv->out_count)
{
if (zoh->in_used + zoh->channels * input_index >= zoh->in_count)
if (priv->in_used + priv->channels * input_index >= priv->in_count)
break ;
if (zoh->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
src_ratio = psrc->last_ratio + zoh->out_gen * (data->src_ratio - psrc->last_ratio) / zoh->out_count ;
if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ;
for (ch = 0 ; ch < zoh->channels ; ch++)
{ data->data_out [zoh->out_gen] = zoh->last_value [ch] ;
zoh->out_gen ++ ;
for (ch = 0 ; ch < priv->channels ; ch++)
{ data->data_out [priv->out_gen] = priv->last_value [ch] ;
priv->out_gen ++ ;
} ;
/* Figure out the next index. */
@@ -94,44 +94,44 @@ zoh_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
} ;
rem = fmod_one (input_index) ;
zoh->in_used += zoh->channels * lrint (input_index - rem) ;
priv->in_used += priv->channels * lrint (input_index - rem) ;
input_index = rem ;
/* Main processing loop. */
while (zoh->out_gen < zoh->out_count && zoh->in_used + zoh->channels * input_index <= zoh->in_count)
while (priv->out_gen < priv->out_count && priv->in_used + priv->channels * input_index <= priv->in_count)
{
if (zoh->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
src_ratio = psrc->last_ratio + zoh->out_gen * (data->src_ratio - psrc->last_ratio) / zoh->out_count ;
if (priv->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
src_ratio = psrc->last_ratio + priv->out_gen * (data->src_ratio - psrc->last_ratio) / priv->out_count ;
for (ch = 0 ; ch < zoh->channels ; ch++)
{ data->data_out [zoh->out_gen] = data->data_in [zoh->in_used - zoh->channels + ch] ;
zoh->out_gen ++ ;
for (ch = 0 ; ch < priv->channels ; ch++)
{ data->data_out [priv->out_gen] = data->data_in [priv->in_used - priv->channels + ch] ;
priv->out_gen ++ ;
} ;
/* Figure out the next index. */
input_index += 1.0 / src_ratio ;
rem = fmod_one (input_index) ;
zoh->in_used += zoh->channels * lrint (input_index - rem) ;
priv->in_used += priv->channels * lrint (input_index - rem) ;
input_index = rem ;
} ;
if (zoh->in_used > zoh->in_count)
{ input_index += (zoh->in_used - zoh->in_count) / zoh->channels ;
zoh->in_used = zoh->in_count ;
if (priv->in_used > priv->in_count)
{ input_index += (priv->in_used - priv->in_count) / priv->channels ;
priv->in_used = priv->in_count ;
} ;
psrc->last_position = input_index ;
if (zoh->in_used > 0)
for (ch = 0 ; ch < zoh->channels ; ch++)
zoh->last_value [ch] = data->data_in [zoh->in_used - zoh->channels + ch] ;
if (priv->in_used > 0)
for (ch = 0 ; ch < priv->channels ; ch++)
priv->last_value [ch] = data->data_in [priv->in_used - priv->channels + ch] ;
/* Save current ratio rather then target ratio. */
psrc->last_ratio = src_ratio ;
data->input_frames_used = zoh->in_used / zoh->channels ;
data->output_frames_gen = zoh->out_gen / zoh->channels ;
data->input_frames_used = priv->in_used / priv->channels ;
data->output_frames_gen = priv->out_gen / priv->channels ;
return SRC_ERR_NO_ERROR ;
} /* zoh_vari_process */
@@ -159,28 +159,25 @@ zoh_get_description (int src_enum)
int
zoh_set_converter (SRC_PRIVATE *psrc, int src_enum)
{ ZOH_DATA *zoh = NULL ;
{ ZOH_DATA *priv = NULL ;
if (src_enum != SRC_ZERO_ORDER_HOLD)
return SRC_ERR_BAD_CONVERTER ;
if (psrc->private_data != NULL)
{ zoh = (ZOH_DATA*) psrc->private_data ;
if (zoh->zoh_magic_marker != ZOH_MAGIC_MARKER)
{ free (psrc->private_data) ;
psrc->private_data = NULL ;
} ;
{ free (psrc->private_data) ;
psrc->private_data = NULL ;
} ;
if (psrc->private_data == NULL)
{ zoh = calloc (1, sizeof (*zoh) + psrc->channels * sizeof (float)) ;
if (zoh == NULL)
{ priv = calloc (1, sizeof (*priv) + psrc->channels * sizeof (float)) ;
if (priv == NULL)
return SRC_ERR_MALLOC_FAILED ;
psrc->private_data = zoh ;
psrc->private_data = priv ;
} ;
zoh->zoh_magic_marker = ZOH_MAGIC_MARKER ;
zoh->channels = psrc->channels ;
priv->zoh_magic_marker = ZOH_MAGIC_MARKER ;
priv->channels = psrc->channels ;
psrc->const_process = zoh_vari_process ;
psrc->vari_process = zoh_vari_process ;
@@ -196,15 +193,15 @@ zoh_set_converter (SRC_PRIVATE *psrc, int src_enum)
static void
zoh_reset (SRC_PRIVATE *psrc)
{ ZOH_DATA *zoh ;
{ ZOH_DATA *priv ;
zoh = (ZOH_DATA*) psrc->private_data ;
if (zoh == NULL)
priv = (ZOH_DATA*) psrc->private_data ;
if (priv == NULL)
return ;
zoh->channels = psrc->channels ;
zoh->reset = 1 ;
memset (zoh->last_value, 0, sizeof (zoh->last_value [0]) * zoh->channels) ;
priv->channels = psrc->channels ;
priv->reset = 1 ;
memset (priv->last_value, 0, sizeof (priv->last_value [0]) * priv->channels) ;
return ;
} /* zoh_reset */

View File

@@ -245,10 +245,11 @@ inline void envelopeAndLFOParameters::fillLFOLevel( float * _buf,
}
fpp_t offset = 0;
const float lafI = 1.0f / m_lfoAttackFrames;
for( ; offset < _frames && _frame < m_lfoAttackFrames; ++offset,
++_frame )
{
*_buf++ = m_lfoShapeData[offset] * _frame / m_lfoAttackFrames;
*_buf++ = m_lfoShapeData[offset] * _frame * lafI;
}
for( ; offset < _frames; ++offset )
{
@@ -411,39 +412,44 @@ void envelopeAndLFOParameters::updateSampleVars( void )
m_pahdEnv = new sample_t[m_pahdFrames];
m_rEnv = new sample_t[m_rFrames];
const float aa = m_amountAdd;
for( f_cnt_t i = 0; i < predelay_frames; ++i )
{
m_pahdEnv[i] = m_amountAdd;
m_pahdEnv[i] = aa;
}
f_cnt_t add = predelay_frames;
const float afI = ( 1.0f / attack_frames ) * m_amount;
for( f_cnt_t i = 0; i < attack_frames; ++i )
{
m_pahdEnv[add + i] = ( (float)i / attack_frames ) *
m_amount + m_amountAdd;
m_pahdEnv[add+i] = i * afI + aa;
}
add += attack_frames;
const float amsum = m_amount + m_amountAdd;
for( f_cnt_t i = 0; i < hold_frames; ++i )
{
m_pahdEnv[add + i] = m_amount + m_amountAdd;
m_pahdEnv[add + i] = amsum;
}
add += hold_frames;
const float dfI = (1.0 / decay_frames)*(m_sustainLevel-1)*m_amount;
for( f_cnt_t i = 0; i < decay_frames; ++i )
{
/*
m_pahdEnv[add + i] = ( m_sustainLevel + ( 1.0f -
(float)i / decay_frames ) *
( 1.0f - m_sustainLevel ) ) *
m_amount + m_amountAdd;
*/
m_pahdEnv[add + i] = amsum + i*dfI;
}
const float rfI = ( 1.0f / m_rFrames ) * m_amount;
for( f_cnt_t i = 0; i < m_rFrames; ++i )
{
m_rEnv[i] = ( (float)( m_rFrames - i ) / m_rFrames
// * m_sustainLevel
) * m_amount;
m_rEnv[i] = (float)( m_rFrames - i ) * rfI;
}
// save this calculation in real-time-part

View File

@@ -1,7 +1,7 @@
/*
* mixer.cpp - audio-device-independent mixer for LMMS
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -41,6 +41,7 @@
#include "sample_play_handle.h"
#include "piano_roll.h"
#include "micro_timer.h"
#include "atomic_int.h"
#include "audio_device.h"
#include "midi_client.h"
@@ -95,7 +96,7 @@ static void * aligned_malloc( int _bytes )
class mixerWorkerThread : public QThread
class MixerWorkerThread : public QThread
{
public:
enum JobTypes
@@ -107,50 +108,47 @@ public:
NumJobTypes
} ;
struct jobQueueItem
struct JobQueueItem
{
jobQueueItem() :
JobQueueItem() :
type( InvalidJob ),
job( NULL ),
param( 0 ),
done( false )
{
}
jobQueueItem( JobTypes _type, void * _job ) :
JobQueueItem( JobTypes _type, void * _job, int _param = 0 ) :
type( _type ),
job( _job ),
param( _param ),
done( false )
{
}
JobTypes type;
void * job;
int param;
union
{
playHandle * playHandleJob;
audioPort * audioPortJob;
int effectChannelJob;
volatile void * job;
};
#if QT_VERSION >= 0x040400
QAtomicInt done;
#else
volatile bool done;
#endif
AtomicInt done;
} ;
typedef QVector<jobQueueItem> jobQueueItems;
struct jobQueue
struct JobQueue
{
jobQueueItems items;
#if QT_VERSION < 0x040400
QMutex lock;
#endif
#define JOB_QUEUE_SIZE 1024
JobQueue() :
queueSize( 0 )
{
}
JobQueueItem items[JOB_QUEUE_SIZE];
int queueSize;
AtomicInt itemsDone;
} ;
static jobQueue s_jobQueue;
static JobQueue s_jobQueue;
mixerWorkerThread( int _worker_num, mixer * _mixer ) :
MixerWorkerThread( int _worker_num, mixer * _mixer ) :
QThread( _mixer ),
m_workingBuf( (sampleFrame *) aligned_malloc(
_mixer->framesPerPeriod() *
@@ -158,12 +156,11 @@ public:
m_workerNum( _worker_num ),
m_quit( false ),
m_mixer( _mixer ),
m_queueReadySem( &m_mixer->m_queueReadySem ),
m_workersDoneSem( &m_mixer->m_workersDoneSem )
m_queueReadyWaitCond( &m_mixer->m_queueReadyWaitCond )
{
}
virtual ~mixerWorkerThread()
virtual ~MixerWorkerThread()
{
aligned_free( m_workingBuf );
}
@@ -173,60 +170,7 @@ public:
m_quit = true;
}
void processJobQueue( void )
{
jobQueueItems::iterator end_it = s_jobQueue.items.end();
for( jobQueueItems::iterator it =
s_jobQueue.items.begin();
it != end_it; ++it )
{
#if QT_VERSION >= 0x040400
if( it->done.fetchAndStoreOrdered( 1 ) == 0 )
{
#else
s_jobQueue.lock.lock();
if( !it->done )
{
it->done = true;
s_jobQueue.lock.unlock();
#endif
switch( it->type )
{
case PlayHandle:
it->playHandleJob->play( m_workingBuf );
break;
case AudioPortEffects:
{
audioPort * a = it->audioPortJob;
const bool me = a->processEffects();
if( me || a->m_bufferUsage != audioPort::NoUsage )
{
engine::getFxMixer()->mixToChannel( a->firstBuffer(),
a->nextFxChannel() );
a->nextPeriod();
}
}
break;
case EffectChannel:
engine::getFxMixer()->processChannel(
(fx_ch_t) it->effectChannelJob );
break;
default:
/*fprintf( stderr, "invalid job item type %d at %ld in jobqueue(%ld:%ld)\n",
(int) it->type, (long int) it,
(long int) s_jobQueue.items.begin(),
(long int) end_it );*/
break;
}
}
#if QT_VERSION < 0x040400
else
{
s_jobQueue.lock.unlock();
}
#endif
}
}
void processJobQueue( void );
private:
@@ -242,12 +186,13 @@ private:
#endif
#endif
#endif
QMutex m;
while( m_quit == false )
{
m_queueReadySem->acquire();
m.lock();
m_queueReadyWaitCond->wait( &m );
processJobQueue();
m_workersDoneSem->release();
m.unlock();
}
}
@@ -255,34 +200,103 @@ private:
int m_workerNum;
volatile bool m_quit;
mixer * m_mixer;
QSemaphore * m_queueReadySem;
QSemaphore * m_workersDoneSem;
QWaitCondition * m_queueReadyWaitCond;
} ;
mixerWorkerThread::jobQueue mixerWorkerThread::s_jobQueue;
MixerWorkerThread::JobQueue MixerWorkerThread::s_jobQueue;
#define FILL_JOB_QUEUE(_vec_type,_vec,_job_type,_condition) \
mixerWorkerThread::s_jobQueue.items.clear(); \
void MixerWorkerThread::processJobQueue( void )
{
for( int i = 0; i < s_jobQueue.queueSize; ++i )
{
JobQueueItem * it = &s_jobQueue.items[i];
if( it->done.fetchAndStoreOrdered( 1 ) == 0 )
{
switch( it->type )
{
case PlayHandle:
( (playHandle *) it->job )->
play( m_workingBuf );
break;
case AudioPortEffects:
{
audioPort * a = (audioPort *) it->job;
const bool me = a->processEffects();
if( me || a->m_bufferUsage != audioPort::NoUsage )
{
engine::getFxMixer()->mixToChannel( a->firstBuffer(),
a->nextFxChannel() );
a->nextPeriod();
}
}
break;
case EffectChannel:
engine::getFxMixer()->processChannel( (fx_ch_t) it->param );
break;
default:
break;
}
s_jobQueue.itemsDone.fetchAndAddOrdered( 1 );
}
}
}
#define FILL_JOB_QUEUE_BEGIN(_vec_type,_vec,_condition) \
MixerWorkerThread::s_jobQueue.queueSize = 0; \
MixerWorkerThread::s_jobQueue.itemsDone = 0; \
for( _vec_type::iterator it = _vec.begin(); \
it != _vec.end(); ++it ) \
it != _vec.end(); ++it ) \
{ \
if( _condition ) \
{ \
mixerWorkerThread::s_jobQueue.items. \
push_back( \
mixerWorkerThread::jobQueueItem( _job_type, \
(void *)*it ) );\
{
#define FILL_JOB_QUEUE_END() \
++MixerWorkerThread::s_jobQueue.queueSize; \
} \
}
#define FILL_JOB_QUEUE(_vec_type,_vec,_job_type,_condition) \
FILL_JOB_QUEUE_BEGIN(_vec_type,_vec,_condition) \
MixerWorkerThread::s_jobQueue.items \
[MixerWorkerThread::s_jobQueue.queueSize] = \
MixerWorkerThread::JobQueueItem( _job_type, \
(void *) *it ); \
FILL_JOB_QUEUE_END()
#define FILL_JOB_QUEUE_PARAM(_vec_type,_vec,_job_type,_condition) \
FILL_JOB_QUEUE_BEGIN(_vec_type,_vec,_condition) \
MixerWorkerThread::s_jobQueue.items \
[MixerWorkerThread::s_jobQueue.queueSize] = \
MixerWorkerThread::JobQueueItem( _job_type, \
NULL, *it ); \
FILL_JOB_QUEUE_END()
#define START_JOBS() \
m_queueReadySem.release( m_numWorkers ); \
m_queueReadyWaitCond.wakeAll();
// define a pause instruction for spinlock-loop - merely useful on
// HyperThreading systems with just one physical core (e.g. Intel Atom)
#ifdef LMMS_HOST_X86_64
#define SPINLOCK_PAUSE() asm( "pause" )
#else
#ifdef LMMS_HOST_X86_64
#define SPINLOCK_PAUSE() asm( "pause" )
#else
#define SPINLOCK_PAUSE()
#endif
#endif
#define WAIT_FOR_JOBS() \
m_workersDoneSem.acquire( m_numWorkers );
m_workers[m_numWorkers]->processJobQueue(); \
while( MixerWorkerThread::s_jobQueue.itemsDone < \
MixerWorkerThread::s_jobQueue.queueSize ) \
{ \
SPINLOCK_PAUSE(); \
} \
@@ -296,10 +310,8 @@ mixer::mixer( void ) :
m_writeBuf( NULL ),
m_cpuLoad( 0 ),
m_workers(),
m_numWorkers( QThread::idealThreadCount() > 1 ?
QThread::idealThreadCount()-1 : 0 ),
m_queueReadySem( m_numWorkers ),
m_workersDoneSem( m_numWorkers ),
m_numWorkers( QThread::idealThreadCount()-1 ),
m_queueReadyWaitCond(),
m_qualitySettings( qualitySettings::Mode_Draft ),
m_masterGain( 1.0f ),
m_audioDev( NULL ),
@@ -363,14 +375,12 @@ mixer::mixer( void ) :
m_bufferPool.push_back( m_readBuf );
}
m_queueReadySem.acquire( m_numWorkers );
m_workersDoneSem.acquire( m_numWorkers );
for( int i = 0; i < m_numWorkers+1; ++i )
{
mixerWorkerThread * wt = new mixerWorkerThread( i, this );
if( i > 0 )
MixerWorkerThread * wt = new MixerWorkerThread( i, this );
if( i < m_numWorkers )
{
wt->start( QThread::HighestPriority );
wt->start( QThread::TimeCriticalPriority );
}
m_workers.push_back( wt );
}
@@ -387,15 +397,15 @@ mixer::~mixer()
{
// distribute an empty job-queue so that worker-threads
// get out of their processing-loop
mixerWorkerThread::s_jobQueue.items.clear();
MixerWorkerThread::s_jobQueue.queueSize = 0;
for( int w = 0; w < m_numWorkers; ++w )
{
m_workers[w+1]->quit();
m_workers[w]->quit();
}
START_JOBS();
for( int w = 0; w < m_numWorkers; ++w )
{
m_workers[w+1]->wait( 500 );
m_workers[w]->wait( 500 );
}
while( m_fifo->available() )
@@ -432,7 +442,7 @@ void mixer::startProcessing( bool _needs_fifo )
if( _needs_fifo )
{
m_fifoWriter = new fifoWriter( this, m_fifo );
m_fifoWriter->start( QThread::TimeCriticalPriority );
m_fifoWriter->start( QThread::HighPriority );
}
else
{
@@ -609,10 +619,9 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
// STAGE 1: run and render all play handles
FILL_JOB_QUEUE(playHandleVector,m_playHandles,
mixerWorkerThread::PlayHandle,
MixerWorkerThread::PlayHandle,
!( *it )->done());
START_JOBS();
m_workers[0]->processJobQueue();
WAIT_FOR_JOBS();
// removed all play handles which are done
@@ -620,7 +629,7 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
it != m_playHandles.end(); )
{
if( ( *it )->affinityMatters() &&
( *it )->affinity() != QThread::currentThread() )
( *it )->affinity() != QThread::currentThread() )
{
++it;
continue;
@@ -639,17 +648,15 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
// STAGE 2: process effects of all instrument- and sampletracks
FILL_JOB_QUEUE(QVector<audioPort*>,m_audioPorts,
mixerWorkerThread::AudioPortEffects,1);
MixerWorkerThread::AudioPortEffects,1);
START_JOBS();
m_workers[0]->processJobQueue();
WAIT_FOR_JOBS();
// STAGE 3: process effects in FX mixer
FILL_JOB_QUEUE(QVector<fx_ch_t>,__fx_channel_jobs,
mixerWorkerThread::EffectChannel,1);
FILL_JOB_QUEUE_PARAM(QVector<fx_ch_t>,__fx_channel_jobs,
MixerWorkerThread::EffectChannel,1);
START_JOBS();
m_workers[0]->processJobQueue();
WAIT_FOR_JOBS();

View File

@@ -3,7 +3,7 @@
/*
* note.cpp - implementation of class note
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -49,7 +49,8 @@ note::note( const midiTime & _length, const midiTime & _pos,
m_volume( tLimit( _volume, MinVolume, MaxVolume ) ),
m_panning( tLimit( _panning, PanningLeft, PanningRight ) ),
m_length( _length ),
m_pos( _pos )
m_pos( _pos ),
m_detuning( NULL )
{
//saveJournallingState( FALSE );
// setJournalling( FALSE );
@@ -78,9 +79,17 @@ note::note( const note & _note ) :
m_volume( _note.m_volume ),
m_panning( _note.m_panning ),
m_length( _note.m_length ),
m_pos( _note.m_pos )
m_pos( _note.m_pos ),
m_detuning( NULL )
{
m_detuning = sharedObject::ref( _note.m_detuning );
if( _note.m_detuning )
{
m_detuning = sharedObject::ref( _note.m_detuning );
}
else
{
createDetuning();
}
}
@@ -88,7 +97,10 @@ note::note( const note & _note ) :
note::~note()
{
sharedObject::unref( m_detuning );
if( m_detuning )
{
sharedObject::unref( m_detuning );
}
}
@@ -269,7 +281,7 @@ void note::createDetuning( void )
bool note::hasDetuningInfo( void ) const
{
return( m_detuning && m_detuning->hasAutomation() );
return m_detuning && m_detuning->hasAutomation();
}

View File

@@ -3,7 +3,7 @@
/*
* sample_buffer.cpp - container-class sampleBuffer
*
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -67,7 +67,7 @@
sampleBuffer::sampleBuffer( const QString & _audio_file,
bool _is_base64_data ) :
m_audioFile( ( _is_base64_data == TRUE ) ? "" : _audio_file ),
m_audioFile( ( _is_base64_data == true ) ? "" : _audio_file ),
m_origData( NULL ),
m_origFrames( 0 ),
m_data( NULL ),
@@ -77,11 +77,11 @@ sampleBuffer::sampleBuffer( const QString & _audio_file,
m_loopStartFrame( 0 ),
m_loopEndFrame( 0 ),
m_amplification( 1.0f ),
m_reversed( FALSE ),
m_reversed( false ),
m_frequency( BaseFreq ),
m_sampleRate( engine::getMixer()->baseSampleRate() )
{
if( _is_base64_data == TRUE )
if( _is_base64_data == true )
{
loadFromBase64( _audio_file );
}
@@ -102,7 +102,7 @@ sampleBuffer::sampleBuffer( const sampleFrame * _data, const f_cnt_t _frames ) :
m_loopStartFrame( 0 ),
m_loopEndFrame( 0 ),
m_amplification( 1.0f ),
m_reversed( FALSE ),
m_reversed( false ),
m_frequency( BaseFreq ),
m_sampleRate( engine::getMixer()->baseSampleRate() )
{
@@ -129,7 +129,7 @@ sampleBuffer::sampleBuffer( const f_cnt_t _frames ) :
m_loopStartFrame( 0 ),
m_loopEndFrame( 0 ),
m_amplification( 1.0f ),
m_reversed( FALSE ),
m_reversed( false ),
m_frequency( BaseFreq ),
m_sampleRate( engine::getMixer()->baseSampleRate() )
{
@@ -165,13 +165,13 @@ void sampleBuffer::update( bool _keep_settings )
delete[] m_data;
}
if( m_audioFile == "" && m_origData != NULL && m_origFrames > 0 )
if( m_audioFile.isEmpty() && m_origData != NULL && m_origFrames > 0 )
{
// TODO: reverse- and amplification-property is not covered
// by following code...
m_data = new sampleFrame[m_origFrames];
memcpy( m_data, m_origData, m_origFrames * BYTES_PER_FRAME );
if( _keep_settings == FALSE )
if( _keep_settings == false )
{
m_frames = m_origFrames;
m_loopStartFrame = m_startFrame = 0;
@@ -185,9 +185,16 @@ void sampleBuffer::update( bool _keep_settings )
int_sample_t * buf = NULL;
ch_cnt_t channels = DEFAULT_CHANNELS;
sample_rate_t samplerate = engine::getMixer()->baseSampleRate();
m_frames = 0;
if( QFileInfo( file ).size() > 100*1024*1024 )
{
qWarning( "refusing to load sample files bigger "
"than 100 MB" );
}
else
{
if( m_frames == 0 )
{
m_frames = decodeSampleSF( f, buf, channels,
@@ -207,6 +214,7 @@ void sampleBuffer::update( bool _keep_settings )
}
delete[] f;
}
if( m_frames > 0 && buf != NULL )
{
@@ -295,7 +303,7 @@ void sampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr,
delete resampled;
}
if( _keep_settings == FALSE )
if( _keep_settings == false )
{
// update frame-variables
m_loopStartFrame = m_startFrame = 0;
@@ -338,7 +346,7 @@ f_cnt_t sampleBuffer::decodeSampleSF( const char * _f,
"sample %s: %s\n", _f, sf_strerror( NULL ) );
#endif
}
return( frames );
return frames;
}
@@ -350,8 +358,8 @@ f_cnt_t sampleBuffer::decodeSampleSF( const char * _f,
size_t qfileReadCallback( void * _ptr, size_t _size, size_t _n, void * _udata )
{
return( static_cast<QFile *>( _udata )->read( (char*) _ptr,
_size * _n ) );
return static_cast<QFile *>( _udata )->read( (char*) _ptr,
_size * _n );
}
@@ -373,7 +381,7 @@ int qfileSeekCallback( void * _udata, ogg_int64_t _offset, int _whence )
{
f->seek( _offset );
}
return( 0 );
return 0;
}
@@ -382,7 +390,7 @@ int qfileSeekCallback( void * _udata, ogg_int64_t _offset, int _whence )
int qfileCloseCallback( void * _udata )
{
delete static_cast<QFile *>( _udata );
return( 0 );
return 0;
}
@@ -390,7 +398,7 @@ int qfileCloseCallback( void * _udata )
long qfileTellCallback( void * _udata )
{
return( static_cast<QFile *>( _udata )->pos() );
return static_cast<QFile *>( _udata )->pos();
}
@@ -414,10 +422,10 @@ f_cnt_t sampleBuffer::decodeSampleOGGVorbis( const char * _f,
f_cnt_t frames = 0;
QFile * f = new QFile( _f );
if( f->open( QFile::ReadOnly ) == FALSE )
if( f->open( QFile::ReadOnly ) == false )
{
delete f;
return( 0 );
return 0;
}
int err = ov_open_callbacks( f, &vf, NULL, 0, callbacks );
@@ -448,7 +456,7 @@ f_cnt_t sampleBuffer::decodeSampleOGGVorbis( const char * _f,
break;
}
delete f;
return( 0 );
return 0;
}
ov_pcm_seek( &vf, 0 );
@@ -479,7 +487,7 @@ f_cnt_t sampleBuffer::decodeSampleOGGVorbis( const char * _f,
ov_clear( &vf );
return( frames );
return frames;
}
#endif
@@ -492,7 +500,7 @@ f_cnt_t sampleBuffer::decodeSampleDS( const char * _f,
sample_rate_t & _samplerate )
{
DrumSynth ds;
return( ds.GetDSFileSamples( _f, _buf, _channels ) );
return ds.GetDSFileSamples( _f, _buf, _channels );
}
@@ -509,7 +517,7 @@ bool sampleBuffer::play( sampleFrame * _ab, handleState * _state,
if( m_endFrame == 0 || _frames == 0 )
{
return( FALSE );
return false;
}
const double freq_factor = (double) _freq / (double) m_frequency *
@@ -521,7 +529,7 @@ bool sampleBuffer::play( sampleFrame * _ab, handleState * _state,
freq_factor );
if( total_frames_for_current_pitch == 0 )
{
return( FALSE );
return false;
}
// this holds the number of the first frame to play
@@ -544,14 +552,14 @@ bool sampleBuffer::play( sampleFrame * _ab, handleState * _state,
{
if( play_frame >= m_endFrame )
{
return( FALSE );
return false;
}
frames_for_loop = static_cast<f_cnt_t>(
( m_endFrame - play_frame ) /
freq_factor );
if( frames_for_loop == 0 )
{
return( FALSE );
return false;
}
}
@@ -571,7 +579,7 @@ bool sampleBuffer::play( sampleFrame * _ab, handleState * _state,
src_data.input_frames = fragment_size;
src_data.output_frames = _frames;
src_data.src_ratio = 1.0 / freq_factor;
src_data.end_of_input = _state->m_eof;
src_data.end_of_input = 0;
int error = src_process( _state->m_resamplingData,
&src_data );
if( error )
@@ -584,7 +592,6 @@ bool sampleBuffer::play( sampleFrame * _ab, handleState * _state,
printf( "sampleBuffer: not enough frames: %ld / %d\n",
src_data.output_frames_gen, _frames );
}
_state->m_eof = src_data.end_of_input;
// Advance
play_frame += src_data.input_frames_used;
if( _looped )
@@ -613,7 +620,7 @@ bool sampleBuffer::play( sampleFrame * _ab, handleState * _state,
_state->m_frameIndex = play_frame;
return( TRUE );
return true;
}
@@ -627,14 +634,14 @@ sampleFrame * sampleBuffer::getSampleFragment( f_cnt_t _start,
{
if( _start + _frames <= m_loopEndFrame )
{
return( m_data + _start );
return m_data + _start;
}
}
else
{
if( _start + _frames <= m_endFrame )
{
return( m_data + _start );
return m_data + _start;
}
}
@@ -661,7 +668,7 @@ sampleFrame * sampleBuffer::getSampleFragment( f_cnt_t _start,
BYTES_PER_FRAME );
}
return( *_tmp );
return *_tmp;
}
@@ -671,10 +678,10 @@ f_cnt_t sampleBuffer::getLoopedIndex( f_cnt_t _index ) const
{
if( _index < m_loopEndFrame )
{
return( _index );
return _index;
}
return( m_loopStartFrame + ( _index - m_loopStartFrame )
% ( m_loopEndFrame - m_loopStartFrame ) );
return m_loopStartFrame + ( _index - m_loopStartFrame )
% ( m_loopEndFrame - m_loopStartFrame );
}
@@ -727,7 +734,7 @@ QString sampleBuffer::openAudioFile( void ) const
if( QFileInfo( f ).isRelative() )
{
f = configManager::inst()->userSamplesDir() + f;
if( QFileInfo( f ).exists() == FALSE )
if( QFileInfo( f ).exists() == false )
{
f = configManager::inst()->factorySamplesDir() +
m_audioFile;
@@ -771,12 +778,12 @@ QString sampleBuffer::openAudioFile( void ) const
{
if( ofd.selectedFiles().isEmpty() )
{
return( "" );
return QString::null;
}
return( tryToMakeRelative( ofd.selectedFiles()[0] ) );
return tryToMakeRelative( ofd.selectedFiles()[0] );
}
return( "" );
return QString::null;
}
@@ -795,13 +802,13 @@ FLAC__StreamEncoderWriteStatus flacStreamEncoderWriteCallback(
{
/* if( _bytes == 0 )
{
return( FLAC__STREAM_ENCODER_WRITE_STATUS_OK );
return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
}*/
return( ( static_cast<QBuffer *>( _client_data )->write(
return ( static_cast<QBuffer *>( _client_data )->write(
(const char *) _buffer, _bytes ) ==
(int) _bytes ) ?
FLAC__STREAM_ENCODER_WRITE_STATUS_OK :
FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR );
FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
}
@@ -826,8 +833,8 @@ QString & sampleBuffer::toBase64( QString & _dst ) const
FLAC__StreamEncoder * flac_enc = FLAC__stream_encoder_new();
FLAC__stream_encoder_set_channels( flac_enc, DEFAULT_CHANNELS );
FLAC__stream_encoder_set_blocksize( flac_enc, FRAMES_PER_BUF );
/* FLAC__stream_encoder_set_do_exhaustive_model_search( flac_enc, TRUE );
FLAC__stream_encoder_set_do_mid_side_stereo( flac_enc, TRUE );*/
/* FLAC__stream_encoder_set_do_exhaustive_model_search( flac_enc, true );
FLAC__stream_encoder_set_do_mid_side_stereo( flac_enc, true );*/
FLAC__stream_encoder_set_sample_rate( flac_enc,
engine::getMixer()->sampleRate() );
QBuffer ba_writer;
@@ -877,7 +884,7 @@ QString & sampleBuffer::toBase64( QString & _dst ) const
#endif /* LMMS_HAVE_FLAC_STREAM_ENCODER_H */
return( _dst );
return _dst;
}
@@ -900,7 +907,7 @@ sampleBuffer * sampleBuffer::resample( sampleFrame * _data,
DEFAULT_CHANNELS, &error ) ) != NULL )
{
SRC_DATA src_data;
src_data.end_of_input = 0;
src_data.end_of_input = 1;
src_data.data_in = _data[0];
src_data.data_out = dst_buf[0];
src_data.input_frames = _frames;
@@ -918,7 +925,7 @@ sampleBuffer * sampleBuffer::resample( sampleFrame * _data,
printf( "Error: src_new() failed in sample_buffer.cpp!\n" );
}
dst_sb->update();
return( dst_sb );
return dst_sb;
}
@@ -956,11 +963,11 @@ FLAC__StreamDecoderReadStatus flacStreamDecoderReadCallback(
if( res > 0 )
{
*_bytes = res;
return( FLAC__STREAM_DECODER_READ_STATUS_CONTINUE );
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
}
*_bytes = 0;
return( FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM );
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
}
@@ -977,14 +984,14 @@ FLAC__StreamDecoderWriteStatus flacStreamDecoderWriteCallback(
{
printf( "channels != 2 in "
"flacStreamDecoderWriteCallback()\n" );
return( FLAC__STREAM_DECODER_WRITE_STATUS_ABORT );
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
if( _frame->header.bits_per_sample != 16 )
{
printf( "bits_per_sample != 16 in "
"flacStreamDecoderWriteCallback()\n" );
return( FLAC__STREAM_DECODER_WRITE_STATUS_ABORT );
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
const f_cnt_t frames = _frame->header.blocksize;
@@ -999,7 +1006,7 @@ FLAC__StreamDecoderWriteStatus flacStreamDecoderWriteCallback(
_client_data )->write_buffer->write(
(const char *) sframe, sizeof( sframe ) );
}
return( FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE );
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
@@ -1112,7 +1119,7 @@ void sampleBuffer::setEndFrame( const f_cnt_t _e )
void sampleBuffer::setAmplification( float _a )
{
m_amplification = _a;
update( TRUE );
update( true );
}
@@ -1121,7 +1128,7 @@ void sampleBuffer::setAmplification( float _a )
void sampleBuffer::setReversed( bool _on )
{
m_reversed = _on;
update( TRUE );
update( true );
}
@@ -1129,7 +1136,7 @@ void sampleBuffer::setReversed( bool _on )
QString sampleBuffer::tryToMakeRelative( const QString & _file )
{
if( QFileInfo( _file ).isRelative() == FALSE )
if( QFileInfo( _file ).isRelative() == false )
{
QString f = QString( _file ).replace( QDir::separator(), '/' );
QString fsd = configManager::inst()->factorySamplesDir();
@@ -1138,14 +1145,14 @@ QString sampleBuffer::tryToMakeRelative( const QString & _file )
usd.replace( QDir::separator(), '/' );
if( f.startsWith( fsd ) )
{
return( QString( f ).mid( fsd.length() ) );
return QString( f ).mid( fsd.length() );
}
else if( f.startsWith( usd ) )
{
return( QString( f ).mid( usd.length() ) );
return QString( f ).mid( usd.length() );
}
}
return( _file );
return _file;
}
@@ -1155,16 +1162,16 @@ QString sampleBuffer::tryToMakeAbsolute( const QString & _file )
{
if( QFileInfo( _file ).isAbsolute() )
{
return( _file );
return _file;
}
QString f = configManager::inst()->userSamplesDir() + _file;
if( QFileInfo( f ).exists() )
{
return( f );
return f;
}
return( configManager::inst()->factorySamplesDir() + _file );
return configManager::inst()->factorySamplesDir() + _file;
}
@@ -1176,12 +1183,11 @@ QString sampleBuffer::tryToMakeAbsolute( const QString & _file )
sampleBuffer::handleState::handleState( bool _varying_pitch ) :
m_frameIndex( 0 ),
m_varyingPitch( _varying_pitch ),
m_eof( 0 )
m_varyingPitch( _varying_pitch )
{
int error;
if( ( m_resamplingData = src_new(/*
( engine::getMixer()->highQuality() == TRUE ) ?
( engine::getMixer()->highQuality() == true ) ?
SRC_SINC_FASTEST :*/
SRC_LINEAR,
DEFAULT_CHANNELS, &error ) ) == NULL )

View File

@@ -4,7 +4,7 @@
* track.cpp - implementation of classes concerning tracks -> neccessary for
* all track-like objects (beat/bassline, sample-track...)
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -40,6 +40,7 @@
#include "track.h"
#include <assert.h>
#include <cstdio>
#include <QtGui/QLayout>
#include <QtGui/QMenu>
@@ -683,7 +684,7 @@ void trackContentObjectView::mouseMoveEvent( QMouseEvent * _me )
QVector<selectableObject *> so =
m_trackView->getTrackContainerView()->selectedObjects();
QVector<trackContentObject *> tcos;
midiTime smallest_pos;
midiTime smallest_pos, t;
// find out smallest position of all selected objects for not
// moving an object before zero
for( QVector<selectableObject *>::iterator it = so.begin();
@@ -705,10 +706,15 @@ void trackContentObjectView::mouseMoveEvent( QMouseEvent * _me )
for( QVector<trackContentObject *>::iterator it = tcos.begin();
it != tcos.end(); ++it )
{
( *it )->movePosition( ( *it )->startPosition() +
static_cast<int>( dx *
midiTime::ticksPerTact() / ppt ) -
smallest_pos );
t = ( *it )->startPosition() +
static_cast<int>( dx *midiTime::ticksPerTact() /
ppt )-smallest_pos;
if( ! ( _me->modifiers() & Qt::AltModifier )
&& _me->button() == Qt::NoButton )
{
t = t.toNearestTact();
}
( *it )->movePosition( t );
}
}
else if( m_action == Resize )
@@ -1355,6 +1361,7 @@ trackOperationsWidget::trackOperationsWidget( trackView * _parent ) :
m_trackOps = new QPushButton( this );
m_trackOps->move( 12, 1 );
m_trackOps->setFocusPolicy( Qt::NoFocus );
m_trackOps->setMenu( to_menu );
toolTip::add( m_trackOps, tr( "Actions for this track" ) );
@@ -1378,8 +1385,6 @@ trackOperationsWidget::trackOperationsWidget( trackView * _parent ) :
m_trackView->getTrackContainerView(),
SLOT( deleteTrackView( trackView * ) ),
Qt::QueuedConnection );
setAttribute( Qt::WA_OpaquePaintEvent, true );
}

View File

@@ -2,7 +2,7 @@
* piano_roll.cpp - implementation of piano-roll which is used for actual
* writing of melodies
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008 Andrew Kelley <superjoe30/at/gmail/dot/com>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
@@ -48,6 +48,7 @@
#include <math.h>
#include "bb_track_container.h"
#include "clipboard.h"
#include "combobox.h"
#include "debug.h"
@@ -235,6 +236,17 @@ pianoRoll::pianoRoll( void ) :
connect( m_timeLine, SIGNAL( positionChanged( const midiTime & ) ),
this, SLOT( updatePosition( const midiTime & ) ) );
// update timeline when in record-accompany mode
connect( engine::getSong()->getPlayPos( song::Mode_PlaySong ).m_timeLine,
SIGNAL( positionChanged( const midiTime & ) ),
this,
SLOT( updatePositionAccompany( const midiTime & ) ) );
// TODO
/* connect( engine::getSong()->getPlayPos( song::Mode_PlayBB ).m_timeLine,
SIGNAL( positionChanged( const midiTime & ) ),
this,
SLOT( updatePositionAccompany( const midiTime & ) ) );*/
m_toolBar = new QWidget( this );
m_toolBar->setFixedHeight( 32 );
@@ -579,11 +591,12 @@ void pianoRoll::setCurrentPattern( pattern * _new_pattern )
// of start-notes and so on...)
resizeEvent( NULL );
// and now connect to noteDone()-signal of channel so that
// we receive note-off-events from it's midi-port for recording it
connect( m_pattern->getInstrumentTrack(),
SIGNAL( noteDone( const note & ) ),
this, SLOT( recordNote( const note & ) ) );
SIGNAL( noteOn( const note & ) ),
this, SLOT( startRecordNote( const note & ) ) );
connect( m_pattern->getInstrumentTrack(),
SIGNAL( noteOff( const note & ) ),
this, SLOT( finishRecordNote( const note & ) ) );
setWindowTitle( tr( "Piano-Roll - %1" ).arg( m_pattern->name() ) );
@@ -806,13 +819,25 @@ void pianoRoll::shiftPos( int amount ) //shift notes pos by amount
{
bool useAllNotes = ! isSelection();
const noteVector & notes = m_pattern->notes();
bool first = true;
for( noteVector::const_iterator it = notes.begin(); it != notes.end();
++it )
{
// if none are selected, move all notes, otherwise
// only move selected notes
if( useAllNotes || ( *it )->selected() )
if( ( *it )->selected() || (useAllNotes && ( *it )->length() > 0) )
{
// don't let notes go to out of bounds
if( first )
{
m_moveBoundaryLeft = ( *it )->pos();
if( m_moveBoundaryLeft + amount < 0 )
{
amount += 0 - (amount + m_moveBoundaryLeft);
}
first = false;
}
( *it )->setPos( ( *it )->pos() + amount );
}
}
@@ -2852,11 +2877,13 @@ void pianoRoll::paintEvent( QPaintEvent * _pe )
break;
case ModeErase: cursor = s_toolErase; break;
case ModeSelect: cursor = s_toolSelect; break;
//case ModeMove: cursor = s_toolMove; break;
case ModeOpen: cursor = s_toolOpen; break;
}
p.drawPixmap( mapFromGlobal( QCursor::pos() ) + QPoint( 8, 8 ),
if( cursor != NULL )
{
p.drawPixmap( mapFromGlobal( QCursor::pos() ) + QPoint( 8, 8 ),
*cursor );
}
}
@@ -2959,6 +2986,19 @@ int pianoRoll::getKey( int _y ) const
song::PlayModes pianoRoll::desiredPlayModeForAccompany( void ) const
{
if( m_pattern->getTrack()->getTrackContainer() ==
engine::getBBTrackContainer() )
{
return song::Mode_PlayBB;
}
return song::Mode_PlaySong;
}
void pianoRoll::play( void )
{
if( validPattern() == false )
@@ -3027,7 +3067,7 @@ void pianoRoll::recordAccompany( void )
}
m_recording = true;
if( m_pattern->getTrack()->getTrackContainer() == engine::getSong() )
{
engine::getSong()->play();
@@ -3054,17 +3094,57 @@ void pianoRoll::stop( void )
void pianoRoll::recordNote( const note & _n )
void pianoRoll::startRecordNote( const note & _n )
{
if( m_recording == true && validPattern() == true )
if( m_recording == true && validPattern() == true &&
engine::getSong()->isPlaying() &&
( engine::getSong()->playMode() ==
desiredPlayModeForAccompany() ||
engine::getSong()->playMode() ==
song::Mode_PlayPattern ) )
{
note n( _n.length(), engine::getSong()->getPlayPos(
engine::getSong()->playMode() ) - _n.length(),
midiTime sub;
if( engine::getSong()->playMode() == song::Mode_PlaySong )
{
sub = m_pattern->startPosition();
}
note n( 1, engine::getSong()->getPlayPos(
engine::getSong()->playMode() ) - sub,
_n.key(), _n.getVolume(), _n.getPanning() );
n.quantizeLength( quantization() );
m_pattern->addNote( n );
update();
engine::getSong()->setModified();
if( n.pos() >= 0 )
{
m_recordingNotes << n;
}
}
}
void pianoRoll::finishRecordNote( const note & _n )
{
if( m_recording == true && validPattern() == true &&
engine::getSong()->isPlaying() &&
( engine::getSong()->playMode() ==
desiredPlayModeForAccompany() ||
engine::getSong()->playMode() ==
song::Mode_PlayPattern ) )
{
for( QList<note>::Iterator it = m_recordingNotes.begin();
it != m_recordingNotes.end(); ++it )
{
if( it->key() == _n.key() )
{
note n( _n.length(), it->pos(),
it->key(), it->getVolume(),
it->getPanning() );
n.quantizeLength( quantization() );
m_pattern->addNote( n );
update();
m_recordingNotes.erase( it );
break;
}
}
}
}
@@ -3367,6 +3447,27 @@ void pianoRoll::deleteSelectedNotes( void )
void pianoRoll::autoScroll( const midiTime & _t )
{
const int w = width() - WHITE_KEY_WIDTH;
if( _t > m_currentPosition + w * midiTime::ticksPerTact() / m_ppt )
{
m_leftRightScroll->setValue( _t.getTact() *
midiTime::ticksPerTact() );
}
else if( _t < m_currentPosition )
{
midiTime t = qMax( _t - w * midiTime::ticksPerTact() *
midiTime::ticksPerTact() / m_ppt, 0 );
m_leftRightScroll->setValue( t.getTact() *
midiTime::ticksPerTact() );
}
m_scrollBack = false;
}
void pianoRoll::updatePosition( const midiTime & _t )
{
if( ( engine::getSong()->isPlaying() &&
@@ -3375,21 +3476,30 @@ void pianoRoll::updatePosition( const midiTime & _t )
m_timeLine->autoScroll() == timeLine::AutoScrollEnabled ) ||
m_scrollBack == true )
{
const int w = width() - WHITE_KEY_WIDTH;
if( _t > m_currentPosition + w * midiTime::ticksPerTact() /
m_ppt )
autoScroll( _t );
}
}
void pianoRoll::updatePositionAccompany( const midiTime & _t )
{
song * s = engine::getSong();
if( m_recording && validPattern() &&
s->playMode() != song::Mode_PlayPattern )
{
midiTime pos = _t;
if( s->playMode() != song::Mode_PlayBB )
{
m_leftRightScroll->setValue( _t.getTact() *
midiTime::ticksPerTact() );
pos -= m_pattern->startPosition();
}
else if( _t < m_currentPosition )
if( (int) pos > 0 )
{
midiTime t = qMax( _t - w * midiTime::ticksPerTact() *
midiTime::ticksPerTact() / m_ppt, 0 );
m_leftRightScroll->setValue( t.getTact() *
midiTime::ticksPerTact() );
s->getPlayPos( song::Mode_PlayPattern ).setTicks( pos );
autoScroll( pos );
}
m_scrollBack = false;
}
}

View File

@@ -3,7 +3,7 @@
/*
* song_editor.cpp - basic window for song-editing
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -51,6 +51,7 @@
#include "tooltip.h"
#include "visualization_widget.h"
#include "audio_device.h"
#include "piano_roll.h"
@@ -414,6 +415,7 @@ void songEditor::scrolled( int _new_pos )
void songEditor::play( void )
{
m_s->play();
engine::getPianoRoll()->stopRecording();
if( m_s->playMode() == song::Mode_PlaySong )
{
m_playButton->setIcon( embed::getIconPixmap( "pause" ) );
@@ -446,6 +448,7 @@ void songEditor::recordAccompany( void )
void songEditor::stop( void )
{
m_s->stop();
engine::getPianoRoll()->stopRecording();
m_playButton->setIcon( embed::getIconPixmap( "play" ) );
}

View File

@@ -4,7 +4,7 @@
* automatable_button.cpp - implementation of class automatableButton and
* automatableButtonGroup
*
* Copyright (c) 2006-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2006-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -47,6 +47,7 @@ automatableButton::automatableButton( QWidget * _parent,
{
setAccessibleName( _name );
doConnections();
setFocusPolicy( Qt::NoFocus );
}

View File

@@ -3,7 +3,7 @@
/*
* combobox.cpp - implementation of LMMS-combobox
*
* Copyright (c) 2006-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2006-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -80,7 +80,6 @@ comboBox::comboBox( QWidget * _parent, const QString & _name ) :
connect( &m_menu, SIGNAL( triggered( QAction * ) ),
this, SLOT( setItem( QAction * ) ) );
setAttribute( Qt::WA_OpaquePaintEvent, true );
setAccessibleName( _name );
doConnections();
}

View File

@@ -52,6 +52,7 @@ controllerRackView::controllerRackView( ) :
m_scrollArea = new QScrollArea( this );
m_scrollArea->setFixedSize( 230, 184 );
m_scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
m_scrollArea->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
m_scrollArea->setPalette( QApplication::palette( m_scrollArea ) );
m_scrollArea->move( 6, 22 );

View File

@@ -57,8 +57,7 @@ controllerView::controllerView( controller * _model, QWidget * _parent ) :
setAttribute( Qt::WA_OpaquePaintEvent, TRUE );
QPushButton * ctls_btn = new QPushButton( tr( "Controls" ),
this );
QPushButton * ctls_btn = new QPushButton( tr( "Controls" ), this );
QFont f = ctls_btn->font();
ctls_btn->setFont( pointSize<7>( f ) );
@@ -79,8 +78,8 @@ controllerView::controllerView( controller * _model, QWidget * _parent ) :
m_subWindow->setWindowIcon( m_controllerDlg->windowIcon() );
connect( m_controllerDlg, SIGNAL( closed() ),
this, SLOT( closeControls() ) );
connect( m_controllerDlg, SIGNAL( closed() ),
this, SLOT( closeControls() ) );
m_subWindow->hide();
@@ -149,8 +148,8 @@ void controllerView::paintEvent( QPaintEvent * )
p.setPen( Qt::white );
p.drawText( 6, 12, c->displayName() );
f.setBold( FALSE );
p.setFont( f );
f.setBold( FALSE );
p.setFont( f );
p.drawText( 8, 26, c->name() );
}

View File

@@ -4,7 +4,7 @@
* effect_rack_view.cpp - view for effectChain-model
*
* Copyright (c) 2006-2007 Danny McRae <khjklujn@netscape.net>
* Copyright (c) 2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -42,16 +42,21 @@ effectRackView::effectRackView( effectChain * _model, QWidget * _parent ) :
QWidget( _parent ),
modelView( NULL, this )
{
setAttribute( Qt::WA_OpaquePaintEvent, true );
setFixedSize( 250, 250 );
m_effectsGroupBox = new groupBox( tr( "EFFECTS CHAIN" ), this );
m_effectsGroupBox->setGeometry( 4, 5, 242, 240 );
m_mainLayout = new QVBoxLayout( this );
m_mainLayout->setSpacing( 0 );
m_mainLayout->setMargin( 5 );
m_effectsGroupBox = new groupBox( tr( "EFFECTS CHAIN" ) );
m_mainLayout->addWidget( m_effectsGroupBox );
m_scrollArea = new QScrollArea( m_effectsGroupBox );
m_scrollArea->setFixedSize( 230, 184 );
m_scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
m_scrollArea->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
m_scrollArea->setPalette( QApplication::palette( m_scrollArea ) );
m_scrollArea->setWidget( new QWidget );
m_scrollArea->move( 6, 22 );
QPushButton * addButton = new QPushButton( m_effectsGroupBox );
@@ -59,8 +64,6 @@ effectRackView::effectRackView( effectChain * _model, QWidget * _parent ) :
addButton->move( 8, 210 );
connect( addButton, SIGNAL( clicked() ), this, SLOT( addEffect() ) );
QWidget * w = new QWidget;
m_scrollArea->setWidget( w );
m_lastY = 0;

View File

@@ -4,7 +4,7 @@
* envelope_and_lfo_view.cpp - widget which is m_used by envelope/lfo/filter-
* tab of channel-window
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -103,8 +103,6 @@ envelopeAndLFOView::envelopeAndLFOView( QWidget * _parent ) :
s_lfoGraph = new QPixmap( embed::getIconPixmap( "lfo_graph" ) );
}
setAttribute( Qt::WA_OpaquePaintEvent, true );
m_predelayKnob = new knob( knobBright_26, this );
m_predelayKnob->setLabel( tr( "DEL" ) );
m_predelayKnob->move( PREDELAY_KNOB_X, ENV_KNOBS_Y );

View File

@@ -3,7 +3,7 @@
/*
* fade_button.cpp - implementation of fade-button
*
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -35,15 +35,19 @@
#include "update_event.h"
const float FadeDuration = 300;
fadeButton::fadeButton( const QColor & _normal_color,
const QColor & _activated_color, QWidget * _parent ) :
QAbstractButton( _parent ),
m_state( 0.0f ),
m_stateTimer(),
m_normalColor( _normal_color ),
m_activatedColor( _activated_color )
{
setAttribute( Qt::WA_OpaquePaintEvent, true );
setCursor( QCursor( embed::getIconPixmap( "hand" ), 0, 0 ) );
setFocusPolicy( Qt::NoFocus );
}
@@ -58,21 +62,12 @@ fadeButton::~fadeButton()
void fadeButton::activate( void )
{
m_state = 1.00f;
m_stateTimer.restart();
signalUpdate();
}
void fadeButton::reset( void )
{
m_state = 0.0f;
signalUpdate();
}
void fadeButton::customEvent( QEvent * )
{
@@ -85,20 +80,19 @@ void fadeButton::customEvent( QEvent * )
void fadeButton::paintEvent( QPaintEvent * _pe )
{
QColor col = m_normalColor;
if( m_state > 0.0f )
if( m_stateTimer.elapsed() < FadeDuration )
{
const float state = 1 - m_stateTimer.elapsed() / FadeDuration;
const int r = (int)( m_normalColor.red() *
( 1.0f - m_state ) +
m_activatedColor.red() * m_state );
( 1.0f - state ) +
m_activatedColor.red() * state );
const int g = (int)( m_normalColor.green() *
( 1.0f - m_state ) +
m_activatedColor.green() * m_state );
( 1.0f - state ) +
m_activatedColor.green() * state );
const int b = (int)( m_normalColor.blue() *
( 1.0f - m_state ) +
m_activatedColor.blue() * m_state );
( 1.0f - state ) +
m_activatedColor.blue() * state );
col.setRgb( r, g, b );
m_state -= 0.1f;
QTimer::singleShot( 20, this, SLOT( update() ) );
}

View File

@@ -3,7 +3,7 @@
/*
* group_box.cpp - groupbox for LMMS
*
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -47,7 +47,6 @@ groupBox::groupBox( const QString & _caption, QWidget * _parent ) :
boolModelView( NULL, this ),
m_caption( _caption )
{
setAttribute( Qt::WA_OpaquePaintEvent, true );
updatePixmap();
m_led = new pixmapButton( this, _caption );

View File

@@ -474,7 +474,7 @@ void knob::mousePressEvent( QMouseEvent * _me )
void knob::mouseMoveEvent( QMouseEvent * _me )
{
if( m_buttonPressed == TRUE )
if( m_buttonPressed == TRUE && _me->pos() != m_origMousePos )
{
setPosition( _me->pos() );
emit sliderMoved( model()->value() );

View File

@@ -3,7 +3,7 @@
/*
* lcd_spinbox.cpp - class lcdSpinBox, an improved QLCDNumber
*
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008 Paul Giblock <pgllama/at/gmail.com>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
@@ -52,7 +52,6 @@ lcdSpinBox::lcdSpinBox( int _num_digits, QWidget * _parent,
m_numDigits( _num_digits ),
m_origMousePos()
{
setAttribute( Qt::WA_OpaquePaintEvent, true );
setEnabled( true );
setAccessibleName( _name );

View File

@@ -3,7 +3,7 @@
/*
* tab_widget.cpp - tabwidget for LMMS
*
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -50,8 +50,6 @@ tabWidget::tabWidget( const QString & _caption, QWidget * _parent ) :
QPalette pal = palette();
pal.setColor( QPalette::Background, bg_color );
setPalette( pal );
setAttribute( Qt::WA_OpaquePaintEvent, true );
}

View File

@@ -3,7 +3,7 @@
/*
* visualization_widget.cpp - widget for visualization of sound-data
*
* Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -29,6 +29,7 @@
#include <QtGui/QPainter>
#include "visualization_widget.h"
#include "gui_templates.h"
#include "main_window.h"
#include "embed.h"
#include "engine.h"
@@ -42,7 +43,7 @@ visualizationWidget::visualizationWidget( const QPixmap & _bg, QWidget * _p,
QWidget( _p ),
s_background( _bg ),
m_points( new QPointF[engine::getMixer()->framesPerPeriod()] ),
m_active( FALSE )
m_active( false )
{
setFixedSize( s_background.width(), s_background.height() );
setAttribute( Qt::WA_OpaquePaintEvent, true );
@@ -55,9 +56,6 @@ visualizationWidget::visualizationWidget( const QPixmap & _bg, QWidget * _p,
toolTip::add( this, tr( "click to enable/disable visualization of "
"master-output" ) );
setActive( TRUE );
}
@@ -79,11 +77,7 @@ void visualizationWidget::updateAudioBuffer( void )
const surroundSampleFrame * c = engine::getMixer()->
currentReadBuffer();
const fpp_t fpp = engine::getMixer()->framesPerPeriod();
for( f_cnt_t f = 0; f < fpp; ++f )
{
m_buffer[f][0] = c[f][0];
m_buffer[f][1] = c[f][1];
}
memcpy( m_buffer, c, sizeof( surroundSampleFrame ) * fpp );
engine::getMixer()->unlock();
}
}
@@ -169,12 +163,18 @@ void visualizationWidget::paintEvent( QPaintEvent * )
{
m_points[frame] = QPointF(
x_base + (float) frame * xd,
y_base + ( mixer::clip( m_buffer[frame][ch] ) *
half_h ) );
y_base + ( mixer::clip(
m_buffer[frame][ch] ) *
half_h ) );
}
p.drawPolyline( m_points, frames );
}
}
else
{
p.setPen( QColor( 192, 192, 192 ) );
p.setFont( pointSize<7>( p.font() ) );
p.drawText( 6, height()-5, tr( "Click to enable" ) );
}
}

View File

@@ -455,7 +455,7 @@ void bbTrack::loadTrackSpecificSettings( const QDomElement & _this )
if( _this.hasAttribute( "clonebbt" ) )
{
const int src = _this.attribute( "clonebb" ).toInt();
const int src = _this.attribute( "clonebbt" ).toInt();
const int dst = s_infoMap[this];
engine::getBBTrackContainer()->createTCOsForBB( dst );
trackContainer::trackList tl =

View File

@@ -2,7 +2,7 @@
* instrument_track.cpp - implementation of instrument-track-class
* (window + data-structures)
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -248,6 +248,8 @@ void instrumentTrack::processInEvent( const midiEvent & _me,
{
m_notes[_me.key()] = nph;
}
emit noteOn( n );
}
break;
}
@@ -259,7 +261,7 @@ void instrumentTrack::processInEvent( const midiEvent & _me,
{
// create dummy-note which has the same length
// as the played note for sending it later
// to all slots connected to signal noteDone()
// to all slots connected to signal noteOff()
// this is for example needed by piano-roll for
// recording notes into a pattern
note done_note(
@@ -274,7 +276,7 @@ void instrumentTrack::processInEvent( const midiEvent & _me,
n->noteOff();
m_notes[_me.key()] = NULL;
emit noteDone( done_note );
emit noteOff( done_note );
}
break;
}
@@ -463,7 +465,7 @@ void instrumentTrack::deleteNotePluginData( notePlayHandle * _n )
_n->getVolume(), _n->getPanning() );
_n->noteOff();
m_notes[_n->key()] = NULL;
emit noteDone( done_note );
emit noteOff( done_note );
}
}

View File

@@ -3,7 +3,7 @@
/*
* pattern.cpp - implementation of class pattern which holds notes
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2007 Danny McRae <khjklujn/at/yahoo.com>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
@@ -183,17 +183,6 @@ midiTime pattern::beatPatternLength( void ) const
void pattern::printNotes( void )
{
for( noteVector::iterator it = m_notes.begin(); it != m_notes.end();
++it )
{
printf("note (pos = %i)\n", (int) ( *it )->pos() );
}
printf("\n");
}
note * pattern::addNote( const note & _new_note, const bool _quant_pos )
{
@@ -742,6 +731,7 @@ patternFreezeThread::patternFreezeThread( pattern * _pattern ) :
patternFreezeThread::~patternFreezeThread()
{
m_pattern->dataChanged();
}
@@ -1321,8 +1311,9 @@ void patternView::paintEvent( QPaintEvent * )
}
else if( m_pat->m_frozenPattern != NULL )
{
p.setBrush( QBrush() );
p.setPen( QColor( 0, 224, 255 ) );
p.drawRect( 0, 0, width(), height() - 1 );
p.drawRect( 0, 0, width()-1, height() - 1 );
p.drawPixmap( 3, height() - s_frozen->height() - 4, *s_frozen );
}