Merge branch 'stable-0.4' into next

This commit is contained in:
Paul Giblock
2013-02-27 17:34:21 -05:00
92 changed files with 1946 additions and 369 deletions

View File

@@ -16,7 +16,7 @@ INCLUDE(FindPkgConfig)
SET(VERSION_MAJOR "0")
SET(VERSION_MINOR "4")
SET(VERSION_PATCH "14")
SET(VERSION_SUFFIX "rc1")
#SET(VERSION_SUFFIX "")
SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
IF(VERSION_SUFFIX)
SET(VERSION "${VERSION}-${VERSION_SUFFIX}")

4
README
View File

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

Binary file not shown.

View File

@@ -539,7 +539,7 @@ If you're interested in translating LMMS in another language or want to imp
</message>
<message>
<source>6add9</source>
<translation>madd9</translation>
<translation>6add9</translation>
</message>
<message>
<source>m6</source>

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.2-cvs20060123" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="Default" basetone="9" tab="1" >
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="alien_strings" basetone="9" tab="1" >
<bitinvader sampleLength="128" interpolation="1" version="0.1" normalize="0" sampleShape="PKaOPeKT5r6uR+G9CtejvczMTL2PwvW8CtejvAAAAAAK16M8CtejPI/C9TzMzEw9j8J1PY/CdT2PwnU9j8J1PY/CdT2PwnU9j8J1PczMTD2PwvU8CtejPArXIzwK1yO8CtejvI/C9bzMzEy9KVyPvQrXo73sUbi9rkfhvY/C9b2PwvW9uB4FvpqZGb4K1yO+CtcjvnsULr7sUTi+XI9Cvs3MTL7NzEy+zcxMvs3MTL7NzEy+PgpXvq5HYb6uR2G+rkdhvh6Fa76PwnW+j8J1vo/Cdb6PwnW+j8J1vo/Cdb6PwnW+j8J1vo/Cdb6PwnW+j8J1vo/Cdb6PwnW+HoVrvq5HYb4+Cle+zcxMvlyPQr57FC6+CtcjvpqZGb64HgW+rkfhvc3MzL3sUbi9KVyPvczMTL0K1yO9j8L1vArXI7wK1yM8CtejPI/C9TyPwvU8CtcjPSlcjz3sUbg9rkfhPY/C9T24HgU+mpkZPgrXIz57FC4+7FE4PlyPQj7NzEw+PgpXPh6Faz64HoU+KVyPPuJ6lD5SuJ4+exSuPuxRuD5cj8I+hevRPq5H4T7Xo/A+j8L1PgAAAD+4HgU/zMwMP+F6FD8+Chc/9igcP2ZmJj/XozA/MzMzP5DCNT9I4To/XI9CP3A9Sj/NzEw/KVxPP4XrUT/helQ/9ihcP2ZmZj8=" />
<eldata fres="0.21" ftype="0" fcut="3840" fwet="1" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.33" ctlenvamt="0" latt="0" sus="0.49" lspd="0.7311" att="0.4" pdel="0" lamt="0" dec="0.897" userwavefile="" x100="1" lshp="0" hold="0" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.2-cvs20060123" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="Default" basetone="9" tab="1" >
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="beehive" basetone="9" tab="1" >
<bitinvader sampleLength="30" interpolation="1" version="0.1" normalize="1" sampleShape="AAAAAPMEtT56glo/eoJaP/IEtT72BLW+eoJav3iCWr/vBLW+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI/CdT3NzEw+rkfhPlK4Hj97FC4/pHA9P1yPQj89Clc/rkdhP65HYT/Xo3A/j8J1P0jhej8AAIA/" />
<eldata fres="0.43" ftype="1" fcut="1120" fwet="1" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.65" ctlenvamt="0" latt="0" sus="0" lspd="0.1" att="0.496" pdel="0" lamt="0" dec="0.499" userwavefile="" x100="0" lshp="0" hold="0" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.2-cvs20060123" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="Default" basetone="9" tab="0" >
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="bell" basetone="9" tab="0" >
<bitinvader sampleLength="8" interpolation="1" version="0.1" normalize="0" sampleShape="AAAAAPMENT8AAIA/8wQ1Py69u7P1BDW/AACAv+8ENb8=" />
<eldata fres="0.43" ftype="0" fcut="1280" fwet="0" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.351" ctlenvamt="0" latt="0" sus="0.499" lspd="0.1" att="0" pdel="0" lamt="0" dec="0.499" userwavefile="" x100="0" lshp="0" hold="0" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.4" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="Default" basetone="9" tab="0" >
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="cello" basetone="9" tab="0" >
<bitinvader sampleLength="128" interpolation="1" version="0.1" normalize="1" sampleShape="xUHivbW52r2yLVm+IY2QvlbDqr5qnbS+bhe3vm5Bt74UH4q+NgEbvlF9KL7+kX6+ILePviYNk74+YZ++W4utvighlL65edy9rZnWPeoZdT45f5w+VgurPjr5nD55STw+qsHUPIoBRbyeyc491VlqPszNZT7coW09IAEQvgYzg75QAai+fAO+vixDlr5++b692JHrPfYlez7W9Wo+vNFdPRRhCr7gOXC+JN+Rvui5c76P4Ue9IYUQPuepcz4vi5c+WCesPiNFkT6CycA9tiHbvao9Vb4GT4O+tZVavkuxJb2ygdg9Y1UxPuBZcD7EDWI+QumgPXQJur2WFUu+CWOEvkThob5y9bi+iEPEvo+Fx75vb7e+RrGivi2Zlr60KVq+8oF4vWjhsz1+0T4+dqk6PsoBZT2jUdG9qMVTvh9zj75dc66+MuuYvv7J/r3TwWk9hClCPjIjmT40UZo+FbkKPii5k72VcUq+ED2Ivi7/lr6+YV++KaEUvS7xFj4G7YI+NCmaPj4Bnz7evW4+luFKPf+R/73AwV++H2ePvlV1qr5owbO+VFmqvlY9q756rby+RK2hvgAtAL5+Kb894oVxPtgRbD4YYYw9/oH/vfdpe75Bc6C+WE2svvJZeb5F8SK9G5UNPvbFej5Ep6E+HhWPPrah2j2YWcy97ml3vtz1bb4=" />
<eldata fres="0.5" ftype="0" fcut="16000" fwet="0" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.727" ctlenvamt="0" latt="0" sus="0" lspd="0.1" att="0.517" pdel="0" lamt="0" dec="0" userwavefile="" x100="0" lshp="0" hold="0" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.2-cvs20060123" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="Default" basetone="9" tab="0" >
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="drama" basetone="9" tab="0" >
<bitinvader sampleLength="128" interpolation="1" version="0.1" normalize="0" sampleShape="kNtHv4tFRb+EOUK/ftM+v3Y1O79vaTe/Z3Mzv19tL79Xdyu/T4Mnv0e1I79ACSC/OaEcvzNnGb8tbRa/J70TvyNNEb8eNQ+/G10NvxjRC78Vlwq/E58JvxLxCL8Rgwi/EU8IvxFZCL8RkQi/Eu0IvxN3Cb8UHwq/FucKvxexC78ZlQy/G3cNvx1bDr8fRw+/ICsQvyLxEL8jsxG/JWcSvyYHE78ngRO/KOETvygpFL8pWRS/KXEUvylnFL8pSxS/KBUUvyjHE78naxO/JusSvyVhEr8jvRG/IgkRvyFDEL8fdw+/HaMOvxu9Db8azQy/GN8LvxbnCr8U6wm/Eu8IvxD5B78O/wa/DAUGvwoXBb8IKwS/B0MDvwVbAr8DdwG/AZsAv/+N/7787f2++Vn8vvbF+r7yQfm+8NX3vu119r7qDfW+553zvuRB8r7i2fC+34nvvtwp7r7Zvey+12HrvtQZ6r7Szei+z23nvswV5r7KzeS+x1XjvsTZ4b7BXeC+vs3evrtF3b63mdu+tBHavrGF2L6u9da+q2XVvqjN076kMdK+oZnQvp7lzr6aLc2+l33LvpO9yb6Q8ce+jCXGvoldxL6FmcK+gsHAvn7tvr56Cb2+d027vnNxub5vpbe+bMm1vmj1s75kIbK+YVGwvl2Frr5Zpay+Vs2qvlINqb4=" />
<eldata fres="0.43" ftype="6" fcut="1120" fwet="0" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.351" ctlenvamt="0" latt="0" sus="0" lspd="0.7311" att="0.058" pdel="0" lamt="0" dec="0.499" userwavefile="" x100="1" lshp="0" hold="0" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.2-cvs20060123" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="Default" basetone="9" tab="1" >
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="epiano" basetone="9" tab="1" >
<bitinvader sampleLength="30" interpolation="1" version="0.1" normalize="1" sampleShape="AAAAAPMEtT56glo/eoJaP/IEtT72BLW+eoJav3iCWr/vBLW+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" />
<eldata fres="0.43" ftype="0" fcut="1280" fwet="0" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.351" ctlenvamt="0" latt="0" sus="0.499" lspd="0.1" att="0" pdel="0" lamt="0" dec="0.499" userwavefile="" x100="0" lshp="0" hold="0.22" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.4" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="Default" basetone="9" tab="0" >
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="soft_pad" basetone="9" tab="0" >
<bitinvader sampleLength="128" interpolation="1" version="0.1" normalize="0" sampleShape="4lVxvqJBUb6xfVi+j0VHvkFRIL7UGeq9Z2GzvV4hr72iwdC98Kn3vQjdA77+2f697NH1vQuFBb5JhSS+nEVOvuDRb77vXXe+v0lfvmqlNL4eCQ++Ar0Avh6tDr5cKS6+lWVKvqjZU76RVUi+X2kvvighFL71Qfq9pMHRvURhor2CAUG9OAGcu2xxNj2O2cY9NbEaPqjNUz4O+4Y+Q1+hPmgLtD52B7s+bbG2PlzJrT5Vf6o+aDu0Ppdbyz7SO+k+BPsBPxTCCT8WCws/ECUIPwgcBD8AOQA/7Af2PsWJ4j6Ff8I+NVWaPtaBaj5+ST8+gMk/Pst5ZT4ax4w+QEGgPkpBpT47cZ0+Ia2QPg7Thj4EC4I+9k17PsphZT50BTo+75n3PbRxWj24Ady7jFFGvRrZjL0gSZC9x1FjvZzBzbwc4Y08DWmGPcGx4D0YUQw+IKEPPvzJ/T2fkc89YGmwPV5Brz2KKcU9sKHXPZqhzD06EZ09YuEwPZpBTTz7gf27bAG2vGPBMb1Syai9HkUPvp15Tr72vXq+BN+Bvtida76KFUW+UjkpvlOFKb6JVUS+0JlnvvzVfb70JXq+v6VfvnwpPr5MaSa+QGUgvk5hJ75dsS6+WDUsvjxVHr4XeQu+8XH4vdOR6b3S0ei95qnyvQotBb48nR2+jr1Gvvr9fL4=" />
<eldata fres="0.5" ftype="0" fcut="9120" fwet="1" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.727" ctlenvamt="1" latt="0" sus="0" lspd="0.1" att="0.657" pdel="0" lamt="0" dec="0" userwavefile="" x100="0" lshp="0" hold="0" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.2-cvs20060123" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="Default" basetone="9" tab="1" >
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="spacefx" basetone="9" tab="1" >
<bitinvader sampleLength="68" interpolation="0" version="0.1" normalize="0" sampleShape="W/iCvqwtgL2mPdg+iodDP+wPEz9vmss5NYLSvr5Zp764oRs9I/l+PjGqND73GnY9WMfrPUu8ej6Rqlk+PSsXO54U/L10nDk97x62Pmty2z4tfu49K3SIvvHCjb7lk/090lz+Pl543T6v5qQ8QySRvjVzN75K9Es+qUf9Pr9J8D7l4AY+KxKgvlRRD78AQsa+9qL8PTwnFj+X3yc/b+W2PlNf0zsVwCq+fEhGvtRdQL4b0Bu+nLoCvc53Fz63MJY+ch6qPq4daj76RsO87J6ovjZj8L6GTpO+gpDEPXm/tT5TBo4+iBUcvXS8nr608KW+QNtwvf8ioz5qDgY/iTKrPksJMr70uhu/nh8Xv01bA74=" />
<eldata fres="0.43" ftype="4" fcut="1120" fwet="1" >
<elvol lfosyncmode="0" lpdel="0" amt="0" rel="0.65" ctlenvamt="0" latt="0" sus="0" lspd="0.7311" att="0.496" pdel="0" lamt="1" dec="0.499" userwavefile="" x100="1" lshp="0" hold="0" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.4" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="7" vol="100" name="Default" basetone="9" tab="0" >
<channeltrack surpos="134219776" fxch="0" baseoct="7" vol="100" name="subbass" basetone="9" tab="0" >
<bitinvader sampleLength="128" interpolation="1" version="0.1" normalize="1" sampleShape="2kpgviIPhz3VQAM+oJkyu8pZrr5y/Ta/5nhxv9QFf7+cp3a//hNovwSBTb+OOR+/s2TIvruEJL5Oy2I9DDSIPmge7D4MVx0/pyQ5P5aHTz8Qp2M/XIhxP/SJdT/mnnI/vbltP2jiZj+x51o/F5pJP9gINj84YiE/iLIJP/+T3D5WAaQ+bGVePt5p8j06A3o81CG5vQSrP77SmIm+xamuvjpD1L5u/vu+wEURv+w7Ib878Su/XHgxv3ClM7+oLzS/HPIyv4ZlLr/YxSW/wR0avzoZDb+KHv++RRrjvoILxr7yV6e+DyCFvhxUO74+g8a9lA3luyFIqz0CcTM+qPOIPq+Rtj68guA++kkDP1jHFD8MlyQ/vC4yP8h7PT/ZxEY/uqdNP9osUT9WVlE/Ct5PP56cTj8xiU0/zBpLPzCMRj9S4UA/EWU7P7zTNT8MlC4/AWwkP/B3Fz/0qQg/ZfLxPrRG0j5sRbM+YtmUPgeFaz7TSik+YFjFPaeVzTw4qT69Je/yvQgvRb4juYm+LTGxvrwJ176QXPm+WKkLv5mbGL924iO/Fsstv16RNr9kaD6/HV9Fv3NZS7+CQFC/wBJUvxubVr/NUle/VvdVvwo8U78WaFC/qfpNv4QBS79SKUa/ykU/vwxcN7+UOy+/upQmv4KdHL+EJRG/OqYEv9Ya774=" />
<eldata fres="1.13" ftype="0" fcut="4960" fwet="1" >
<elvol lfosyncmode="0" lpdel="0" amt="0" rel="0.1" ctlenvamt="0" latt="0" sus="0.499" lspd="0.1" att="0" pdel="0" lamt="0" dec="0.499" userwavefile="" x100="0" lshp="0" hold="0.499" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.2-cvs20060123" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="Default" basetone="9" tab="1" >
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="sweep_pad" basetone="9" tab="1" >
<bitinvader sampleLength="8" interpolation="0" version="0.1" normalize="0" sampleShape="+MrwPiRn7r4WUV6/xEkNv429tL6ofBA+P7uAPtTiwD4=" />
<eldata fres="0.43" ftype="0" fcut="1280" fwet="1" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.351" ctlenvamt="0" latt="0" sus="0.499" lspd="0.1" att="0.164" pdel="0" lamt="0" dec="0.499" userwavefile="" x100="0" lshp="0" hold="0.499" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.4" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="Default" basetone="9" tab="1" >
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="toy_piano" basetone="9" tab="1" >
<bitinvader sampleLength="128" interpolation="1" version="0.1" normalize="0" sampleShape="cAE4OuAB8DkIAYS6gAFAugABALmgAdC5AAEAuiABEDp4Abw6UAEoOggBhLogAZC6gAHAuAgBhLpAASC7oAFQugABgDqAAUA5gAHAOJABSLpaAa27gAFAvHLBuLxBgSC9xCFive4hd72LYUW9GCEMvUZBI70UMYq9+YH8vZIpSb7DkWG+S4Elvnwhvr044Zu9MbGYvQlRhL2JkcS9UjEpvrABWL7rgXW+EhWJvgYFg765sVy+ftk+vj9pH74dUQ6+W2ktvrmxXL4G1YK+J0mTvhuNjb7owXO+0DFovsYRY76teVa+31lvvg2Nhr7iQXG+ujldvgmphL4G7YK+IDkQvjpBHb3sAfa7dsE6PeQB8j0CMQE+SAGkPSWBkjxSAam7PNGdPWt5NT6dWU4+zhlnPgLJgD6uyVY+eWE8PsBBYD7bSW0+5glzPhGdiD4DeYE+23ltPi9Jlz5hebA+Fh2LPpGRSD7RmWg+Gu2MPgYBgz6+2V4+vglfPvD5dz7haXA+cgk5Pi15Fj4lmRI+VvGqPbRB2rzcMe69O2kdvsOh4b3jYXG9J1GTvS1hFr0PYQc9KAGUuyYBk71Voaq9XNGtvWrxtL0CKQG+c2E5vn4hP76RYUi+8Ul4viDZj74RmYi+dBE6vgr5BL4wIRi+q5HVvYeBw7wOAYe8gEFAvamR1L0=" />
<eldata fres="0.5" ftype="0" fcut="9120" fwet="0" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.727" ctlenvamt="1" latt="0" sus="0.717" lspd="0.1" att="0" pdel="0" lamt="0" dec="0.673" userwavefile="" x100="0" lshp="0" hold="0.37" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.2-cvs20060123" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="6" vol="100" name="Default" basetone="9" tab="0" >
<channeltrack surpos="134219776" fxch="0" baseoct="6" vol="100" name="wah_synth" basetone="9" tab="0" >
<bitinvader sampleLength="56" interpolation="1" version="0.1" normalize="1" sampleShape="AAAAAKJN5T2H3GM+VxqpPgMm3j5BMwg/CJ0fP/MENT89Ctc+XI/CPlyPwj57FK4+CtejPpqZmT4pXI8+rkdhPq5HYT7NzEw+zcxMPo/CdT4pXI8+CtejPgrXoz57FK4+7FG4PlyPwj6H3GM+nE3lPS69u7OzTeW9k9xjvlYaqb4DJt6+rkfhvq5H4b49Cte+zczMvs3MzL5cj8K+exSuvnsUrr57FK6+CtejvpqZmb4pXI++KVyPvilcj74pXI++KVyPvilcj74pXI++CtejvuxRuL5cj8K+gtxjvpBN5b0=" />
<eldata fres="0.21" ftype="6" fcut="2720" fwet="1" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.528" ctlenvamt="0" latt="0" sus="0" lspd="0.7311" att="0" pdel="0" lamt="0" dec="0.897" userwavefile="" x100="1" lshp="0" hold="0.234" />

View File

@@ -3,7 +3,7 @@
<multimedia-project version="1.0" creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.4.0-svn20071123" type="instrumenttracksettings" >
<head/>
<instrumenttracksettings>
<instrumenttrack width="250" x="583" y="240" fxch="0" height="470" surpos-x="0" surpos-y="0" visible="1" basenote="75" name="Default" vol="102" tab="0" >
<instrumenttrack width="250" x="583" y="240" fxch="0" height="470" surpos-x="0" surpos-y="0" visible="1" basenote="75" name="Oh Synth" vol="102" tab="0" >
<lb302 db24="1" vcf_res="1.045" vcf_dec="0.42" vco_detune="-16" dead="0" vcf_cut="0.15" vcf_mod="0.61" dist="0" slide_dec="0.57" slide="0" shape="3" />
<eldata fres="0.5" ftype="0" fcut="14000" fwet="0" >
<elvol lspd_denominator="4" pdel="0" userwavefile="" dec="0.5" lamt="0" syncmode="0" latt="0" rel="0.1" sus="0.5" amt="0" x100="0" att="0" lpdel="0" hold="0.5" lshp="0" lspd="0.1" ctlenvamt="0" lspd_numerator="4" />

View File

@@ -2,7 +2,7 @@
<!DOCTYPE multimedia-project>
<multimedia-project version="1.0" creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.4.0-rc3" type="instrumenttracksettings" >
<head/>
<instrumenttracksettings muted="0" type="0" name="Default preset" >
<instrumenttracksettings muted="0" type="0" name="STrash" >
<instrumenttrack pan="0" fxch="0" pitch="0" basenote="81" vol="88" >
<instrument name="lb302" >
<lb302 db24="0" vcf_res="1.01" vcf_dec="0.1" dead="0" vcf_cut="0.18" vcf_mod="1" dist="1" slide_dec="0.5" slide="1" shape="0" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.4-cvs20060209" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="Default" basetone="9" tab="0" >
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="organ_blues" basetone="9" tab="0" >
<organic harmonic4="3" wavetype1="0" harmonic5="4" wavetype2="0" vol0="100" harmonic6="5" wavetype3="0" vol1="100" num_osc="8" harmonic7="6" wavetype4="0" vol2="100" wavetype5="0" vol3="0" detune0="0" wavetype6="0" vol4="0" detune1="0" wavetype7="0" vol5="0" detune2="0" vol6="0" detune3="0" vol7="0" detune4="0" pan0="0" detune5="0" pan1="0" detune6="0" pan2="0" detune7="0" pan3="0" pan4="0" pan5="0" harmonic0="0.5" vol="100" pan6="0" harmonic1="0.75" foldback="0" pan7="0" harmonic2="1" harmonic3="2" wavetype0="0" />
<eldata fres="0.5" ftype="0" fcut="16000" fwet="0" >
<elvol lfosyncmode="0" lpdel="0" amt="0" rel="0.1" ctlenvamt="0" latt="0" sus="0.499" lspd="0.1" att="0" pdel="0" lamt="0" dec="0.499" userwavefile="" x100="0" lshp="0" hold="0.499" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.4-cvs20060209" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="24" name="Default" basetone="9" tab="0" >
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="24" name="organ_risingsun" basetone="9" tab="0" >
<organic harmonic4="3" wavetype1="0" harmonic5="4" wavetype2="0" vol0="100" harmonic6="5" wavetype3="0" vol1="77" num_osc="8" harmonic7="6" wavetype4="0" vol2="100" wavetype5="0" vol3="73" detune0="0" wavetype6="0" vol4="55" detune1="0" wavetype7="0" vol5="47" detune2="1" vol6="73" detune3="0" vol7="100" detune4="0" pan0="0" detune5="0" pan1="0" detune6="0" pan2="0" detune7="0" pan3="0" pan4="0" pan5="0" harmonic0="0.5" vol="166" pan6="0" harmonic1="0.75" foldback="0" pan7="0" harmonic2="1" harmonic3="2" wavetype0="0" />
<eldata fres="0.5" ftype="0" fcut="16000" fwet="0" >
<elvol lfosyncmode="0" lpdel="0" amt="0" rel="0.1" ctlenvamt="0" latt="0" sus="0.499" lspd="0.1" att="0" pdel="0" lamt="0" dec="0.499" userwavefile="" x100="0" lshp="0" hold="0.499" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.4-cvs20060209" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="Default" basetone="9" tab="0" >
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="organ_swish" basetone="9" tab="0" >
<organic harmonic4="3" wavetype1="0" harmonic5="4" wavetype2="0" vol0="5" harmonic6="5" wavetype3="0" vol1="64" num_osc="8" harmonic7="6" wavetype4="0" vol2="66" wavetype5="0" vol3="67" detune0="3" wavetype6="0" vol4="32" detune1="0" wavetype7="0" vol5="32" detune2="1" vol6="4" detune3="1" vol7="0" detune4="0" pan0="0" detune5="40" pan1="0" detune6="0" pan2="0" detune7="0" pan3="0" pan4="0" pan5="0" harmonic0="0.5" vol="100" pan6="0" harmonic1="0.75" foldback="0" pan7="0" harmonic2="1" harmonic3="2" wavetype0="0" />
<eldata fres="0.5" ftype="0" fcut="16000" fwet="0" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.471" ctlenvamt="0" latt="0" sus="0.313" lspd="0.1" att="0.241" pdel="0" lamt="0" dec="0.499" userwavefile="" x100="0" lshp="0" hold="0.499" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.4-cvs20060209" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="Default" basetone="0" tab="1" >
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="pad_ethereal" basetone="0" tab="1" >
<organic harmonic4="3" wavetype1="3" harmonic5="4" wavetype2="3" vol0="79" harmonic6="5" wavetype3="3" vol1="72" num_osc="8" harmonic7="6" wavetype4="0" vol2="31" wavetype5="0" vol3="77" detune0="0" wavetype6="4" vol4="0" detune1="0" wavetype7="0" vol5="13" detune2="0" vol6="20" detune3="0" vol7="69" detune4="0" pan0="0" detune5="0" pan1="0" detune6="0" pan2="0" detune7="0" pan3="0" pan4="0" pan5="0" harmonic0="0.5" vol="100" pan6="0" harmonic1="0.75" foldback="0" pan7="0" harmonic2="1" harmonic3="2" wavetype0="3" />
<eldata fres="0.89" ftype="0" fcut="5600" fwet="1" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.404" ctlenvamt="0" latt="0" sus="0.329" lspd="0.1" att="0.247" pdel="0" lamt="0" dec="0.702" userwavefile="" x100="0" lshp="0" hold="0.329" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.4-cvs20060209" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="Default" basetone="9" tab="0" >
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="pad_rich" basetone="9" tab="0" >
<organic harmonic4="3" wavetype1="2" harmonic5="4" wavetype2="5" vol0="100" harmonic6="5" wavetype3="1" vol1="100" num_osc="8" harmonic7="6" wavetype4="2" vol2="100" wavetype5="5" vol3="100" detune0="1" wavetype6="0" vol4="100" detune1="0" wavetype7="0" vol5="100" detune2="0" vol6="100" detune3="0" vol7="0" detune4="0" pan0="0" detune5="0" pan1="0" detune6="0" pan2="0" detune7="0" pan3="0" pan4="0" pan5="0" harmonic0="0.5" vol="100" pan6="0" harmonic1="0.75" foldback="0.26" pan7="0" harmonic2="1" harmonic3="2" wavetype0="4" />
<eldata fres="1.19" ftype="0" fcut="320" fwet="1" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.708" ctlenvamt="0" latt="0" sus="0.039" lspd="0.1" att="0.363" pdel="0" lamt="0" dec="0.499" userwavefile="" x100="0" lshp="0" hold="0.499" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.4-cvs20060209" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="Default" basetone="9" tab="1" >
<channeltrack surpos="134219776" fxch="0" baseoct="5" vol="100" name="pad_sweep" basetone="9" tab="1" >
<organic harmonic4="3" wavetype1="1" harmonic5="4" wavetype2="1" vol0="37" harmonic6="5" wavetype3="0" vol1="81" num_osc="8" harmonic7="6" wavetype4="5" vol2="100" wavetype5="0" vol3="24" detune0="0" wavetype6="0" vol4="52" detune1="0" wavetype7="0" vol5="0" detune2="0" vol6="0" detune3="0" vol7="0" detune4="0" pan0="0" detune5="0" pan1="0" detune6="0" pan2="0" detune7="0" pan3="0" pan4="0" pan5="0" harmonic0="0.5" vol="200" pan6="6" harmonic1="0.75" foldback="0.06" pan7="0" harmonic2="1" harmonic3="2" wavetype0="1" />
<eldata fres="0.37" ftype="0" fcut="960" fwet="1" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.576" ctlenvamt="0" latt="0" sus="0" lspd="0.1" att="0.345" pdel="0" lamt="0" dec="0.499" userwavefile="" x100="0" lshp="0" hold="0.116" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.4-cvs20060209" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="Default" basetone="9" tab="0" >
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="puresine" basetone="9" tab="0" >
<organic harmonic4="3" wavetype1="0" harmonic5="4" wavetype2="0" vol0="0" harmonic6="5" wavetype3="0" vol1="1" num_osc="8" harmonic7="6" wavetype4="0" vol2="100" wavetype5="0" vol3="5" detune0="0" wavetype6="0" vol4="1" detune1="0" wavetype7="0" vol5="0" detune2="0" vol6="0" detune3="0" vol7="0" detune4="0" pan0="0" detune5="0" pan1="0" detune6="0" pan2="0" detune7="0" pan3="0" pan4="0" pan5="0" harmonic0="0.5" vol="200" pan6="0" harmonic1="0.75" foldback="0" pan7="0" harmonic2="1" harmonic3="2" wavetype0="0" />
<eldata fres="0.5" ftype="0" fcut="16000" fwet="0" >
<elvol lfosyncmode="0" lpdel="0" amt="0" rel="0.1" ctlenvamt="0" latt="0" sus="0.499" lspd="0.1" att="0" pdel="0" lamt="0" dec="0.499" userwavefile="" x100="0" lshp="0" hold="0.499" />

View File

@@ -3,7 +3,7 @@
<multimediaproject creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.1.4-cvs20060209" type="channelsettings" version="1.0" >
<head/>
<channelsettings>
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="Default" basetone="9" tab="2" >
<channeltrack surpos="134219776" fxch="0" baseoct="4" vol="100" name="sequencer_64" basetone="9" tab="2" >
<organic harmonic4="3" wavetype1="3" harmonic5="4" wavetype2="3" vol0="100" harmonic6="5" wavetype3="0" vol1="100" num_osc="8" harmonic7="6" wavetype4="0" vol2="100" wavetype5="0" vol3="1" detune0="0" wavetype6="0" vol4="5" detune1="0" wavetype7="0" vol5="10" detune2="0" vol6="33" detune3="0" vol7="23" detune4="0" pan0="-20" detune5="0" pan1="20" detune6="0" pan2="0" detune7="0" pan3="0" pan4="0" pan5="0" harmonic0="0.5" vol="70" pan6="0" harmonic1="0.75" foldback="0.75" pan7="0" harmonic2="1" harmonic3="2" wavetype0="3" />
<eldata fres="0.5" ftype="0" fcut="16000" fwet="0" >
<elvol lfosyncmode="0" lpdel="0" amt="1" rel="0.169" ctlenvamt="0" latt="0" sus="0" lspd="0.1" att="0" pdel="0" lamt="0" dec="0" userwavefile="" x100="0" lshp="0" hold="0.171" />

View File

@@ -2,7 +2,7 @@
<!DOCTYPE multimedia-project>
<multimedia-project version="1.0" creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.4.0-rc3" type="instrumenttracksettings" >
<head/>
<instrumenttracksettings muted="0" type="0" name="Default preset" >
<instrumenttracksettings muted="0" type="0" name="SBass" >
<instrumenttrack pan="0" fxch="0" pitch="0" basenote="81" vol="200" >
<instrument name="tripleoscillator" >
<tripleoscillator phoffset2="0" userwavefile0="" finer0="0" userwavefile1="" finer1="-4" userwavefile2="" finer2="2" coarse0="0" coarse1="0" coarse2="0" finel0="0" finel1="4" modalgo1="0" modalgo2="0" finel2="-2" pan0="0" modalgo3="2" pan1="0" stphdetun0="0" pan2="0" stphdetun1="0" wavetype0="3" stphdetun2="0" wavetype1="5" wavetype2="5" vol0="33" vol1="33" phoffset0="0" phoffset1="0" vol2="33" />

View File

@@ -2,7 +2,7 @@
<!DOCTYPE multimedia-project>
<multimedia-project version="1.0" creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.4.0-rc3" type="instrumenttracksettings" >
<head/>
<instrumenttracksettings muted="0" type="0" name="Default preset" >
<instrumenttracksettings muted="0" type="0" name="SBass2" >
<instrumenttrack pan="0" fxch="0" pitch="0" basenote="81" vol="175" >
<instrument name="tripleoscillator" >
<tripleoscillator phoffset2="240" userwavefile0="" finer0="0" userwavefile1="" finer1="-2" userwavefile2="" finer2="2" coarse0="0" coarse1="0" coarse2="0" finel0="0" finel1="2" modalgo1="0" modalgo2="0" finel2="-2" pan0="0" modalgo3="2" pan1="0" stphdetun0="0" pan2="0" stphdetun1="0" wavetype0="2" stphdetun2="0" wavetype1="1" wavetype2="0" vol0="33" vol1="33" phoffset0="0" phoffset1="120" vol2="33" />

View File

@@ -2,7 +2,7 @@
<!DOCTYPE multimedia-project>
<multimedia-project version="1.0" creator="Linux MultiMedia Studio (LMMS)" creatorversion="0.4.0-rc3" type="instrumenttracksettings" >
<head/>
<instrumenttracksettings muted="0" type="0" name="Default preset" >
<instrumenttracksettings muted="0" type="0" name="SEGuitar" >
<instrumenttrack pan="0" fxch="0" pitch="0" basenote="69" vol="200" >
<instrument name="tripleoscillator" >
<tripleoscillator phoffset2="0" userwavefile0="" finer0="-2" userwavefile1="" finer1="2" userwavefile2="" finer2="0" coarse0="0" coarse1="0" coarse2="0" finel0="0" finel1="-2" modalgo1="1" modalgo2="0" finel2="-2" pan0="0" modalgo3="2" pan1="0" stphdetun0="0" pan2="0" stphdetun1="0" wavetype0="5" stphdetun2="0" wavetype1="5" wavetype2="5" vol0="33" vol1="33" phoffset0="0" phoffset1="0" vol2="33" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1006 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1006 B

After

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 985 B

After

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 860 B

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 852 B

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 894 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1012 B

After

Width:  |  Height:  |  Size: 726 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 709 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1006 B

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,7 +1,7 @@
/*
* AutomatableModelView.h - class AutomatableModelView
*
* Copyright (c) 2008-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -101,6 +101,7 @@ public slots:
void execConnectionDialog();
void removeConnection();
void editSongGlobalAutomation();
void removeSongGlobalAutomation();
protected:

View File

@@ -2,7 +2,7 @@
* AutomationPattern.h - declaration of class AutomationPattern, which contains
* all information about an automation pattern
*
* Copyright (c) 2008-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2006-2008 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
@@ -109,6 +109,8 @@ public slots:
private:
void cleanObjects();
AutomationTrack * m_autoTrack;
QVector<jo_id_t> m_idsToResolve;
objectVector m_objects;

View File

@@ -1,7 +1,7 @@
/*
* main_window.h - declaration of class MainWindow, the main window of LMMS
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -106,7 +106,7 @@ public slots:
void aboutLMMS( void );
void help( void );
void toggleAutomationEditorWin( void );
void toggleBBEditorWin( void );
void toggleBBEditorWin( bool forceShow = false );
void toggleSongEditorWin( void );
void toggleProjectNotesWin( void );
void toggleFxMixerWin( void );
@@ -132,7 +132,7 @@ private:
void finalize( void );
void toggleWindow( QWidget * _w );
void toggleWindow( QWidget *window, bool forceShow = false );
QMdiArea * m_workspace;

View File

@@ -27,6 +27,7 @@
#include "export.h"
#include "midi.h"
#include "VST_sync_shm.h"
#include <vector>
#include <cstdio>
@@ -811,7 +812,9 @@ class RemotePluginClient : public RemotePluginBase
public:
RemotePluginClient( key_t _shm_in, key_t _shm_out );
virtual ~RemotePluginClient();
#ifdef USE_QT_SHMEM
sncVST * getQtVSTshm();
#endif
virtual bool processMessage( const message & _m );
virtual void process( const sampleFrame * _in_buf,
@@ -879,7 +882,9 @@ private:
#ifdef USE_QT_SHMEM
QSharedMemory m_shmObj;
QSharedMemory m_shmQtID;
#endif
sncVST * m_SncVSTplug;
float * m_shm;
int m_inputCount;
@@ -1007,13 +1012,60 @@ RemotePluginClient::RemotePluginClient( key_t _shm_in, key_t _shm_out ) :
RemotePluginBase( new shmFifo( _shm_in ), new shmFifo( _shm_out ) ),
#ifdef USE_QT_SHMEM
m_shmObj(),
m_shmQtID( "/usr/bin/lmms" ),
#endif
m_SncVSTplug( NULL ),
m_shm( NULL ),
m_inputCount( 0 ),
m_outputCount( 0 ),
m_sampleRate( 44100 ),
m_bufferSize( 0 )
{
#ifdef USE_QT_SHMEM
if( m_shmQtID.attach( QSharedMemory::ReadOnly ) )
{
m_SncVSTplug = (sncVST *) m_shmQtID.data();
m_bufferSize = m_SncVSTplug->m_bufferSize;
m_sampleRate = m_SncVSTplug->m_sampleRate;
return;
}
#else
key_t key;
int m_shmID;
if( ( key = ftok( VST_SNC_SHM_KEY_FILE, 'R' ) ) == -1 )
{
perror( "RemotePluginClient::ftok" );
}
else
{ // connect to shared memory segment
if( ( m_shmID = shmget( key, 0, 0 ) ) == -1 )
{
perror( "RemotePluginClient::shmget" );
}
else
{ // attach segment
m_SncVSTplug = (sncVST *)shmat(m_shmID, 0, 0);
if( m_SncVSTplug == (sncVST *)( -1 ) )
{
perror( "RemotePluginClient::shmat" );
}
else
{
m_bufferSize = m_SncVSTplug->m_bufferSize;
m_sampleRate = m_SncVSTplug->m_sampleRate;
// detach segment
if( shmdt(m_SncVSTplug) == -1 )
{
perror("RemotePluginClient::shmdt");
}
return;
}
}
}
#endif
// if attaching shared memory fails
sendMessage( IdSampleRateInformation );
sendMessage( IdBufferSizeInformation );
}
@@ -1023,6 +1075,9 @@ RemotePluginClient::RemotePluginClient( key_t _shm_in, key_t _shm_out ) :
RemotePluginClient::~RemotePluginClient()
{
#ifdef USE_QT_SHMEM
m_shmQtID.detach();
#endif
sendMessage( IdQuit );
#ifndef USE_QT_SHMEM
@@ -1032,6 +1087,14 @@ RemotePluginClient::~RemotePluginClient()
#ifdef USE_QT_SHMEM
sncVST * RemotePluginClient::getQtVSTshm()
{
return m_SncVSTplug;
}
#endif
bool RemotePluginClient::processMessage( const message & _m )
{

58
include/VST_sync_shm.h Normal file
View File

@@ -0,0 +1,58 @@
/*
* VST_sync_shm.h - type declarations needed for VST to lmms host sync
*
* Copyright (c) 2004-2013 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 _VST_SYNC_SHM_H
#define _VST_SYNC_SHM_H
// VST sync frequency (in ms), how often will be VST plugin synced
// keep it power of two if possible (not used by now)
//#define VST_SNC_TIMER 1
// When defined, latency should be subtracted from song PPQ position
//#define VST_SNC_LATENCY
// define file for ftok as shared memory shmget key
#define VST_SNC_SHM_KEY_FILE "/dev/null"
//#define VST_SNC_SHM_RND_KEY 3561653564469
struct sncVST
{
bool isPlayin;
float ppqPos;
int timeSigNumer;
int timeSigDenom;
bool isCycle;
bool hasSHM;
float cycleStart;
float cycleEnd;
int m_bufferSize;
int m_sampleRate;
int m_bpm;
#ifdef VST_SNC_LATENCY
float m_latency;
#endif
} ;
#endif

View File

@@ -114,8 +114,14 @@ const int kEffectMagic = CCONST( 'V', 's', 't', 'P' );
const int kVstLangEnglish = 1;
const int kVstMidiType = 1;
const int kVstParameterUsesFloatStep = 1 << 2;
const int kVstPpqPosValid = 1 << 9;
const int kVstTempoValid = 1 << 10;
const int kVstBarsValid = 1 << 11;
const int kVstCyclePosValid = 1 << 12;
const int kVstTimeSigValid = 1 << 13;
const int kVstTransportPlaying = 1 << 1;
const int kVstTransportCycleActive = 1 << 2;
const int kVstTransportChanged = 1;
class RemoteVstPlugin;
@@ -267,12 +273,18 @@ public:
double samplePos;
// 08
double sampleRate;
// unconfirmed 10 18
char empty1[8 + 8];
// unconfirmed 10
char empty1[8];
// 18
double ppqPos;
// 20?
double tempo;
// unconfirmed 28 30 38
char empty2[8 + 8 + 8];
// 28
double barStartPos;
// 30?
double cycleStartPos;
// 38?
double cycleEndPos;
// 40?
int timeSigNumerator;
// 44?

View File

@@ -59,6 +59,7 @@ private slots:
private:
QString m_fileName;
QString m_dirName;
QString m_fileExtension;
typedef QVector<ProjectRenderer*> RenderVector;
RenderVector m_renderers;
bool m_multiExport;

View File

@@ -1,7 +1,7 @@
/*
* midi.h - constants, structs etc. concerning MIDI
*
* Copyright (c) 2005-2012 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -98,6 +98,16 @@ enum MidiStandardControllers
MidiControllerSostenuto = 66,
MidiControllerSoftPedal = 67,
MidiControllerLegatoFootswitch = 68,
// Channel Mode Messages are controllers too...
MidiControllerAllSoundOff = 120,
MidiControllerResetAllControllers = 121,
MidiControllerLocalControl = 122,
MidiControllerAllNotesOff = 123,
MidiControllerOmniOn = 124,
MidiControllerOmniOff = 125,
MidiControllerMonoOn = 126,
MidiControllerPolyOn = 127,
};
const int MidiChannelCount = 16;
@@ -122,7 +132,8 @@ struct midiEvent
m_metaEvent( MidiMetaInvalid ),
m_channel( _channel ),
m_sysExData( NULL ),
m_sourcePort( _sourcePort )
m_sourcePort( _sourcePort ),
m_fromMidiPort( false )
{
m_data.m_param[0] = _param1;
m_data.m_param[1] = _param2;
@@ -134,7 +145,8 @@ struct midiEvent
m_metaEvent( MidiMetaInvalid ),
m_channel( 0 ),
m_sysExData( _sysex_data ),
m_sourcePort( NULL )
m_sourcePort( NULL ),
m_fromMidiPort( false )
{
m_data.m_sysExDataLen = _data_len;
}
@@ -145,7 +157,8 @@ struct midiEvent
m_channel( _copy.m_channel ),
m_data( _copy.m_data ),
m_sysExData( _copy.m_sysExData ),
m_sourcePort( _copy.m_sourcePort )
m_sourcePort( _copy.m_sourcePort ),
m_fromMidiPort( _copy.m_fromMidiPort )
{
}
@@ -212,6 +225,15 @@ struct midiEvent
( (float)( PanningRight - PanningLeft ) ) );
}
void setFromMidiPort( bool enabled )
{
m_fromMidiPort = enabled;
}
bool isFromMidiPort() const
{
return m_fromMidiPort;
}
MidiEventTypes m_type; // MIDI event type
MidiMetaEvents m_metaEvent; // Meta event (mostly unused)
@@ -226,6 +248,10 @@ struct midiEvent
const char * m_sysExData;
const void * m_sourcePort;
private:
bool m_fromMidiPort;
} ;

View File

@@ -108,6 +108,7 @@ private slots:
void toggleAutoSave( bool _enabled );
void toggleOneInstrumentTrackWindow( bool _enabled );
void toggleCompactTrackButtons( bool _enabled );
void toggleSyncVSTPlugins( bool _enabled );
private:
@@ -156,6 +157,7 @@ private:
bool m_enableAutoSave;
bool m_oneInstrumentTrackWindow;
bool m_compactTrackButtons;
bool m_syncVSTPlugins;
typedef QMap<QString, AudioDevice::setupWidget *> AswMap;
typedef QMap<QString, MidiClient::setupWidget *> MswMap;

View File

@@ -25,13 +25,14 @@
#ifndef _SONG_H
#define _SONG_H
#include <QtCore/QSharedMemory>
#include <QtCore/QVector>
#include "track_container.h"
#include "AutomatableModel.h"
#include "Controller.h"
#include "MeterModel.h"
#include "VST_sync_shm.h"
class AutomationTrack;
class pattern;
@@ -249,6 +250,8 @@ private slots:
void updateFramesPerTick();
void updateSampleRateSHM();
private:
@@ -323,6 +326,9 @@ private:
} ;
QVector<Actions> m_actions;
int m_shmID;
sncVST * m_SncVSTplug;
QSharedMemory m_shmQtID;
friend class engine;
friend class songEditor;

View File

@@ -2,7 +2,7 @@ lmmsicon ICON data/lmms.ico
#include <windows.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,4,13,0
FILEVERSION 0,4,14,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
@@ -17,7 +17,7 @@ BEGIN
VALUE "CompanyName", "LMMS Developers\0"
VALUE "FileDescription", "Linux MultiMedia Studio\0"
VALUE "FileVersion", "@VERSION@\0"
VALUE "LegalCopyright", "Copyright (c) 2004-2012 LMMS Developers\0"
VALUE "LegalCopyright", "Copyright (c) 2004-2013 LMMS Developers\0"
VALUE "OriginalFilename", "lmms.exe\0"
VALUE "ProductName", "LMMS\0"
VALUE "ProductVersion", "@VERSION@\0"

View File

@@ -2,6 +2,7 @@ ADD_SUBDIRECTORY(audio_file_processor)
ADD_SUBDIRECTORY(bass_booster)
ADD_SUBDIRECTORY(bit_invader)
ADD_SUBDIRECTORY(flp_import)
ADD_SUBDIRECTORY(HydrogenImport)
ADD_SUBDIRECTORY(kicker)
ADD_SUBDIRECTORY(ladspa_browser)
ADD_SUBDIRECTORY(ladspa_effect)

View File

@@ -0,0 +1,4 @@
INCLUDE(BuildPlugin)
BUILD_PLUGIN(hydrogenimport HydrogenImport.cpp HydrogenImport.h local_file_mgr.cpp LocalFileMng.h)

View File

@@ -0,0 +1,404 @@
#include <QtXml/QDomDocument>
#include <QtCore/QDir>
#include <QtGui/QApplication>
#include <QtGui/QMessageBox>
#include <QtGui/QProgressDialog>
#include <QTextStream>
#include <stdlib.h>
#include "LocalFileMng.h"
#include "HydrogenImport.h"
#include "song.h"
#include "engine.h"
#include "Instrument.h"
#include "InstrumentTrack.h"
#include "note.h"
#include "pattern.h"
#include "track.h"
#include "bb_track.h"
#include "bb_track_container.h"
#include "Instrument.h"
#define MAX_LAYERS 4
extern "C"
{
Plugin::Descriptor PLUGIN_EXPORT hydrogenimport_plugin_descriptor =
{
STRINGIFY( PLUGIN_NAME ),
"Hydrogen Import",
QT_TRANSLATE_NOOP( "pluginBrowser",
"Filter for importing Hydrogen files into LMMS" ),
"frank mather",
0x0100,
Plugin::ImportFilter,
NULL,
NULL,
NULL
} ;
}
QString filename;
class NoteKey
{
public:
enum Key {
C = 0,
Cs,
D,
Ef,
E,
F,
Fs,
G,
Af,
A,
Bf,
B,
};
static int stringToNoteKey( const QString& str )
{
int m_key;
QString sKey = str.left( str.length() - 1 );
QString sOct = str.mid( str.length() - 1, str.length() );
if ( sKey.endsWith( "-" ) )
{
sKey.replace( "-", "" );
sOct.insert( 0, "-" );
}
int nOctave = sOct.toInt();
if ( sKey == "C" )
{
m_key = NoteKey::C;
}
else if ( sKey == "Cs" )
{
m_key = NoteKey::Cs;
}
else if ( sKey == "D" )
{
m_key = NoteKey::D;
}
else if ( sKey == "Ef" )
{
m_key = NoteKey::Ef;
}
else if ( sKey == "E" )
{
m_key = NoteKey::E;
}
else if ( sKey == "F" )
{
m_key = NoteKey::F;
}
else if ( sKey == "Fs" )
{
m_key = NoteKey::Fs;
}
else if ( sKey == "G" )
{
m_key = NoteKey::G;
}
else if ( sKey == "Af" )
{
m_key = NoteKey::Af;
}
else if ( sKey == "A" )
{
m_key = NoteKey::A;
}
else if ( sKey == "Bf" )
{
m_key = NoteKey::Bf;
}
else if ( sKey == "B" ) {
m_key = NoteKey::B;
}
return m_key + (nOctave*12)+57;
}
};
HydrogenImport::HydrogenImport( const QString & _file ) :
ImportFilter( _file, &hydrogenimport_plugin_descriptor )
{
filename = _file;
}
HydrogenImport::~HydrogenImport()
{
}
Instrument * ins;
bool HydrogenImport::readSong()
{
QHash<QString, InstrumentTrack *> drum_track;
QHash<QString, int> pattern_length;
QHash<QString, int> pattern_id;
song *s = engine::getSong();
int song_num_tracks = s->tracks().size();
if ( QFile( filename ).exists() == false )
{
printf( "Song file not found \n" );
return false;
}
QDomDocument doc = LocalFileMng::openXmlDocument( filename );
QDomNodeList nodeList = doc.elementsByTagName( "song" );
if( nodeList.isEmpty() )
{
printf( "Error reading song: song node not found\n" );
return NULL;
}
QDomNode songNode = nodeList.at( 0 );
QString m_sSongVersion = LocalFileMng::readXmlString( songNode , "version", "Unknown version" );
float fBpm = LocalFileMng::readXmlFloat( songNode, "bpm", 120 );
float fVolume = LocalFileMng::readXmlFloat( songNode, "volume", 0.5 );
float fMetronomeVolume = LocalFileMng::readXmlFloat( songNode, "metronomeVolume", 0.5 );
QString sName( LocalFileMng::readXmlString( songNode, "name", "Untitled Song" ) );
QString sAuthor( LocalFileMng::readXmlString( songNode, "author", "Unknown Author" ) );
QString sNotes( LocalFileMng::readXmlString( songNode, "notes", "..." ) );
QString sLicense( LocalFileMng::readXmlString( songNode, "license", "Unknown license" ) );
bool bLoopEnabled = LocalFileMng::readXmlBool( songNode, "loopEnabled", false );
QString sMode = LocalFileMng::readXmlString( songNode, "mode", "pattern" );
float fHumanizeTimeValue = LocalFileMng::readXmlFloat( songNode, "humanize_time", 0.0 );
float fHumanizeVelocityValue = LocalFileMng::readXmlFloat( songNode, "humanize_velocity", 0.0 );
float fSwingFactor = LocalFileMng::readXmlFloat( songNode, "swing_factor", 0.0 );
QDomNode instrumentListNode = songNode.firstChildElement( "instrumentList" );
if ( ( ! instrumentListNode.isNull() ) )
{
int instrumentList_count = 0;
QDomNode instrumentNode;
instrumentNode = instrumentListNode.firstChildElement( "instrument" );
while ( ! instrumentNode.isNull() )
{
instrumentList_count++;
QString sId = LocalFileMng::readXmlString( instrumentNode, "id", "" ); // instrument id
QString sDrumkit = LocalFileMng::readXmlString( instrumentNode, "drumkit", "" ); // drumkit
QString sName = LocalFileMng::readXmlString( instrumentNode, "name", "" ); // name
float fVolume = LocalFileMng::readXmlFloat( instrumentNode, "volume", 1.0 ); // volume
bool bIsMuted = LocalFileMng::readXmlBool( instrumentNode, "isMuted", false ); // is muted
float fPan_L = LocalFileMng::readXmlFloat( instrumentNode, "pan_L", 0.5 ); // pan L
float fPan_R = LocalFileMng::readXmlFloat( instrumentNode, "pan_R", 0.5 ); // pan R
float fFX1Level = LocalFileMng::readXmlFloat( instrumentNode, "FX1Level", 0.0 ); // FX level
float fFX2Level = LocalFileMng::readXmlFloat( instrumentNode, "FX2Level", 0.0 ); // FX level
float fFX3Level = LocalFileMng::readXmlFloat( instrumentNode, "FX3Level", 0.0 ); // FX level
float fFX4Level = LocalFileMng::readXmlFloat( instrumentNode, "FX4Level", 0.0 ); // FX level
float fGain = LocalFileMng::readXmlFloat( instrumentNode, "gain", 1.0, false, false ); // instrument gain
int fAttack = LocalFileMng::readXmlInt( instrumentNode, "Attack", 0, false, false ); // Attack
int fDecay = LocalFileMng::readXmlInt( instrumentNode, "Decay", 0, false, false ); // Decay
float fSustain = LocalFileMng::readXmlFloat( instrumentNode, "Sustain", 1.0, false, false ); // Sustain
int fRelease = LocalFileMng::readXmlInt( instrumentNode, "Release", 1000, false, false ); // Release
float fRandomPitchFactor = LocalFileMng::readXmlFloat( instrumentNode, "randomPitchFactor", 0.0f, false, false );
bool bFilterActive = LocalFileMng::readXmlBool( instrumentNode, "filterActive", false );
float fFilterCutoff = LocalFileMng::readXmlFloat( instrumentNode, "filterCutoff", 1.0f, false );
float fFilterResonance = LocalFileMng::readXmlFloat( instrumentNode, "filterResonance", 0.0f, false );
QString sMuteGroup = LocalFileMng::readXmlString( instrumentNode, "muteGroup", "-1", false );
QString sMidiOutChannel = LocalFileMng::readXmlString( instrumentNode, "midiOutChannel", "-1", false, false );
QString sMidiOutNote = LocalFileMng::readXmlString( instrumentNode, "midiOutNote", "60", false, false );
int nMuteGroup = sMuteGroup.toInt();
bool isStopNote = LocalFileMng::readXmlBool( instrumentNode, "isStopNote", false );
int nMidiOutChannel = sMidiOutChannel.toInt();
int nMidiOutNote = sMidiOutNote.toInt();
if ( sId.isEmpty() ) {
printf( "Empty ID for instrument. skipping \n" );
instrumentNode = (QDomNode) instrumentNode.nextSiblingElement( "instrument" );
continue;
}
QDomNode filenameNode = instrumentNode.firstChildElement( "filename" );
if ( ! filenameNode.isNull() )
{
return false;
}
else
{
unsigned nLayer = 0;
QDomNode layerNode = instrumentNode.firstChildElement( "layer" );
while ( ! layerNode.isNull() )
{
if ( nLayer >= MAX_LAYERS )
{
printf( "nLayer >= MAX_LAYERS" );
continue;
}
QString sFilename = LocalFileMng::readXmlString( layerNode, "filename", "" );
bool sIsModified = LocalFileMng::readXmlBool( layerNode, "ismodified", false );
QString sMode = LocalFileMng::readXmlString( layerNode, "smode", "forward" );
unsigned sStartframe = LocalFileMng::readXmlInt( layerNode, "startframe", 0 );
unsigned sLoopFrame = LocalFileMng::readXmlInt( layerNode, "loopframe", 0 );
int sLoops = LocalFileMng::readXmlInt( layerNode, "loops", 0 );
unsigned sEndframe = LocalFileMng::readXmlInt( layerNode, "endframe", 0 );
bool sUseRubber = LocalFileMng::readXmlInt( layerNode, "userubber", 0, false );
float sRubberDivider = LocalFileMng::readXmlFloat( layerNode, "rubberdivider", 0.0 );
int sRubberCsettings = LocalFileMng::readXmlInt( layerNode, "rubberCsettings", 1 );
int sRubberPitch = LocalFileMng::readXmlFloat( layerNode, "rubberPitch", 0.0 );
float fMin = LocalFileMng::readXmlFloat( layerNode, "min", 0.0 );
float fMax = LocalFileMng::readXmlFloat( layerNode, "max", 1.0 );
float fGain = LocalFileMng::readXmlFloat( layerNode, "gain", 1.0 );
float fPitch = LocalFileMng::readXmlFloat( layerNode, "pitch", 0.0, false, false );
if ( nLayer == 0 )
{
drum_track[sId] = ( InstrumentTrack * ) track::create( track::InstrumentTrack,engine::getBBTrackContainer() );
drum_track[sId]->volumeModel()->setValue( fVolume * 100 );
drum_track[sId]->panningModel()->setValue( ( fPan_R - fPan_L ) * 100 );
ins = drum_track[sId]->loadInstrument( "audiofileprocessor" );
ins->loadFile( sFilename );
}
nLayer++;
layerNode = ( QDomNode ) layerNode.nextSiblingElement( "layer" );
}
}
instrumentNode = (QDomNode) instrumentNode.nextSiblingElement( "instrument" );
}
if ( instrumentList_count == 0 )
{
return false;
}
}
else
{
return false;
}
QDomNode patterns = songNode.firstChildElement( "patternList" );
int pattern_count = 0;
int nbb = engine::getBBTrackContainer()->numOfBBs();
QDomNode patternNode = patterns.firstChildElement( "pattern" );
int pn = 1;
while ( !patternNode.isNull() )
{
if ( pn > 0 )
{
pattern_count++;
s->addBBTrack();
pn = 0;
}
QString sName; // name
sName = LocalFileMng::readXmlString( patternNode, "name", sName );
QString sCategory = ""; // category
sCategory = LocalFileMng::readXmlString( patternNode, "category", sCategory ,false ,false );
int nSize = -1;
nSize = LocalFileMng::readXmlInt( patternNode, "size", nSize, false, false );
pattern_length[sName] = nSize;
QDomNode pNoteListNode = patternNode.firstChildElement( "noteList" );
if ( ! pNoteListNode.isNull() ) {
QDomNode noteNode = pNoteListNode.firstChildElement( "note" );
while ( ! noteNode.isNull() ) {
unsigned nPosition = LocalFileMng::readXmlInt( noteNode, "position", 0 );
float fLeadLag = LocalFileMng::readXmlFloat( noteNode, "leadlag", 0.0 , false , false );
float fVelocity = LocalFileMng::readXmlFloat( noteNode, "velocity", 0.8f );
float fPan_L = LocalFileMng::readXmlFloat( noteNode, "pan_L", 0.5 );
float fPan_R = LocalFileMng::readXmlFloat( noteNode, "pan_R", 0.5 );
int nLength = LocalFileMng::readXmlInt( noteNode, "length", -1, true );
float nPitch = LocalFileMng::readXmlFloat( noteNode, "pitch", 0.0, false, false );
QString sKey = LocalFileMng::readXmlString( noteNode, "key", "C0", false, false );
QString nNoteOff = LocalFileMng::readXmlString( noteNode, "note_off", "false", false, false );
QString instrId = LocalFileMng::readXmlString( noteNode, "instrument", 0,false, false );
int i = pattern_count - 1 + nbb;
pattern_id[sName] = pattern_count - 1;
pattern *p = dynamic_cast<pattern *>( drum_track[instrId]->getTCO( i ) );
note n;
n.setPos( nPosition );
if ( (nPosition + 48) <= nSize )
{
n.setLength( 48 );
}
else
{
n.setLength( nSize - nPosition );
}
n.setVolume( fVelocity * 100 );
n.setPanning( ( fPan_R - fPan_L ) * 100 );
n.setKey( NoteKey::stringToNoteKey( sKey ) );
p->addNote( n,false );
pn = pn + 1;
noteNode = ( QDomNode ) noteNode.nextSiblingElement( "note" );
}
}
patternNode = ( QDomNode ) patternNode.nextSiblingElement( "pattern" );
}
// Pattern sequence
QDomNode patternSequenceNode = songNode.firstChildElement( "patternSequence" );
QDomNode groupNode = patternSequenceNode.firstChildElement( "group" );
int pos = 0;
while ( !groupNode.isNull() )
{
int best_length = 0;
QDomNode patternId = groupNode.firstChildElement( "patternID" );
while ( !patternId.isNull() )
{
QString patId = patternId.firstChild().nodeValue();
patternId = ( QDomNode ) patternId.nextSiblingElement( "patternID" );
int i = pattern_id[patId]+song_num_tracks;
track *t = ( bbTrack * ) s->tracks().at( i );
trackContentObject *tco = t->createTCO( pos );
tco->movePosition( pos );
if ( pattern_length[patId] > best_length )
{
best_length = pattern_length[patId];
}
}
pos = pos + best_length;
groupNode = groupNode.nextSiblingElement( "group" );
}
if ( pattern_count == 0 )
{
return false;
}
return true;
}
bool HydrogenImport::tryImport( trackContainer * _tc )
{
if( openFile() == false )
{
return false;
}
return readSong();
}
extern "C"
{
// necessary for getting instance out of shared lib
Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data )
{
return new HydrogenImport( QString::fromUtf8(
static_cast<const char *>( _data ) ) );
}
}

View File

@@ -0,0 +1,27 @@
#ifndef _HYDROGEN_IMPORT_H
#define _HYDROGEN_IMPORT_H
#include <QtCore/QString>
#include <QtCore/QPair>
#include <QtCore/QVector>
#include "ImportFilter.h"
class HydrogenImport : public ImportFilter
{
public:
HydrogenImport( const QString & _file );
bool readSong();
virtual ~HydrogenImport();
virtual PluginView * instantiateView( QWidget * )
{
return( NULL );
}
private:
virtual bool tryImport( trackContainer * _tc );
};
#endif

View File

@@ -0,0 +1,29 @@
#ifndef LFILEMNG_H
#define LFILEMNG_H
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <QDomDocument>
class LocalFileMng
{
public:
LocalFileMng();
~LocalFileMng();
std::vector<QString> getallPatternList(){
return m_allPatternList;
}
static QString readXmlString( QDomNode , const QString& nodeName, const QString& defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false);
static float readXmlFloat( QDomNode , const QString& nodeName, float defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false);
static int readXmlInt( QDomNode , const QString& nodeName, int defaultValue, bool bCanBeEmpty = false, bool bShouldExists = true , bool tinyXmlCompatMode = false);
static bool readXmlBool( QDomNode , const QString& nodeName, bool defaultValue, bool bShouldExists = true , bool tinyXmlCompatMode = false );
static void convertFromTinyXMLString( QByteArray* str );
static bool checkTinyXMLCompatMode( const QString& filename );
static QDomDocument openXmlDocument( const QString& filename );
std::vector<QString> m_allPatternList;
};
#endif //LFILEMNG_H

View File

@@ -0,0 +1,234 @@
#include <cstdlib>
#include <cassert>
#include <sys/stat.h>
#include <ctype.h>
#include <QDir>
#include <QApplication>
#include <QVector>
#include <QDomDocument>
#include <QLocale>
#include <QTextCodec>
#include <algorithm>
#include "LocalFileMng.h"
/* New QtXml based methods */
QString LocalFileMng::readXmlString( QDomNode node , const QString& nodeName, const QString& defaultValue, bool bCanBeEmpty, bool bShouldExists, bool tinyXmlCompatMode)
{
QDomElement element = node.firstChildElement( nodeName );
if( !node.isNull() && !element.isNull() ){
if( !element.text().isEmpty() ){
return element.text();
} else {
if ( !bCanBeEmpty ) {
//_WARNINGLOG( "Using default value in " + nodeName );
}
return defaultValue;
}
} else {
if( bShouldExists ){
//_WARNINGLOG( "'" + nodeName + "' node not found" );
}
return defaultValue;
}
}
float LocalFileMng::readXmlFloat( QDomNode node , const QString& nodeName, float defaultValue, bool bCanBeEmpty, bool bShouldExists, bool tinyXmlCompatMode)
{
QLocale c_locale = QLocale::c();
QDomElement element = node.firstChildElement( nodeName );
if( !node.isNull() && !element.isNull() ){
if( !element.text().isEmpty() ){
return c_locale.toFloat(element.text());
} else {
if ( !bCanBeEmpty ) {
//_WARNINGLOG( "Using default value in " + nodeName );
}
return defaultValue;
}
} else {
if( bShouldExists ){
//_WARNINGLOG( "'" + nodeName + "' node not found" );
}
return defaultValue;
}
}
int LocalFileMng::readXmlInt( QDomNode node , const QString& nodeName, int defaultValue, bool bCanBeEmpty, bool bShouldExists, bool tinyXmlCompatMode)
{
QLocale c_locale = QLocale::c();
QDomElement element = node.firstChildElement( nodeName );
if( !node.isNull() && !element.isNull() ){
if( !element.text().isEmpty() ){
return c_locale.toInt( element.text() );
} else {
if ( !bCanBeEmpty ) {
//_WARNINGLOG( "Using default value in " + nodeName );
}
return defaultValue;
}
} else {
if( bShouldExists ){
//_WARNINGLOG( "'" + nodeName + "' node not found" );
}
return defaultValue;
}
}
bool LocalFileMng::readXmlBool( QDomNode node , const QString& nodeName, bool defaultValue, bool bShouldExists, bool tinyXmlCompatMode)
{
QDomElement element = node.firstChildElement( nodeName );
if( !node.isNull() && !element.isNull() ){
if( !element.text().isEmpty() ){
if( element.text() == "true"){
return true;
} else {
return false;
}
} else {
//_WARNINGLOG( "Using default value in " + nodeName );
return defaultValue;
}
} else {
if( bShouldExists ){
//_WARNINGLOG( "'" + nodeName + "' node not found" );
}
return defaultValue;
}
}
/* Convert (in-place) an XML escape sequence into a literal byte,
* rather than the character it actually refers to.
*/
void LocalFileMng::convertFromTinyXMLString( QByteArray* str )
{
/* When TinyXML encountered a non-ASCII character, it would
* simply write the character as "&#xx;" -- where "xx" is
* the hex character code. However, this doesn't respect
* any encodings (e.g. UTF-8, UTF-16). In XML, &#xx; literally
* means "the Unicode character # xx." However, in a UTF-8
* sequence, this could be an escape character that tells
* whether we have a 2, 3, or 4-byte UTF-8 sequence.
*
* For example, the UTF-8 sequence 0xD184 was being written
* by TinyXML as "&#xD1;&#x84;". However, this is the UTF-8
* sequence for the cyrillic small letter EF (which looks
* kind of like a thorn or a greek phi). This letter, in
* XML, should be saved as &#x00000444;, or even literally
* (no escaping). As a consequence, when &#xD1; is read
* by an XML parser, it will be interpreted as capital N
* with a tilde (~). Then &#x84; will be interpreted as
* an unknown or control character.
*
* So, when we know that TinyXML wrote the file, we can
* simply exchange these hex sequences to literal bytes.
*/
int pos = 0;
pos = str->indexOf("&#x");
while( pos != -1 ) {
if( isxdigit(str->at(pos+3))
&& isxdigit(str->at(pos+4))
&& (str->at(pos+5) == ';') ) {
char w1 = str->at(pos+3);
char w2 = str->at(pos+4);
w1 = tolower(w1) - 0x30; // '0' = 0x30
if( w1 > 9 ) w1 -= 0x27; // '9' = 0x39, 'a' = 0x61
w1 = (w1 & 0xF);
w2 = tolower(w2) - 0x30; // '0' = 0x30
if( w2 > 9 ) w2 -= 0x27; // '9' = 0x39, 'a' = 0x61
w2 = (w2 & 0xF);
char ch = (w1 << 4) | w2;
(*str)[pos] = ch;
++pos;
str->remove(pos, 5);
}
pos = str->indexOf("&#x");
}
}
bool LocalFileMng::checkTinyXMLCompatMode( const QString& filename )
{
/*
Check if filename was created with TinyXml or QtXml
TinyXML: return true
QtXml: return false
*/
QFile file( filename );
if ( !file.open(QIODevice::ReadOnly) )
return false;
QString line = file.readLine();
file.close();
if ( line.startsWith( "<?xml" )){
return false;
} else {
//_WARNINGLOG( QString("File '%1' is being read in "
// "TinyXML compatability mode")
// .arg(filename) );
return true;
}
}
QDomDocument LocalFileMng::openXmlDocument( const QString& filename )
{
bool TinyXMLCompat = LocalFileMng::checkTinyXMLCompatMode( filename );
QDomDocument doc;
QFile file( filename );
if ( !file.open(QIODevice::ReadOnly) )
return QDomDocument();
if( TinyXMLCompat ) {
QString enc = QTextCodec::codecForLocale()->name();
if( enc == QString("System") ) {
enc = "UTF-8";
}
QByteArray line;
QByteArray buf = QString("<?xml version='1.0' encoding='%1' ?>\n")
.arg( enc )
.toLocal8Bit();
//_INFOLOG( QString("Using '%1' encoding for TinyXML file").arg(enc) );
while( !file.atEnd() ) {
line = file.readLine();
LocalFileMng::convertFromTinyXMLString( &line );
buf += line;
}
if( ! doc.setContent( buf ) ) {
file.close();
return QDomDocument();
}
} else {
if( ! doc.setContent( &file ) ) {
file.close();
return QDomDocument();
}
}
file.close();
return doc;
}

View File

@@ -542,7 +542,15 @@ AudioFileProcessorWaveView::AudioFileProcessorWaveView( QWidget * _parent, int _
void AudioFileProcessorWaveView::isPlaying( f_cnt_t _frames_played )
{
m_framesPlayed = _frames_played % ( m_sampleBuffer.endFrame() - m_sampleBuffer.startFrame() );
const f_cnt_t nb_frames = m_sampleBuffer.endFrame() - m_sampleBuffer.startFrame();
if( nb_frames < 1 )
{
m_framesPlayed = 0;
}
else
{
m_framesPlayed = _frames_played % nb_frames;
}
update();
}
@@ -919,6 +927,10 @@ void AudioFileProcessorWaveView::slideSamplePointByFrames( knobType _point, f_cn
void AudioFileProcessorWaveView::slideSampleByFrames( f_cnt_t _frames )
{
if( m_sampleBuffer.frames() <= 1 )
{
return;
}
const double v = double( _frames ) / m_sampleBuffer.frames();
m_startKnob->slideBy( v, false );
m_endKnob->slideBy( v, false );

View File

@@ -2,7 +2,7 @@
* sf2_player.cpp - a soundfont2 player using fluidSynth
*
* Copyright (c) 2008 Paul Giblock <drfaygo/at/gmail/dot/com>
* Copyright (c) 2009-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2009-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -389,6 +389,8 @@ void sf2Instrument::openFile( const QString & _sf2File )
}
delete[] sf2Ascii;
instrumentTrack()->setName( QFileInfo( _sf2File ).baseName() );
}

View File

@@ -117,22 +117,31 @@ void vestigeInstrument::loadSettings( const QDomElement & _this )
m_plugin->loadSettings( _this );
const QMap<QString, QString> & dump = m_plugin->parameterDump();
int paramCount = (dump).size();
paramCount = dump.size();
char paramStr[35];
vstKnobs = new knob *[paramCount];
knobFModel = new FloatModel *[paramCount];
QStringList list1;
vstKnobs = new knob *[ paramCount ];
knobFModel = new FloatModel *[ paramCount ];
QStringList s_dumpValues;
QWidget * widget = new QWidget();
for (int i = 0; i < paramCount; i++) {
sprintf( paramStr, "param%d", i);
list1 = dump[paramStr].split(":");
for( int i = 0; i < paramCount; i++ )
{
sprintf( paramStr, "param%d", i );
s_dumpValues = dump[ paramStr ].split( ":" );
vstKnobs[i] = new knob( knobBright_26, widget );
vstKnobs[i]->setHintText( list1.at(1) + ":", "");
vstKnobs[i]->setLabel( list1.at(1).left(15) );
vstKnobs[i] = new knob( knobBright_26, widget, s_dumpValues.at( 1 ) );
vstKnobs[i]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
vstKnobs[i]->setLabel( s_dumpValues.at( 1 ).left( 15 ) );
knobFModel[i] = new FloatModel( (list1.at(2)).toFloat(), 0.0f, 1.0f, 0.01f, this, QString::number(i) );
knobFModel[i] = new FloatModel( 0.0f, 0.0f, 1.0f, 0.01f, this, QString::number(i) );
knobFModel[i]->loadSettings( _this, paramStr );
if( !( knobFModel[ i ]->isAutomated() ||
knobFModel[ i ]->getControllerConnection() ) )
{
knobFModel[ i ]->setValue( ( s_dumpValues.at( 2 )).toFloat() );
knobFModel[ i ]->setInitValue( ( s_dumpValues.at( 2 )).toFloat() );
}
connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
vstKnobs[i]->setModel( knobFModel[i] );
@@ -167,9 +176,10 @@ void vestigeInstrument::saveSettings( QDomDocument & _doc, QDomElement & _this )
m_plugin->saveSettings( _doc, _this );
if (knobFModel != NULL) {
const QMap<QString, QString> & dump = m_plugin->parameterDump();
int paramCount = (dump).size();
paramCount = dump.size();
char paramStr[35];
for (int i = 0; i < paramCount; i++) {
for( int i = 0; i < paramCount; i++ )
{
if (knobFModel[i]->isAutomated() || knobFModel[i]->getControllerConnection()) {
sprintf( paramStr, "param%d", i);
knobFModel[i]->saveSettings( _doc, _this, paramStr );
@@ -223,7 +233,10 @@ void vestigeInstrument::loadFile( const QString & _file )
InstrumentTrack::tr( "Default preset" );
m_pluginMutex.unlock();
closePlugin();
if ( m_plugin != NULL )
{
closePlugin();
}
m_pluginDLL = _file;
textFloat * tf = textFloat::displayMessage(
@@ -250,7 +263,7 @@ void vestigeInstrument::loadFile( const QString & _file )
return;
}
m_plugin->showEditor();
m_plugin->showEditor( NULL, false );
if( set_ch_name )
{
@@ -308,6 +321,51 @@ bool vestigeInstrument::handleMidiEvent( const midiEvent & _me,
void vestigeInstrument::closePlugin( void )
{
// disconnect all signals
if( knobFModel != NULL )
{
for( int i = 0; i < paramCount; i++ )
{
delete knobFModel[ i ];
delete vstKnobs[ i ];
}
}
if( vstKnobs != NULL )
{
delete [] vstKnobs;
vstKnobs = NULL;
}
if( knobFModel != NULL )
{
delete [] knobFModel;
knobFModel = NULL;
}
if( m_scrollArea != NULL )
{
// delete m_scrollArea;
m_scrollArea = NULL;
}
if( m_subWindow != NULL )
{
m_subWindow->setAttribute( Qt::WA_DeleteOnClose );
m_subWindow->close();
if( m_subWindow != NULL )
{
delete m_subWindow;
}
m_subWindow = NULL;
}
if( p_subWindow != NULL )
{
p_subWindow = NULL;
}
m_pluginMutex.lock();
if( m_plugin )
{
@@ -685,8 +743,7 @@ void VestigeInstrumentView::selPreset( void )
void VestigeInstrumentView::toggleGUI( void )
{
QMutexLocker ml( &m_vi->m_pluginMutex );
if( m_vi->m_plugin == NULL )
if( m_vi == NULL || m_vi->m_plugin == NULL )
{
return;
}
@@ -790,10 +847,16 @@ void VestigeInstrumentView::paintEvent( QPaintEvent * )
p.setPen( QColor( 251, 41, 8 ) );
f.setBold( false );
p.setFont( pointSize<8>( f ) );
p.drawText( 10, 114, tr( "by" ) + " " +
p.drawText( 10, 114, tr( "by " ) +
m_vi->m_plugin->vendorString() );
p.drawText( 10, 225, m_vi->m_plugin->currentProgramName() );
}
if( m_vi->m_subWindow != NULL )
{
m_vi->m_subWindow->setWindowTitle( m_vi->instrumentTrack()->name()
+ tr( " - VST plugin control" ) );
}
// m_pluginMutex.unlock();
}
@@ -814,7 +877,8 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume
m_vi->m_subWindow->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
m_vi->m_subWindow->setFixedSize( 960, 300);
m_vi->m_subWindow->setWidget(m_vi->m_scrollArea);
m_vi->m_subWindow->setWindowTitle(m_vi->m_plugin->name());
m_vi->m_subWindow->setWindowTitle( m_vi->instrumentTrack()->name()
+ tr( " - VST plugin control" ) );
m_vi->m_subWindow->setWindowIcon( PLUGIN_NAME::getIconPixmap( "logo" ) );
//m_vi->m_subWindow->setAttribute(Qt::WA_DeleteOnClose);
@@ -831,49 +895,77 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume
l->addWidget( m_syncButton, 0, 0, 1, 2, Qt::AlignLeft );
m_displayAutomatedOnly = new QPushButton( tr( "Automated" ), this );
connect( m_displayAutomatedOnly, SIGNAL( clicked() ), this,
SLOT( displayAutomatedOnly() ) );
m_displayAutomatedOnly->setWhatsThis(
tr( "Click here if you want to display automated parameters only." ) );
l->addWidget( m_displayAutomatedOnly, 0, 1, 1, 2, Qt::AlignLeft );
m_closeButton = new QPushButton( tr( " Close " ), widget );
connect( m_closeButton, SIGNAL( clicked() ), this,
SLOT( closeWindow() ) );
m_closeButton->setWhatsThis(
tr( "Close VST plugin knob-controller window." ) );
l->addWidget( m_closeButton, 0, 2, 1, 7, Qt::AlignLeft );
for( int i = 0; i < 10; i++ )
{
l->addItem( new QSpacerItem( 68, 45, QSizePolicy::Fixed, QSizePolicy::Fixed ), 0, i );
}
const QMap<QString, QString> & dump = m_vi->m_plugin->parameterDump();
int paramCount = (dump).size();
m_vi->paramCount = dump.size();
bool isVstKnobs = true;
if (m_vi->vstKnobs == NULL) {
m_vi->vstKnobs = new knob *[paramCount];
m_vi->vstKnobs = new knob *[ m_vi->paramCount ];
isVstKnobs = false;
}
if (m_vi->knobFModel == NULL) {
m_vi->knobFModel = new FloatModel *[paramCount];
m_vi->knobFModel = new FloatModel *[ m_vi->paramCount ];
}
char paramStr[35];
QStringList list1;
QStringList s_dumpValues;
if (isVstKnobs == false) {
for (int i = 0; i < paramCount; i++) {
for( int i = 0; i < m_vi->paramCount; i++ )
{
sprintf( paramStr, "param%d", i);
list1 = dump[paramStr].split(":");
s_dumpValues = dump[ paramStr ].split( ":" );
m_vi->vstKnobs[i] = new knob( knobBright_26, this );
m_vi->vstKnobs[i]->setHintText( list1.at(1) + ":", "");
m_vi->vstKnobs[i]->setLabel( list1.at(1).left(15) );
m_vi->vstKnobs[ i ] = new knob( knobBright_26, this, s_dumpValues.at( 1 ) );
m_vi->vstKnobs[ i ]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
m_vi->vstKnobs[ i ]->setLabel( s_dumpValues.at( 1 ).left( 15 ) );
sprintf( paramStr, "%d", i);
m_vi->knobFModel[i] = new FloatModel( (list1.at(2)).toFloat(), 0.0f, 1.0f, 0.01f,
castModel<vestigeInstrument>(), tr( paramStr ) );
m_vi->knobFModel[ i ] = new FloatModel( (s_dumpValues.at( 2 )).toFloat(),
0.0f, 1.0f, 0.01f, castModel<vestigeInstrument>(), tr( paramStr ) );
connect( m_vi->knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
m_vi->vstKnobs[i] ->setModel( m_vi->knobFModel[i] );
}
}
int i = 0;
for (int lrow = 0+1; lrow < (int(paramCount / 10) + 1)+1; lrow++) {
for (int lcolumn = 0; lcolumn < 10; lcolumn++) {
if (i < paramCount)
for( int lrow = 1; lrow < ( int( m_vi->paramCount / 10 ) + 1 ) + 1; lrow++ )
{
for( int lcolumn = 0; lcolumn < 10; lcolumn++ )
{
if( i < m_vi->paramCount )
{
l->addWidget( m_vi->vstKnobs[i], lrow, lcolumn, Qt::AlignCenter );
}
i++;
}
}
l->setRowStretch( (int(paramCount / 10) + 1), 1 );
l->setRowStretch( ( int( m_vi->paramCount / 10) + 1), 1 );
l->setColumnStretch( 10, 1 );
widget->setLayout(l);
@@ -892,29 +984,84 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume
void manageVestigeInstrumentView::closeWindow()
{
m_vi->m_subWindow->hide();
}
void manageVestigeInstrumentView::syncPlugin( void )
{
char paramStr[35];
QStringList list1;
QStringList s_dumpValues;
const QMap<QString, QString> & dump = m_vi->m_plugin->parameterDump();
float f;
float f_value;
for (int i = 0; i<(dump).size(); i++) {
sprintf( paramStr, "param%d", i);
list1 = dump[paramStr].split(":");
f = (list1.at(2)).toFloat();
m_vi->knobFModel[i]->setValue(f);
m_vi->knobFModel[i]->setInitValue(f);
for( int i = 0; i < m_vi->paramCount; i++ )
{
// only not automated knobs are synced from VST
// those auto-setted values are not jurnaled, tracked for undo / redo
if( !( m_vi->knobFModel[ i ]->isAutomated() ||
m_vi->knobFModel[ i ]->getControllerConnection() ) )
{
sprintf( paramStr, "param%d", i );
s_dumpValues = dump[ paramStr ].split( ":" );
f_value = ( s_dumpValues.at( 2 ) ).toFloat();
m_vi->knobFModel[ i ]->setAutomatedValue( f_value );
m_vi->knobFModel[ i ]->setInitValue( f_value );
}
}
}
void manageVestigeInstrumentView::displayAutomatedOnly( void )
{
bool isAuto = QString::compare( m_displayAutomatedOnly->text(), tr( "Automated" ) ) == 0;
for( int i = 0; i< m_vi->paramCount; i++ )
{
if( !( m_vi->knobFModel[ i ]->isAutomated() ||
m_vi->knobFModel[ i ]->getControllerConnection() ) )
{
if( m_vi->vstKnobs[ i ]->isVisible() == true && isAuto )
{
m_vi->vstKnobs[ i ]->hide();
m_displayAutomatedOnly->setText( "All" );
} else {
m_vi->vstKnobs[ i ]->show();
m_displayAutomatedOnly->setText( "Automated" );
}
}
}
}
manageVestigeInstrumentView::~manageVestigeInstrumentView()
{
if( m_vi->knobFModel != NULL )
{
for( int i = 0; i < m_vi->paramCount; i++ )
{
delete m_vi->knobFModel[ i ];
delete m_vi->vstKnobs[ i ];
}
}
if (m_vi->vstKnobs != NULL) {
delete []m_vi->vstKnobs;
m_vi->vstKnobs = NULL;
}
if( m_vi->knobFModel != NULL )
{
delete [] m_vi->knobFModel;
m_vi->knobFModel = NULL;
}
if (m_vi->m_scrollArea != NULL) {
delete m_vi->m_scrollArea;
@@ -929,6 +1076,8 @@ manageVestigeInstrumentView::~manageVestigeInstrumentView()
delete m_vi->m_subWindow;
m_vi->m_subWindow = NULL;
}
m_vi->p_subWindow = NULL;
}
@@ -989,6 +1138,8 @@ void manageVestigeInstrumentView::dropEvent( QDropEvent * _de )
void manageVestigeInstrumentView::paintEvent( QPaintEvent * )
{
m_vi->m_subWindow->setWindowTitle( m_vi->instrumentTrack()->name()
+ tr( " - VST plugin control" ) );
}

View File

@@ -92,6 +92,7 @@ private:
knob ** vstKnobs;
FloatModel ** knobFModel;
QObject * p_subWindow;
int paramCount;
friend class VestigeInstrumentView;
@@ -110,7 +111,9 @@ public:
protected slots:
void syncPlugin( void );
void displayAutomatedOnly( void );
void setParameter( void );
void closeWindow();
protected:
@@ -127,6 +130,8 @@ private:
QWidget *widget;
QGridLayout * l;
QPushButton * m_syncButton;
QPushButton * m_displayAutomatedOnly;
QPushButton * m_closeButton;
} ;

View File

@@ -92,7 +92,20 @@ struct ERect
#include "midi.h"
#include "communication.h"
#include "VST_sync_shm.h"
#ifdef LMMS_BUILD_WIN32
#define USE_QT_SHMEM
#endif
#ifndef USE_QT_SHMEM
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
static VstHostLanguages hlang = LanguageEnglish;
@@ -303,6 +316,18 @@ private:
double m_currentSamplePos;
int m_currentProgram;
// host to plugin synchronisation data structure
struct in
{
float lastppqPos;
float m_Timestamp;
} ;
in * m_in;
int m_shmID;
sncVST * m_SncVSTplug;
} ;
@@ -324,12 +349,59 @@ RemoteVstPlugin::RemoteVstPlugin( key_t _shm_in, key_t _shm_out ) :
m_midiEvents(),
m_bpm( 0 ),
m_currentSamplePos( 0 ),
m_currentProgram( -1 )
m_currentProgram( -1 ),
m_in( NULL ),
m_shmID( -1 ),
m_SncVSTplug( NULL )
{
pthread_mutex_init( &m_pluginLock, NULL );
__plugin = this;
#ifndef USE_QT_SHMEM
key_t key;
if( ( key = ftok( VST_SNC_SHM_KEY_FILE, 'R' ) ) == -1 )
{
perror( "RemoteVstPlugin.cpp::ftok" );
}
else
{ // connect to shared memory segment
if( ( m_shmID = shmget( key, 0, 0 ) ) == -1 )
{
perror( "RemoteVstPlugin.cpp::shmget" );
}
else
{ // attach segment
m_SncVSTplug = (sncVST *)shmat(m_shmID, 0, 0);
if( m_SncVSTplug == (sncVST *)( -1 ) )
{
perror( "RemoteVstPlugin.cpp::shmat" );
}
}
}
#else
m_SncVSTplug = RemotePluginClient::getQtVSTshm();
#endif
if( m_SncVSTplug == NULL )
{
fprintf(stderr, "RemoteVstPlugin.cpp: "
"Failed to initialize shared memory for VST synchronization.\n"
" (VST-host synchronization will be disabled)\n");
m_SncVSTplug = (sncVST*) malloc( sizeof( sncVST ) );
m_SncVSTplug->isPlayin = true;
m_SncVSTplug->timeSigNumer = 4;
m_SncVSTplug->timeSigDenom = 4;
m_SncVSTplug->ppqPos = 0;
m_SncVSTplug->isCycle = false;
m_SncVSTplug->hasSHM = false;
m_SncVSTplug->m_sampleRate = sampleRate();
}
m_in = ( in* ) new char[ sizeof( in ) ];
m_in->lastppqPos = 0;
m_in->m_Timestamp = -1;
// process until we have loaded the plugin
while( 1 )
{
@@ -347,6 +419,21 @@ RemoteVstPlugin::RemoteVstPlugin( key_t _shm_in, key_t _shm_out ) :
RemoteVstPlugin::~RemoteVstPlugin()
{
#ifndef USE_QT_SHMEM
// detach shared memory segment
if( shmdt( m_SncVSTplug ) == -1)
{
if( __plugin->m_SncVSTplug->hasSHM )
{
perror( "~RemoteVstPlugin::shmdt" );
}
if( m_SncVSTplug != NULL )
{
delete m_SncVSTplug;
m_SncVSTplug = NULL;
}
}
#endif
if( m_window != NULL )
{
pluginDispatch( effEditClose );
@@ -451,7 +538,7 @@ bool RemoteVstPlugin::processMessage( const message & _m )
lock();
m_plugin->setParameter( m_plugin, _m.getInt( 0 ), _m.getFloat( 1 ) );
unlock();
sendMessage( IdVstSetParameter );
//sendMessage( IdVstSetParameter );
break;
@@ -486,6 +573,12 @@ void RemoteVstPlugin::init( const std::string & _plugin_file )
updateInOutCount();
// some plugins have to set samplerate during init
if( m_SncVSTplug->hasSHM )
{
updateSampleRate();
}
/* set program to zero */
/* i comment this out because it breaks dfx Geometer
* looks like we cant set programs for it
@@ -558,10 +651,12 @@ void RemoteVstPlugin::initEditor()
}
#ifdef LMMS_BUILD_LINUX
m_window = CreateWindowEx( 0, "LVSL", m_shortName.c_str(),
( WS_OVERLAPPEDWINDOW | WS_THICKFRAME ) & ~WS_MAXIMIZEBOX,
0, 0, 10, 10, NULL, NULL, hInst, NULL );
//m_window = CreateWindowEx( 0, "LVSL", m_shortName.c_str(),
// ( WS_OVERLAPPEDWINDOW | WS_THICKFRAME ) & ~WS_MAXIMIZEBOX,
// 0, 0, 10, 10, NULL, NULL, hInst, NULL );
m_window = CreateWindowEx( 0 , "LVSL", m_shortName.c_str(),
WS_POPUP | WS_SYSMENU | WS_BORDER , 0, 0, 10, 10, NULL, NULL, hInst, NULL);
#else
m_windowID = 1; // arbitrary value on win32 to signal
// vstPlugin-class that we have an editor
@@ -1349,16 +1444,62 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode,
// fields are required (see valid masks above), as some
// items may require extensive conversions
memset( &_timeInfo, 0, sizeof( _timeInfo ) );
// Shared memory was initialised? - see song.cpp
//assert( __plugin->m_SncVSTplug != NULL );
memset( &_timeInfo, 0, sizeof( _timeInfo ) );
_timeInfo.samplePos = __plugin->m_currentSamplePos;
_timeInfo.sampleRate = __plugin->sampleRate();
_timeInfo.sampleRate = __plugin->m_SncVSTplug->hasSHM ?
__plugin->m_SncVSTplug->m_sampleRate :
__plugin->sampleRate();
_timeInfo.flags = 0;
_timeInfo.tempo = __plugin->m_bpm;
_timeInfo.timeSigNumerator = 4;
_timeInfo.timeSigDenominator = 4;
_timeInfo.flags |= (/* kVstBarsValid|*/kVstTempoValid );
_timeInfo.flags |= kVstTransportPlaying;
_timeInfo.tempo = __plugin->m_SncVSTplug->hasSHM ?
__plugin->m_SncVSTplug->m_bpm :
__plugin->m_bpm;
_timeInfo.timeSigNumerator = __plugin->m_SncVSTplug->timeSigNumer;
_timeInfo.timeSigDenominator = __plugin->m_SncVSTplug->timeSigDenom;
_timeInfo.flags |= kVstTempoValid;
_timeInfo.flags |= kVstTimeSigValid;
if( __plugin->m_SncVSTplug->isCycle )
{
_timeInfo.cycleStartPos = __plugin->m_SncVSTplug->cycleStart;
_timeInfo.cycleEndPos = __plugin->m_SncVSTplug->cycleEnd;
_timeInfo.flags |= kVstCyclePosValid;
_timeInfo.flags |= kVstTransportCycleActive;
}
if( __plugin->m_SncVSTplug->ppqPos !=
__plugin->m_in->m_Timestamp )
{
_timeInfo.ppqPos = __plugin->m_SncVSTplug->ppqPos;
_timeInfo.flags |= kVstTransportChanged;
__plugin->m_in->lastppqPos = __plugin->m_SncVSTplug->ppqPos;
__plugin->m_in->m_Timestamp = __plugin->m_SncVSTplug->ppqPos;
}
else if( __plugin->m_SncVSTplug->isPlayin )
{
__plugin->m_in->lastppqPos += (
__plugin->m_SncVSTplug->hasSHM ?
__plugin->m_SncVSTplug->m_bpm :
__plugin->m_bpm ) / (float)10340;
_timeInfo.ppqPos = __plugin->m_in->lastppqPos;
}
// _timeInfo.ppqPos = __plugin->m_SncVSTplug->ppqPos;
_timeInfo.flags |= kVstPpqPosValid;
if( __plugin->m_SncVSTplug->isPlayin )
{
_timeInfo.flags |= kVstTransportPlaying;
}
_timeInfo.barStartPos = ( (int) ( _timeInfo.ppqPos /
( 4 *__plugin->m_SncVSTplug->timeSigNumer
/ (float) __plugin->m_SncVSTplug->timeSigDenom ) ) ) *
( 4 * __plugin->m_SncVSTplug->timeSigNumer
/ (float) __plugin->m_SncVSTplug->timeSigDenom );
_timeInfo.flags |= kVstBarsValid;
#ifdef LMMS_BUILD_WIN64
return (long long) &_timeInfo;
#else

View File

@@ -49,6 +49,7 @@
#include "MainWindow.h"
#include "song.h"
#include "templates.h"
#include <QtGui/QLayout>
class vstSubWin : public QMdiSubWindow
@@ -200,11 +201,24 @@ void VstPlugin::tryLoad( const QString &remoteVstPluginExecutable )
void VstPlugin::showEditor( QWidget * _parent )
void VstPlugin::showEditor( QWidget * _parent, bool isEffect )
{
QWidget * w = pluginWidget();
if( w )
{
#ifdef LMMS_BUILD_WIN32
// hide sw, plugin window wrapper on win32
// this is obtained from pluginWidget()
if( isEffect )
{
w->setWindowFlags( Qt::FramelessWindowHint );
w->setAttribute( Qt::WA_TranslucentBackground );
}
else
{
w->setWindowFlags( Qt::WindowCloseButtonHint );
}
#endif
w->show();
return;
}
@@ -222,13 +236,30 @@ void VstPlugin::showEditor( QWidget * _parent )
{
vstSubWin * sw = new vstSubWin(
engine::mainWindow()->workspace() );
sw->setWidget( m_pluginWidget );
if( isEffect )
{
sw->setAttribute( Qt::WA_TranslucentBackground );
sw->setWindowFlags( Qt::FramelessWindowHint );
sw->setWidget( m_pluginWidget );
QX11EmbedContainer * xe = new QX11EmbedContainer( sw );
xe->embedClient( m_pluginWindowID );
xe->setFixedSize( m_pluginGeometry );
xe->show();
}
else
{
sw->setWindowFlags( Qt::WindowCloseButtonHint );
sw->setWidget( m_pluginWidget );
QX11EmbedContainer * xe = new QX11EmbedContainer( sw );
xe->embedClient( m_pluginWindowID );
xe->setFixedSize( m_pluginGeometry );
xe->move( 4, 24 );
xe->show();
}
}
QX11EmbedContainer * xe = new QX11EmbedContainer( m_pluginWidget );
xe->embedClient( m_pluginWindowID );
xe->setFixedSize( m_pluginGeometry );
xe->show();
#endif
if( m_pluginWidget )
@@ -258,7 +289,7 @@ void VstPlugin::loadSettings( const QDomElement & _this )
{
if( _this.attribute( "guivisible" ).toInt() )
{
showEditor();
showEditor( NULL, false );
}
else
{
@@ -574,7 +605,7 @@ void VstPlugin::setParam( int i, float f )
{
lock();
sendMessage( message( IdVstSetParameter ).addInt( i ).addFloat( f ) );
waitForMessage( IdVstSetParameter );
//waitForMessage( IdVstSetParameter );
unlock();
}

View File

@@ -53,7 +53,7 @@ public:
return m_pluginWindowID != 0;
}
void showEditor( QWidget * _parent = NULL );
void showEditor( QWidget * _parent = NULL, bool isEffect = false );
void hideEditor();
inline const QString & name() const

View File

@@ -65,7 +65,8 @@ VstEffect::VstEffect( Model * _parent,
{
openPlugin( m_key.attributes["file"] );
}
setDisplayName( m_key.name );
setDisplayName( m_key.attributes["file"].section( ".dll", 0, 0 ).isEmpty()
? m_key.name : m_key.attributes["file"].section( ".dll", 0, 0 ) );
}
@@ -162,6 +163,10 @@ void VstEffect::openPlugin( const QString & _plugin )
void VstEffect::closePlugin()
{
m_pluginMutex.lock();
if( m_plugin->pluginWidget() != NULL )
{
delete m_plugin->pluginWidget();
}
delete m_plugin;
m_plugin = NULL;
m_pluginMutex.unlock();

View File

@@ -36,34 +36,54 @@
#include <QObject>
#include <QtGui/QPainter>
#include "gui_templates.h"
#include <QtGui/QToolBar>
#include <QtGui/QLabel>
VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
EffectControlDialog( _ctl ),
m_pluginWidget( NULL )
m_pluginWidget( NULL ),
m_plugin( NULL ),
tbLabel( NULL )
{
QGridLayout * l = new QGridLayout( this );
l->setContentsMargins( 20, 10, 10, 10 );
l->setContentsMargins( 10, 10, 10, 10 );
l->setVerticalSpacing( 2 );
l->setHorizontalSpacing( 2 );
#ifdef LMMS_BUILD_LINUX
_ctl->m_effect->m_plugin->showEditor();
m_pluginWidget = _ctl->m_effect->m_plugin->pluginWidget();
if( _ctl != NULL && _ctl->m_effect != NULL &&
_ctl->m_effect->m_plugin != NULL )
{
m_plugin = _ctl->m_effect->m_plugin;
m_plugin->showEditor( NULL, true );
m_pluginWidget = m_plugin->pluginWidget();
#ifdef LMMS_BUILD_WIN32
if( !m_pluginWidget )
{
m_pluginWidget = m_plugin->pluginWidget( false );
}
#endif
}
if( m_pluginWidget )
{
setWindowTitle( m_pluginWidget->windowTitle() );
QPushButton * btn = new QPushButton( tr( "Show/hide VST FX GUI" ) );
setMinimumWidth( 250 );
QPushButton * btn = new QPushButton( tr( "Show/hide" ) );
btn->setCheckable( true );
l->addWidget( btn, 0, 0, 1, 13, Qt::AlignCenter );
connect( btn, SIGNAL( toggled( bool ) ),
m_pluginWidget, SLOT( setVisible( bool ) ) );
btn->setMinimumWidth( 200 );
btn->setMaximumWidth( 200 );
emit btn->click();
btn->setMinimumWidth( 78 );
btn->setMaximumWidth( 78 );
btn->setMinimumHeight( 24 );
btn->setMaximumHeight( 24 );
m_managePluginButton = new pixmapButton( this, "" );
m_managePluginButton->setCheckable( false );
m_managePluginButton->setCursor( Qt::PointingHandCursor );
@@ -78,13 +98,11 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
m_managePluginButton->setWhatsThis(
tr( "Click here, if you want to control VST-plugin from host." ) );
m_managePluginButton->setMinimumWidth( 21 );
m_managePluginButton->setMaximumWidth( 21 );
m_managePluginButton->setMinimumHeight( 21 );
m_managePluginButton->setMaximumHeight( 21 );
m_openPresetButton = new pixmapButton( this, "" );
m_openPresetButton->setCheckable( false );
m_openPresetButton->setCursor( Qt::PointingHandCursor );
@@ -104,7 +122,6 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
m_openPresetButton->setMinimumHeight( 16 );
m_openPresetButton->setMaximumHeight( 16 );
m_rolLPresetButton = new pixmapButton( this, "" );
m_rolLPresetButton->setCheckable( false );
m_rolLPresetButton->setCursor( Qt::PointingHandCursor );
@@ -114,6 +131,10 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
"stepper-left" ) );
connect( m_rolLPresetButton, SIGNAL( clicked() ), _ctl,
SLOT( rolrPreset() ) );
connect( m_rolLPresetButton, SIGNAL( clicked() ), this,
SLOT( update() ) );
toolTip::add( m_rolLPresetButton, tr( "Previous (-)" ) );
m_rolLPresetButton->setShortcut( Qt::Key_Minus );
@@ -126,7 +147,6 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
m_rolLPresetButton->setMinimumHeight( 16 );
m_rolLPresetButton->setMaximumHeight( 16 );
m_rolRPresetButton = new pixmapButton( this, "" );
m_rolRPresetButton->setCheckable( false );
m_rolRPresetButton->setCursor( Qt::PointingHandCursor );
@@ -136,6 +156,10 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
"stepper-right" ) );
connect( m_rolRPresetButton, SIGNAL( clicked() ), _ctl,
SLOT( rollPreset() ) );
connect( m_rolRPresetButton, SIGNAL( clicked() ), this,
SLOT( update() ) );
toolTip::add( m_rolRPresetButton, tr( "Next (+)" ) );
m_rolRPresetButton->setShortcut( Qt::Key_Plus );
@@ -148,8 +172,6 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
m_rolRPresetButton->setMinimumHeight( 16 );
m_rolRPresetButton->setMaximumHeight( 16 );
_ctl->m_selPresetButton = new QPushButton( tr( "" ), this );
_ctl->m_selPresetButton->setCheckable( false );
@@ -160,13 +182,11 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
_ctl->m_selPresetButton->setMenu(_ctl->menu);
_ctl->m_selPresetButton->setMinimumWidth( 16 );
_ctl->m_selPresetButton->setMaximumWidth( 16 );
_ctl->m_selPresetButton->setMinimumHeight( 16 );
_ctl->m_selPresetButton->setMaximumHeight( 16 );
m_savePresetButton = new pixmapButton( this, "" );
m_savePresetButton->setCheckable( false );
m_savePresetButton->setCursor( Qt::PointingHandCursor );
@@ -181,36 +201,46 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
m_savePresetButton->setWhatsThis(
tr( "Click here, if you want to save current VST-plugin preset program." ) );
m_savePresetButton->setMinimumWidth( 21 );
m_savePresetButton->setMaximumWidth( 21 );
m_savePresetButton->setMinimumHeight( 21 );
m_savePresetButton->setMaximumHeight( 21 );
int newSize = m_pluginWidget->width() + 20;
newSize = (newSize < 250) ? 250 : newSize;
QWidget* resize = new QWidget(this);
resize->resize( newSize, 10 );
QWidget* space0 = new QWidget(this);
space0->resize(8, 10);
QWidget* space1 = new QWidget(this);
space1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
QFont f( "Arial", 10 );
l->addWidget( m_openPresetButton, 1, 7, Qt::AlignCenter );
l->addWidget( m_rolLPresetButton, 1, 4, Qt::AlignCenter );
l->addWidget( m_rolRPresetButton, 1, 5, Qt::AlignCenter );
l->addWidget(_ctl->m_selPresetButton, 1, 6, Qt::AlignLeft );
l->addItem( new QSpacerItem( newSize - 20, 30, QSizePolicy::Fixed,
QSizePolicy::Fixed ), 1, 0 );
l->addWidget( resize, 2, 0, 1, 1, Qt::AlignCenter );
l->addWidget( m_pluginWidget, 3, 0, 1, 1, Qt::AlignCenter );
l->setRowStretch( 5, 1 );
l->setColumnStretch( 1, 1 );
l->addWidget( m_managePluginButton, 1, 10, 2, 2, Qt::AlignLeft );
l->addWidget( m_savePresetButton, 1, 8, 2, 2, Qt::AlignCenter );
l->setRowStretch( 3, 1 );
l->setColumnStretch( 13, 1 );
QToolBar * tb = new QToolBar( this );
tb->resize( newSize , 32 );
tb->addWidget(space0);
tb->addWidget( m_rolLPresetButton );
tb->addWidget( m_rolRPresetButton );
tb->addWidget( _ctl->m_selPresetButton );
tb->addWidget( m_openPresetButton );
tb->addWidget( m_savePresetButton );
tb->addWidget( m_managePluginButton );
tb->addWidget( btn );
tb->addWidget(space1);
tbLabel = new QLabel( tr( "Effect by: " ), this );
tbLabel->setFont( pointSize<7>( f ) );
tbLabel->setTextFormat(Qt::RichText);
tbLabel->setAlignment( Qt::AlignTop | Qt::AlignLeft );
tb->addWidget( tbLabel );
}
#endif
#ifdef LMMS_BUILD_WIN32
_ctl->m_effect->m_plugin->showEditor( this );
QWidget * w = _ctl->m_effect->m_plugin->pluginWidget( false );
if( w )
{
setWindowTitle( w->windowTitle() );
l->addWidget( w );
}
#endif
}
@@ -218,7 +248,12 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
void VstEffectControlDialog::paintEvent( QPaintEvent * )
{
if( m_plugin != NULL && tbLabel != NULL )
{
tbLabel->setText( tr( "Effect by: " ) + m_plugin->vendorString() +
tr( "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />" ) +
m_plugin->currentProgramName() );
}
}
@@ -226,7 +261,7 @@ void VstEffectControlDialog::paintEvent( QPaintEvent * )
VstEffectControlDialog::~VstEffectControlDialog()
{
delete m_pluginWidget;
//delete m_pluginWidget;
}

View File

@@ -26,9 +26,11 @@
#define _VST_EFFECT_CONTROL_DIALOG_H
#include "EffectControlDialog.h"
#include "VstPlugin.h"
#include <QObject>
#include <QPainter>
#include <QtGui/QLabel>
class VstEffectControls;
@@ -57,6 +59,9 @@ private:
pixmapButton * m_managePluginButton;
pixmapButton * m_savePresetButton;
VstPlugin * m_plugin;
QLabel * tbLabel;
} ;
#endif

View File

@@ -61,30 +61,39 @@ VstEffectControls::~VstEffectControls()
void VstEffectControls::loadSettings( const QDomElement & _this )
{
m_effect->closePlugin();
m_effect->openPlugin( _this.attribute( "plugin" ) );
//m_effect->closePlugin();
//m_effect->openPlugin( _this.attribute( "plugin" ) );
m_effect->m_pluginMutex.lock();
if( m_effect->m_plugin != NULL )
{
m_effect->m_plugin->loadSettings( _this );
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
int paramCount = (dump).size();
paramCount = dump.size();
char paramStr[35];
vstKnobs = new knob *[paramCount];
knobFModel = new FloatModel *[paramCount];
QStringList list1;
vstKnobs = new knob *[ paramCount ];
knobFModel = new FloatModel *[ paramCount ];
QStringList s_dumpValues;
QWidget * widget = new QWidget();
for (int i = 0; i < paramCount; i++) {
sprintf( paramStr, "param%d", i);
list1 = dump[paramStr].split(":");
for( int i = 0; i < paramCount; i++ )
{
sprintf( paramStr, "param%d", i );
s_dumpValues = dump[ paramStr ].split( ":" );
vstKnobs[i] = new knob( knobBright_26, widget );
vstKnobs[i]->setHintText( list1.at(1) + ":", "");
vstKnobs[i]->setLabel( list1.at(1).left(15) );
vstKnobs[i] = new knob( knobBright_26, widget, s_dumpValues.at( 1 ) );
vstKnobs[i]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
vstKnobs[i]->setLabel( s_dumpValues.at( 1 ).left( 15 ) );
knobFModel[i] = new FloatModel( (list1.at(2)).toFloat(), 0.0f, 1.0f, 0.01f, this, QString::number(i) );
knobFModel[i] = new FloatModel( 0.0f, 0.0f, 1.0f, 0.01f, this, QString::number(i) );
knobFModel[i]->loadSettings( _this, paramStr );
if( !( knobFModel[ i ]->isAutomated() ||
knobFModel[ i ]->getControllerConnection() ) )
{
knobFModel[ i ]->setValue( (s_dumpValues.at( 2 ) ).toFloat() );
knobFModel[ i ]->setInitValue( (s_dumpValues.at( 2 ) ).toFloat() );
}
connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
vstKnobs[i]->setModel( knobFModel[i] );
@@ -120,13 +129,15 @@ void VstEffectControls::saveSettings( QDomDocument & _doc, QDomElement & _this )
m_effect->m_plugin->saveSettings( _doc, _this );
if (knobFModel != NULL) {
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
int paramCount = (dump).size();
paramCount = dump.size();
char paramStr[35];
for (int i = 0; i < paramCount; i++)
for( int i = 0; i < paramCount; i++ )
{
if (knobFModel[i]->isAutomated() || knobFModel[i]->getControllerConnection()) {
sprintf( paramStr, "param%d", i);
knobFModel[i]->saveSettings( _doc, _this, paramStr );
}
}
}
}
m_effect->m_pluginMutex.unlock();
@@ -303,7 +314,7 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls *
m_vi->m_subWindow->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
m_vi->m_subWindow->setFixedSize( 960, 300);
m_vi->m_subWindow->setWidget(m_vi->m_scrollArea);
m_vi->m_subWindow->setWindowTitle(_eff->m_plugin->name());
m_vi->m_subWindow->setWindowTitle( _eff->m_plugin->name() + tr( " - VST parameter control" ) );
m_vi->m_subWindow->setWindowIcon( PLUGIN_NAME::getIconPixmap( "logo" ) );
//m_vi->m_subWindow->setAttribute(Qt::WA_DeleteOnClose);
@@ -320,51 +331,80 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls *
l->addWidget( m_syncButton, 0, 0, 1, 2, Qt::AlignLeft );
m_displayAutomatedOnly = new QPushButton( tr( "Automated" ), widget );
connect( m_displayAutomatedOnly, SIGNAL( clicked() ), this,
SLOT( displayAutomatedOnly() ) );
m_displayAutomatedOnly->setWhatsThis(
tr( "Click here if you want to display automated parameters only." ) );
l->addWidget( m_displayAutomatedOnly, 0, 1, 1, 2, Qt::AlignLeft );
m_closeButton = new QPushButton( tr( " Close " ), widget );
connect( m_closeButton, SIGNAL( clicked() ), this,
SLOT( closeWindow() ) );
m_closeButton->setWhatsThis(
tr( "Close VST effect knob-controller window." ) );
l->addWidget( m_closeButton, 0, 2, 1, 7, Qt::AlignLeft );
for( int i = 0; i < 10; i++ )
{
l->addItem( new QSpacerItem( 68, 45, QSizePolicy::Fixed, QSizePolicy::Fixed ), 0, i );
}
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
int paramCount = (dump).size();
m_vi->paramCount = dump.size();
bool isVstKnobs = true, isKnobFModel = true;
if (m_vi->vstKnobs == NULL) {
m_vi->vstKnobs = new knob *[paramCount];
m_vi->vstKnobs = new knob *[ m_vi->paramCount ];
isVstKnobs = false;
}
if (m_vi->knobFModel == NULL) {
m_vi->knobFModel = new FloatModel *[paramCount];
m_vi->knobFModel = new FloatModel *[ m_vi->paramCount ];
isKnobFModel = false;
}
char paramStr[35];
QStringList list1;
QStringList s_dumpValues;
if (isVstKnobs == false) {
for (int i = 0; i < paramCount; i++) {
for( int i = 0; i < m_vi->paramCount; i++ )
{
sprintf( paramStr, "param%d", i);
list1 = dump[paramStr].split(":");
s_dumpValues = dump[ paramStr ].split( ":" );
m_vi->vstKnobs[i] = new knob( knobBright_26, widget);
m_vi->vstKnobs[i]->setHintText( list1.at(1) + ":", "");
m_vi->vstKnobs[i]->setLabel( list1.at(1).left(15) );
m_vi->vstKnobs[ i ] = new knob( knobBright_26, widget, s_dumpValues.at( 1 ) );
m_vi->vstKnobs[ i ]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
m_vi->vstKnobs[ i ]->setLabel( s_dumpValues.at( 1 ).left( 15 ) );
sprintf( paramStr, "%d", i);
m_vi->knobFModel[i] = new FloatModel( (list1.at(2)).toFloat(), 0.0f, 1.0f, 0.01f,
_eff, tr( paramStr ) );
connect( m_vi->knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
m_vi->vstKnobs[i] ->setModel( m_vi->knobFModel[i] );
m_vi->knobFModel[ i ] = new FloatModel( ( s_dumpValues.at( 2 ) ).toFloat(),
0.0f, 1.0f, 0.01f, _eff, tr( paramStr ) );
connect( m_vi->knobFModel[ i ], SIGNAL( dataChanged() ), this,
SLOT( setParameter() ) );
m_vi->vstKnobs[ i ] ->setModel( m_vi->knobFModel[ i ] );
}
}
int i = 0;
for (int lrow = 0+1; lrow < (int(paramCount / 10) + 1)+1; lrow++) {
for (int lcolumn = 0; lcolumn < 10; lcolumn++) {
if (i < paramCount)
for( int lrow = 1; lrow < ( int( m_vi->paramCount / 10 ) + 1 ) + 1; lrow++ )
{
for( int lcolumn = 0; lcolumn < 10; lcolumn++ )
{
if( i < m_vi->paramCount )
{
l->addWidget( m_vi->vstKnobs[i], lrow, lcolumn, Qt::AlignCenter );
}
i++;
}
}
l->setRowStretch( (int(paramCount / 10) + 1), 1 );
l->setRowStretch( ( int( m_vi->paramCount / 10 ) + 1 ), 1 );
l->setColumnStretch( 10, 1 );
widget->setLayout(l);
@@ -383,24 +423,63 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls *
void manageVSTEffectView::closeWindow()
{
m_vi2->m_subWindow->hide();
}
void manageVSTEffectView::syncPlugin( void )
{
char paramStr[35];
QStringList list1;
QStringList s_dumpValues;
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
float f;
float f_value;
for (int i = 0; i<(dump).size(); i++) {
sprintf( paramStr, "param%d", i);
list1 = dump[paramStr].split(":");
f = (list1.at(2)).toFloat();
m_vi2->knobFModel[i]->setValue(f);
m_vi2->knobFModel[i]->setInitValue(f);
for( int i = 0; i < m_vi2->paramCount; i++ )
{
// only not automated knobs are synced from VST
// those auto-setted values are not jurnaled, tracked for undo / redo
if( !( m_vi2->knobFModel[ i ]->isAutomated() ||
m_vi2->knobFModel[ i ]->getControllerConnection() ) )
{
sprintf( paramStr, "param%d", i );
s_dumpValues = dump[ paramStr ].split( ":" );
f_value = ( s_dumpValues.at( 2 ) ).toFloat();
m_vi2->knobFModel[ i ]->setAutomatedValue( f_value );
m_vi2->knobFModel[ i ]->setInitValue( f_value );
}
}
}
void manageVSTEffectView::displayAutomatedOnly( void )
{
bool isAuto = QString::compare( m_displayAutomatedOnly->text(), tr( "Automated" ) ) == 0;
for( int i = 0; i< m_vi2->paramCount; i++ )
{
if( !( m_vi2->knobFModel[ i ]->isAutomated() ||
m_vi2->knobFModel[ i ]->getControllerConnection() ) )
{
if( m_vi2->vstKnobs[ i ]->isVisible() == true && isAuto )
{
m_vi2->vstKnobs[ i ]->hide();
m_displayAutomatedOnly->setText( "All" );
} else {
m_vi2->vstKnobs[ i ]->show();
m_displayAutomatedOnly->setText( "Automated" );
}
}
}
}
void manageVSTEffectView::setParameter( void )
{
@@ -418,8 +497,46 @@ void manageVSTEffectView::setParameter( void )
manageVSTEffectView::~manageVSTEffectView()
{
delete m_vi2->m_subWindow;
m_vi2->m_subWindow = NULL;
if( m_vi2->knobFModel != NULL )
{
for( int i = 0; i < m_vi2->paramCount; i++ )
{
delete m_vi2->knobFModel[ i ];
delete m_vi2->vstKnobs[ i ];
}
}
if( m_vi2->vstKnobs != NULL )
{
delete [] m_vi2->vstKnobs;
m_vi2->vstKnobs = NULL;
}
if( m_vi2->knobFModel != NULL )
{
delete [] m_vi2->knobFModel;
m_vi2->knobFModel = NULL;
}
if( m_vi2->m_scrollArea != NULL )
{
delete m_vi2->m_scrollArea;
m_vi2->m_scrollArea = NULL;
}
if( m_vi2->m_subWindow != NULL )
{
m_vi2->m_subWindow->setAttribute( Qt::WA_DeleteOnClose );
m_vi2->m_subWindow->close();
if( m_vi2->m_subWindow != NULL )
{
delete m_vi2->m_subWindow;
}
m_vi2->m_subWindow = NULL;
}
//delete m_vi2->m_subWindow;
//m_vi2->m_subWindow = NULL;
}

View File

@@ -88,6 +88,7 @@ private:
QScrollArea * m_scrollArea;
FloatModel ** knobFModel;
knob ** vstKnobs;
int paramCount;
QObject * ctrHandle;
@@ -112,7 +113,9 @@ public:
protected slots:
void syncPlugin( void );
void displayAutomatedOnly( void );
void setParameter( void );
void closeWindow();
private:
@@ -128,6 +131,8 @@ private:
QGridLayout * l;
QPushButton * m_syncButton;
QPushButton * m_displayAutomatedOnly;
QPushButton * m_closeButton;
} ;

View File

@@ -1,7 +1,7 @@
/*
* LocalZynAddSubFx.cpp - local implementation of ZynAddSubFx plugin
*
* Copyright (c) 2009-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2009-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -206,10 +206,10 @@ void LocalZynAddSubFx::processMidiEvent( const midiEvent & _e )
}
if( m_runningNotes[_e.key()] > 0 )
{
m_master->NoteOff( 0, _e.key() );
m_master->NoteOff( _e.channel(), _e.key() );
}
++m_runningNotes[_e.key()];
m_master->NoteOn( 0, _e.key(), _e.velocity() );
m_master->NoteOn( _e.channel(), _e.key(), _e.velocity() );
break;
}
case MidiNoteOff:
@@ -219,16 +219,16 @@ void LocalZynAddSubFx::processMidiEvent( const midiEvent & _e )
}
if( --m_runningNotes[_e.key()] <= 0 )
{
m_master->NoteOff( 0, _e.key() );
m_master->NoteOff( _e.channel(), _e.key() );
}
break;
case MidiPitchBend:
m_master->SetController( 0, C_pitchwheel,
m_master->SetController( _e.channel(), C_pitchwheel,
_e.m_data.m_param[0] +
_e.m_data.m_param[1]*128-8192 );
break;
case MidiControlChange:
m_master->SetController( 0,
m_master->SetController( _e.channel(),
midiIn.getcontroller( _e.m_data.m_param[0] ),
_e.m_data.m_param[1] );
break;

View File

@@ -1,7 +1,7 @@
/*
* ZynAddSubFx.cpp - ZynAddSubxFX-embedding plugin
*
* Copyright (c) 2008-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -301,6 +301,9 @@ void ZynAddSubFxInstrument::loadFile( const QString & _file )
m_pluginMutex.unlock();
}
instrumentTrack()->setName( QFileInfo( _file ).baseName().
replace( QRegExp( "^[0-9]{4}-" ), QString() ) );
m_modifiedControllers.clear();
emit settingsChanged();
@@ -447,7 +450,7 @@ void ZynAddSubFxInstrument::initPlugin()
void ZynAddSubFxInstrument::sendControlChange( MidiControllers midiCtl, float value )
{
handleMidiEvent( midiEvent( MidiControlChange, 0, midiCtl, (int) value, this ),
handleMidiEvent( midiEvent( MidiControlChange, instrumentTrack()->midiPort()->realOutputChannel(), midiCtl, (int) value, this ),
midiTime() );
}

View File

@@ -93,7 +93,7 @@ extern int OSCIL_SIZE;
/*
* The poliphony (notes)
*/
#define POLIPHONY 60
#define POLIPHONY 128
/*
* Number of system effects

View File

@@ -2,7 +2,7 @@
* AutomationPattern.cpp - implementation of class AutomationPattern which
* holds dynamic values
*
* Copyright (c) 2008-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2006-2008 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
@@ -45,7 +45,6 @@ AutomationPattern::AutomationPattern( AutomationTrack * _auto_track ) :
m_hasAutomation( false )
{
changeLength( midiTime( 1, 0 ) );
m_timeMap[0] = 0;
}
@@ -101,12 +100,6 @@ void AutomationPattern::addObject( AutomatableModel * _obj, bool _search_dup )
if( addIt )
{
m_objects += _obj;
// been empty before?
if( m_objects.size() == 1 && !hasAutomation() )
{
// then initialize default-value
putValue( 0, _obj->value<float>(), false );
}
connect( _obj, SIGNAL( destroyed( jo_id_t ) ),
this, SLOT( objectDestroyed( jo_id_t ) ),
Qt::DirectConnection );
@@ -152,6 +145,8 @@ midiTime AutomationPattern::putValue( const midiTime & _time,
const float _value,
const bool _quant_pos )
{
cleanObjects();
midiTime newTime = _quant_pos && engine::automationEditor() ?
note::quantized( _time,
engine::automationEditor()->quantization() ) :
@@ -159,43 +154,7 @@ midiTime AutomationPattern::putValue( const midiTime & _time,
m_timeMap[newTime] = _value;
if( newTime == 0 )
{
for( objectVector::iterator it = m_objects.begin();
it != m_objects.end(); )
{
if( *it )
{
( *it )->setValue( _value );
++it;
}
else
{
it = m_objects.erase( it );
}
}
}
// just one automation value?
if( m_timeMap.size() == 1 )
{
m_hasAutomation = m_objects.isEmpty(); // usually false
for( objectVector::iterator it = m_objects.begin();
it != m_objects.end(); ++it )
{
// default value differs from current value?
if( *it && _value != ( *it )->initValue<float>() )
{
// then enable automating this object
m_hasAutomation = true;
}
}
}
else
{
// in all other cases assume we have automation
m_hasAutomation = true;
}
m_hasAutomation = true;
// we need to maximize our length in case we're part of a hidden
// automation track as the user can't resize this pattern
@@ -214,41 +173,22 @@ midiTime AutomationPattern::putValue( const midiTime & _time,
void AutomationPattern::removeValue( const midiTime & _time )
{
if( _time != 0 )
cleanObjects();
m_timeMap.remove( _time );
if( getTrack() &&
getTrack()->type() == track::HiddenAutomationTrack )
{
m_timeMap.remove( _time );
if( m_timeMap.size() == 1 )
{
const float val = m_timeMap[0];
m_hasAutomation = false;
for( objectVector::iterator it = m_objects.begin();
it != m_objects.end(); )
{
if( *it )
{
( *it )->setValue( val );
if( ( *it )->initValue<float>() != val )
{
m_hasAutomation = true;
}
++it;
}
else
{
it = m_objects.erase( it );
}
}
}
if( getTrack() &&
getTrack()->type() == track::HiddenAutomationTrack )
{
changeLength( length() );
}
emit dataChanged();
changeLength( length() );
}
if( m_timeMap.isEmpty() )
{
m_hasAutomation = false;
}
emit dataChanged();
}
@@ -260,10 +200,22 @@ float AutomationPattern::valueAt( const midiTime & _time ) const
{
return 0;
}
timeMap::const_iterator v = m_timeMap.lowerBound( _time );
if( m_timeMap.contains( _time ) )
{
return m_timeMap[_time];
}
// lowerBound returns next value with greater key, therefore we take
// the previous element to get the current value
return ( v != m_timeMap.begin() ) ? (v-1).value() : v.value();
timeMap::ConstIterator v = m_timeMap.lowerBound( _time );
if( v == m_timeMap.begin() )
{
return 0;
}
return (v-1).value();
}
@@ -326,17 +278,7 @@ void AutomationPattern::loadSettings( const QDomElement & _this )
}
m_hasAutomation = m_timeMap.size() > 0;
if( m_hasAutomation == false )
{
for( objectVector::iterator it = m_objects.begin();
it != m_objects.end(); ++it )
{
if( *it )
{
( *it )->setValue( m_timeMap[0] );
}
}
}
int len = _this.attribute( "len" ).toInt();
if( len <= 0 )
{
@@ -366,7 +308,7 @@ const QString AutomationPattern::name() const
void AutomationPattern::processMidiTime( const midiTime & _time )
{
if( _time >= 0 && m_hasAutomation )
if( _time >= 0 && hasAutomation() )
{
const float val = valueAt( _time );
for( objectVector::iterator it = m_objects.begin();
@@ -502,9 +444,9 @@ void AutomationPattern::resolveAllIDs()
void AutomationPattern::clear()
{
const float val = firstObject()->value<float>();
m_timeMap.clear();
putValue( 0, val );
emit dataChanged();
if( engine::automationEditor() &&
engine::automationEditor()->currentPattern() == this )
@@ -537,6 +479,21 @@ void AutomationPattern::objectDestroyed( jo_id_t _id )
void AutomationPattern::cleanObjects()
{
for( objectVector::iterator it = m_objects.begin(); it != m_objects.end(); )
{
if( *it )
{
++it;
}
else
{
it = m_objects.erase( it );
}
}
}
#include "moc_AutomationPattern.cxx"

View File

@@ -1,7 +1,7 @@
/*
* InstrumentFunctions.cpp - models for instrument-function-tab
*
* Copyright (c) 2004-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -48,7 +48,7 @@ ChordCreator::ChordTable::Init ChordCreator::ChordTable::s_initTable[] =
{ QT_TRANSLATE_NOOP( "ChordCreator", "6" ), { 0, 4, 7, 9, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "6sus4" ), { 0, 5, 7, 9, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "6add9" ), { 0, 4, 7, 12, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "6add9" ), { 0, 4, 7, 9, 14, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "m6" ), { 0, 3, 7, 9, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "m6add9" ), { 0, 3, 7, 9, 14, -1 } },
@@ -56,11 +56,11 @@ ChordCreator::ChordTable::Init ChordCreator::ChordTable::s_initTable[] =
{ QT_TRANSLATE_NOOP( "ChordCreator", "7sus4" ), { 0, 5, 7, 10, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#5" ), { 0, 4, 8, 10, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7b5" ), { 0, 4, 6, 10, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#9" ), { 0, 4, 7, 10, 13, 18, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7b9" ), { 0, 4, 7, 10, 13, 16, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#5#9" ), { 0, 4, 8, 12, 14, 19, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#5b9" ), { 0, 4, 8, 12, 14, 17, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7b5b9" ), { 0, 4, 6, 10, 12, 15, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#9" ), { 0, 4, 7, 10, 15, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7b9" ), { 0, 4, 7, 10, 13, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#5#9" ), { 0, 4, 8, 10, 15, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#5b9" ), { 0, 4, 8, 10, 13, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7b5b9" ), { 0, 4, 6, 10, 13, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7add11" ), { 0, 4, 7, 10, 17, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7add13" ), { 0, 4, 7, 10, 21, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "7#11" ), { 0, 4, 7, 10, 18, -1 } },
@@ -130,6 +130,7 @@ ChordCreator::ChordTable::Init ChordCreator::ChordTable::s_initTable[] =
{ QT_TRANSLATE_NOOP( "ChordCreator", "Mixolydian" ), { 0, 2, 4, 5, 7, 9, 10, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "Aeolian" ), { 0, 2, 3, 5, 7, 8, 10, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "Locrian" ), { 0, 1, 3, 5, 6, 8, 10, -1 } },
{ QT_TRANSLATE_NOOP( "ChordCreator", "Minor" ), { 0, 2, 3, 5, 7, 8, 10, -1 } },
} ;

View File

@@ -230,14 +230,13 @@ bool RemotePlugin::process( const sampleFrame * _in_buf,
lock();
sendMessage( IdStartProcessing );
unlock();
if( m_failed || _out_buf == NULL || m_outputCount == 0 )
{
unlock();
return false;
}
lock();
waitForMessage( IdProcessingDone );
unlock();

View File

@@ -2,7 +2,7 @@
* MidiPort.cpp - abstraction of MIDI-ports which are part of LMMS's MIDI-
* sequencing system
*
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -45,17 +45,17 @@ MidiPort::MidiPort( const QString & _name, MidiClient * _mc,
m_outputChannelModel( 1, 1, MidiChannelCount, this,
tr( "Output channel" ) ),
m_inputControllerModel( 0, 0, MidiControllerCount, this,
tr( "Input controller" ) ),
tr( "Input controller" ) ),
m_outputControllerModel( 0, 0, MidiControllerCount, this,
tr( "Output controller" ) ),
tr( "Output controller" ) ),
m_fixedInputVelocityModel( -1, -1, MidiMaxVelocity, this,
tr( "Fixed input velocity" ) ),
tr( "Fixed input velocity" ) ),
m_fixedOutputVelocityModel( -1, -1, MidiMaxVelocity, this,
tr( "Fixed output velocity" ) ),
m_fixedOutputNoteModel( -1, -1, MidiMaxNote, this,
tr( "Fixed output note" ) ),
m_outputProgramModel( 1, 1, MidiProgramCount, this,
tr( "Output MIDI program" ) ),
tr( "Output MIDI program" ) ),
m_readableModel( false, this, tr( "Receive MIDI-events" ) ),
m_writableModel( false, this, tr( "Send MIDI-events" ) )
{
@@ -129,20 +129,24 @@ void MidiPort::processInEvent( const midiEvent & _me, const midiTime & _time )
if( inputEnabled() &&
( inputChannel()-1 == _me.m_channel || inputChannel() == 0 ) )
{
midiEvent ev = _me;
if( _me.m_type == MidiNoteOn ||
_me.m_type == MidiNoteOff ||
_me.m_type == MidiKeyPressure )
{
if( _me.key() < 0 || _me.key() >= NumKeys )
ev.key() = ev.key() + KeysPerOctave;
if( ev.key() < 0 || ev.key() >= NumKeys )
{
return;
}
}
midiEvent ev = _me;
if( fixedInputVelocity() >= 0 && _me.velocity() > 0 )
{
ev.velocity() = fixedInputVelocity();
}
ev.setFromMidiPort( true );
m_midiEventProcessor->processInEvent( ev, _time );
}
}
@@ -164,10 +168,11 @@ void MidiPort::processOutEvent( const midiEvent & _me, const midiTime & _time )
--ev.m_channel;
} */
if( ( _me.m_type == MidiNoteOn || _me.m_type == MidiNoteOff ) &&
fixedOutputNote() >=0 ) {
// Convert MIDI note number (from spinbox) -> LMMS note number
// that will be converted back when outputted.
ev.key() = fixedOutputNote() - KeysPerOctave;
fixedOutputNote() >= 0 )
{
// Convert MIDI note number (from spinbox) -> LMMS note number
// that will be converted back when outputted.
ev.key() = fixedOutputNote() - KeysPerOctave;
}
if( fixedOutputVelocity() >= 0 && _me.velocity() > 0 &&
( _me.m_type == MidiNoteOn ||

View File

@@ -1,7 +1,7 @@
/*
* song.cpp - root of the model tree
*
* Copyright (c) 2004-2012 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -61,6 +61,21 @@
#include "text_float.h"
#include "timeline.h"
#ifdef LMMS_BUILD_WIN32
#ifndef USE_QT_SHMEM
#define USE_QT_SHMEM
#endif
#endif
#ifndef USE_QT_SHMEM
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
tick_t midiTime::s_ticksPerTact = DefaultTicksPerTact;
@@ -88,7 +103,10 @@ song::song() :
m_length( 0 ),
m_trackToPlay( NULL ),
m_patternToPlay( NULL ),
m_loopPattern( false )
m_loopPattern( false ),
m_shmID( -1 ),
m_SncVSTplug( NULL ),
m_shmQtID( "/usr/bin/lmms" )
{
connect( &m_tempoModel, SIGNAL( dataChanged() ),
this, SLOT( setTempo() ) );
@@ -101,6 +119,59 @@ song::song() :
connect( engine::getMixer(), SIGNAL( sampleRateChanged() ), this,
SLOT( updateFramesPerTick() ) );
// handle VST plugins sync
if( configManager::inst()->value( "ui", "syncvstplugins" ).toInt() )
{
connect( engine::getMixer(), SIGNAL( sampleRateChanged() ), this,
SLOT( updateSampleRateSHM() ) );
#ifdef USE_QT_SHMEM
if ( !m_shmQtID.create( sizeof( sncVST ) ) )
{
fprintf(stderr, "song.cpp::m_shmQtID create SHM error: %s\n",
m_shmQtID.errorString().toStdString().c_str() );
}
m_SncVSTplug = (sncVST *) m_shmQtID.data();
#else
key_t key; // make the key:
if( ( key = ftok( VST_SNC_SHM_KEY_FILE, 'R' ) ) == -1 )
{
perror( "song.cpp::ftok" );
}
else
{ // connect to shared memory segment
if( ( m_shmID = shmget( key, sizeof( sncVST ),
0644 | IPC_CREAT ) ) == -1 )
{
perror( "song.cpp::shmget" );
}
else
{ // attach segment
m_SncVSTplug = (sncVST *)shmat(m_shmID, 0, 0);
if( m_SncVSTplug == (sncVST *)( -1 ) )
{
perror( "song.cpp::shmat" );
}
}
}
#endif
// if we are connected into shared memory
if( m_SncVSTplug != NULL )
{
m_SncVSTplug->isPlayin = m_playing | m_exporting;
m_SncVSTplug->hasSHM = true;
m_SncVSTplug->m_sampleRate =
engine::getMixer()->processingSampleRate();
m_SncVSTplug->m_bufferSize =
engine::getMixer()->framesPerPeriod();
m_SncVSTplug->timeSigNumer = 4;
m_SncVSTplug->timeSigDenom = 4;
}
} // end of VST plugin sync section
if( m_SncVSTplug == NULL )
{
m_SncVSTplug = (sncVST*) malloc( sizeof( sncVST ) );
}
connect( &m_masterVolumeModel, SIGNAL( dataChanged() ),
this, SLOT( masterVolumeChanged() ) );
@@ -116,6 +187,24 @@ song::song() :
song::~song()
{
// detach shared memory, delete it:
#ifdef USE_QT_SHMEM
m_shmQtID.detach();
#else
if( shmdt( m_SncVSTplug ) == -1)
{
if( m_SncVSTplug->hasSHM )
{
perror("~song::shmdt");
}
if( m_SncVSTplug != NULL )
{
delete m_SncVSTplug;
m_SncVSTplug = NULL;
}
}
shmctl(m_shmID, IPC_RMID, NULL);
#endif
m_playing = false;
delete m_globalAutomationTrack;
}
@@ -150,6 +239,13 @@ void song::setTempo()
engine::updateFramesPerTick();
m_SncVSTplug->m_bpm = tempo;
#ifdef VST_SNC_LATENCY
m_SncVSTplug->m_latency = m_SncVSTplug->m_bufferSize * tempo /
( (float) m_SncVSTplug->m_sampleRate * 60 );
#endif
emit tempoChanged( tempo );
}
@@ -162,6 +258,8 @@ void song::setTimeSignature()
emit timeSignatureChanged( m_oldTicksPerTact, ticksPerTact() );
emit dataChanged();
m_oldTicksPerTact = ticksPerTact();
m_SncVSTplug->timeSigNumer = getTimeSigModel().getNumerator();
m_SncVSTplug->timeSigDenom = getTimeSigModel().getDenominator();
}
@@ -178,6 +276,7 @@ void song::doActions()
timeLine * tl =
m_playPos[m_playMode].m_timeLine;
m_playing = false;
m_SncVSTplug->isPlayin = m_exporting;
m_recording = true;
if( tl != NULL )
{
@@ -219,31 +318,37 @@ void song::doActions()
case ActionPlaySong:
m_playMode = Mode_PlaySong;
m_playing = true;
m_SncVSTplug->isPlayin = true;
Controller::resetFrameCounter();
break;
case ActionPlayTrack:
m_playMode = Mode_PlayTrack;
m_playing = true;
m_SncVSTplug->isPlayin = true;
break;
case ActionPlayBB:
m_playMode = Mode_PlayBB;
m_playing = true;
m_SncVSTplug->isPlayin = true;
break;
case ActionPlayPattern:
m_playMode = Mode_PlayPattern;
m_playing = true;
m_SncVSTplug->isPlayin = true;
break;
case ActionPause:
m_playing = false;// just set the play-flag
m_SncVSTplug->isPlayin = m_exporting;
m_paused = true;
break;
case ActionResumeFromPause:
m_playing = true;// just set the play-flag
m_SncVSTplug->isPlayin = true;
m_paused = false;
break;
}
@@ -360,8 +465,14 @@ void song::processNextBuffer()
while( total_frames_played
< engine::getMixer()->framesPerPeriod() )
{
f_cnt_t played_frames = engine::getMixer()
->framesPerPeriod() - total_frames_played;
f_cnt_t played_frames = ( m_SncVSTplug->m_bufferSize = engine::getMixer()
->framesPerPeriod() ) - total_frames_played;
#ifdef VST_SNC_LATENCY
m_SncVSTplug->m_latency = m_SncVSTplug->m_bufferSize *
m_SncVSTplug->m_bpm /
( (float) m_SncVSTplug->m_sampleRate * 60 );
#endif
float current_frame = m_playPos[m_playMode].currentFrame();
// did we play a tick?
@@ -369,6 +480,14 @@ void song::processNextBuffer()
{
int ticks = m_playPos[m_playMode].getTicks()
+ (int)( current_frame / frames_per_tick );
#ifdef VST_SNC_LATENCY
m_SncVSTplug->ppqPos = ( ( ticks + 0 ) / (float)48 ) -
m_SncVSTplug->m_latency;
#else
m_SncVSTplug->ppqPos = ( ( ticks + 0 ) / (float)48 );
#endif
// did we play a whole tact?
if( ticks >= midiTime::ticksPerTact() )
{
@@ -402,18 +521,37 @@ void song::processNextBuffer()
// offset
ticks = ticks % ( max_tact *
midiTime::ticksPerTact() );
#ifdef VST_SNC_LATENCY
m_SncVSTplug->ppqPos = ( ( ticks + 0 )
/ (float)48 )
- m_SncVSTplug->m_latency;
#else
m_SncVSTplug->ppqPos = ( ( ticks + 0 )
/ (float)48 );
#endif
}
}
m_playPos[m_playMode].setTicks( ticks );
if( check_loop )
{
m_SncVSTplug->isCycle = true;
m_SncVSTplug->cycleStart =
( tl->loopBegin().getTicks() )
/ (float)48;
m_SncVSTplug->cycleEnd =
( tl->loopEnd().getTicks() )
/ (float)48;
if( m_playPos[m_playMode] >= tl->loopEnd() )
{
m_playPos[m_playMode].setTicks(
tl->loopBegin().getTicks() );
}
}
else
{
m_SncVSTplug->isCycle = false;
}
current_frame = fmodf( current_frame, frames_per_tick );
m_playPos[m_playMode].setCurrentFrame( current_frame );
@@ -637,6 +775,7 @@ void song::startExport()
doActions();
m_exporting = true;
m_SncVSTplug->isPlayin = true;
}
@@ -647,6 +786,7 @@ void song::stopExport()
stop();
m_exporting = false;
m_exportLoop = false;
m_SncVSTplug->isPlayin = m_playing;
}
@@ -1096,8 +1236,9 @@ void song::importProject()
tr("MIDI sequences") +
" (*.mid *.midi *.rmi);;" +
tr("FL Studio projects") +
" (*.flp"
");;" +
" (*.flp);;" +
tr("Hydrogen projects") +
" (*.h2song);;" +
tr("All file types") +
" (*.*)");
@@ -1215,6 +1356,19 @@ void song::updateFramesPerTick()
void song::updateSampleRateSHM()
{
m_SncVSTplug->m_sampleRate = engine::getMixer()->processingSampleRate();
#ifdef VST_SNC_LATENCY
m_SncVSTplug->m_latency = m_SncVSTplug->m_bufferSize * m_SncVSTplug->m_bpm /
( (float) m_SncVSTplug->m_sampleRate * 60 );
#endif
}
void song::setModified()
{
if( !m_loadingProject )

View File

@@ -1,7 +1,7 @@
/*
* AutomatableModelView.cpp - implementation of AutomatableModelView
*
* Copyright (c) 2011 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2011-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -88,6 +88,12 @@ void AutomatableModelView::addDefaultActions( QMenu * _menu )
AutomatableModel::tr( "Edit song-global automation" ),
amvSlots,
SLOT( editSongGlobalAutomation() ) );
_menu->addAction( QPixmap(),
AutomatableModel::tr( "Remove song-global automation" ),
amvSlots,
SLOT( removeSongGlobalAutomation() ) );
_menu->addSeparator();
QString controllerTxt;
@@ -241,4 +247,11 @@ void AutomatableModelViewSlots::editSongGlobalAutomation()
void AutomatableModelViewSlots::removeSongGlobalAutomation()
{
delete AutomationPattern::globalAutomationPattern( amv->modelUntyped() );
}
#include "moc_AutomatableModelView.cxx"

View File

@@ -2,7 +2,7 @@
* AutomationEditor.cpp - implementation of AutomationEditor which is used for
* actual setting of dynamic values
*
* Copyright (c) 2008-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2008-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2006-2008 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
@@ -1424,7 +1424,8 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe )
timeMap & time_map = m_pattern->getTimeMap();
timeMap::iterator it = time_map.begin();
p.setPen( QColor( 0xFF, 0xDF, 0x20 ) );
do
while( it != time_map.end() )
{
Sint32 len_ticks = 4;
@@ -1516,7 +1517,7 @@ void AutomationEditor::paintEvent( QPaintEvent * _pe )
}
else printf("not in range\n");
++it;
} while( it != time_map.end() );
}
}
else
{

View File

@@ -1,9 +1,7 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* main_window.cpp - implementation of LMMS-main-window
*
* Copyright (c) 2004-2011 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -810,16 +808,17 @@ void MainWindow::help( void )
void MainWindow::toggleWindow( QWidget * _w )
void MainWindow::toggleWindow( QWidget *window, bool forceShow )
{
QWidget * parent = _w->parentWidget();
QWidget *parent = window->parentWidget();
if( m_workspace->activeSubWindow() != parent
|| parent->isHidden() )
if( forceShow ||
m_workspace->activeSubWindow() != parent ||
parent->isHidden() )
{
parent->show();
_w->show();
_w->setFocus();
window->show();
window->setFocus();
}
else
{
@@ -836,9 +835,9 @@ void MainWindow::toggleWindow( QWidget * _w )
void MainWindow::toggleBBEditorWin( void )
void MainWindow::toggleBBEditorWin( bool forceShow )
{
toggleWindow( engine::getBBEditor() );
toggleWindow( engine::getBBEditor(), forceShow );
}
@@ -1072,5 +1071,3 @@ void MainWindow::autoSave()
#include "moc_MainWindow.cxx"
#endif

View File

@@ -125,7 +125,7 @@
<item>
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>Copyright (c) 2004-2012, LMMS developers</string>
<string>Copyright (c) 2004-2013, LMMS developers</string>
</property>
<property name="wordWrap" >
<bool>true</bool>

View File

@@ -1,7 +1,7 @@
/*
* export_project_dialog.cpp - implementation of dialog for exporting project
*
* Copyright (c) 2004-2012 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -39,6 +39,7 @@ exportProjectDialog::exportProjectDialog( const QString & _file_name,
QDialog( _parent ),
Ui::ExportProjectDialog(),
m_fileName( _file_name ),
m_fileExtension(),
m_multiExport(multi_export)
{
setupUi( this );
@@ -103,6 +104,8 @@ void exportProjectDialog::reject()
{
(*it)->abortProcessing();
}
QDialog::reject();
}
@@ -198,7 +201,7 @@ void exportProjectDialog::multiRender()
m_unmuted.push_back(tk);
QString nextName = tk->name();
nextName = nextName.remove(QRegExp("[^a-zA-Z]"));
QString name = QString("%1_%2.wav").arg(x++).arg(nextName);
QString name = QString( "%1_%2%3" ).arg( x++ ).arg( nextName ).arg( m_fileExtension );
m_fileName = QDir(m_dirName).filePath(name);
prepRender();
}
@@ -219,7 +222,7 @@ void exportProjectDialog::multiRender()
m_unmuted.push_back(tk);
QString nextName = tk->name();
nextName = nextName.remove(QRegExp("[^a-zA-Z]"));
QString name = QString("%1_%2.wav").arg(x++).arg(nextName);
QString name = QString( "%1_%2%3" ).arg( x++ ).arg( nextName ).arg( m_fileExtension );
m_fileName = QDir(m_dirName).filePath(name);
prepRender();
}
@@ -290,6 +293,7 @@ void exportProjectDialog::startBtnClicked()
__fileEncodeDevices[i].m_description ) )
{
m_ft = __fileEncodeDevices[i].m_fileFormat;
m_fileExtension = QString( QLatin1String( __fileEncodeDevices[i].m_extension ) );
break;
}
}

View File

@@ -117,7 +117,9 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) :
m_oneInstrumentTrackWindow( configManager::inst()->value( "ui",
"oneinstrumenttrackwindow" ).toInt() ),
m_compactTrackButtons( configManager::inst()->value( "ui",
"compacttrackbuttons" ).toInt() )
"compacttrackbuttons" ).toInt() ),
m_syncVSTPlugins( configManager::inst()->value( "ui",
"syncvstplugins" ).toInt() )
{
setWindowIcon( embed::getIconPixmap( "setup_general" ) );
setWindowTitle( tr( "Setup LMMS" ) );
@@ -186,7 +188,7 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) :
tabWidget * misc_tw = new tabWidget( tr( "MISC" ), general );
misc_tw->setFixedHeight( 156 );
misc_tw->setFixedHeight( 174 );
ledCheckBox * enable_tooltips = new ledCheckBox(
tr( "Enable tooltips" ),
@@ -247,6 +249,15 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) :
this, SLOT( toggleCompactTrackButtons( bool ) ) );
ledCheckBox * syncVST = new ledCheckBox(
tr( "Sync VST plugins to host playback" ),
misc_tw );
syncVST->move( 10, 144 );
syncVST->setChecked( m_syncVSTPlugins );
connect( syncVST, SIGNAL( toggled( bool ) ),
this, SLOT( toggleSyncVSTPlugins( bool ) ) );
gen_layout->addWidget( bufsize_tw );
gen_layout->addSpacing( 10 );
@@ -774,6 +785,8 @@ void setupDialog::accept()
QString::number( m_oneInstrumentTrackWindow ) );
configManager::inst()->setValue( "ui", "compacttrackbuttons",
QString::number( m_compactTrackButtons ) );
configManager::inst()->setValue( "ui", "syncvstplugins",
QString::number( m_syncVSTPlugins ) );
configManager::inst()->setWorkingDir( m_workingDir );
configManager::inst()->setVSTDir( m_vstDir );
@@ -956,6 +969,15 @@ void setupDialog::toggleCompactTrackButtons( bool _enabled )
void setupDialog::toggleSyncVSTPlugins( bool _enabled )
{
m_syncVSTPlugins = _enabled;
}
void setupDialog::toggleOneInstrumentTrackWindow( bool _enabled )
{
m_oneInstrumentTrackWindow = _enabled;

View File

@@ -175,29 +175,36 @@ void EffectRackView::update()
Qt::QueuedConnection );
view->show();
m_effectViews.append( view );
view_map[i] = true;
if( i < view_map.size() )
{
view_map[i] = true;
}
else
{
view_map.append( true );
}
}
}
int i = m_lastY = 0;
int i = m_lastY = 0, nView = 0;
for( QVector<EffectView *>::Iterator it = m_effectViews.begin();
it != m_effectViews.end(); )
it != m_effectViews.end(); i++ )
{
if( i < view_map.size() && i < m_effectViews.size() &&
view_map[i] == false )
if( i < view_map.size() && view_map[i] == false )
{
delete m_effectViews[i];
delete m_effectViews[nView];
it = m_effectViews.erase( it );
}
else
{
( *it )->move( 0, m_lastY );
m_lastY += ( *it )->height();
++nView;
++it;
++i;
}
}
w->setFixedSize( 210, m_lastY );
QWidget::update();
@@ -242,7 +249,7 @@ void EffectRackView::addEffect()
void EffectRackView::modelChanged()
{
clearViews();
//clearViews();
m_effectsGroupBox->setModel( &fxChain()->m_enabledModel );
connect( fxChain(), SIGNAL( aboutToClear() ),
this, SLOT( clearViews() ) );

View File

@@ -85,6 +85,8 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
"while deciding when to stop processing signals." ) );
setModel( _model );
if( effect()->controls()->controlCount() > 0 )
{
QPushButton * ctls_btn = new QPushButton( tr( "Controls" ),
@@ -94,6 +96,7 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
ctls_btn->setGeometry( 140, 14, 50, 20 );
connect( ctls_btn, SIGNAL( clicked() ),
this, SLOT( editControls() ) );
m_controlView = effect()->controls()->createView();
if( m_controlView )
{
@@ -141,7 +144,8 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
"Right clicking will bring up a context menu where you can change the order "
"in which the effects are processed or delete an effect altogether." ) );
setModel( _model );
//move above vst effect view creation
//setModel( _model );
}
@@ -149,7 +153,15 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
EffectView::~EffectView()
{
#ifdef LMMS_BUILD_LINUX
delete m_subWindow;
#else
// otherwise on win32 build VST GUI can get lost
m_subWindow->hide();
#endif
}
@@ -159,7 +171,7 @@ void EffectView::editControls()
{
if( m_subWindow )
{
if( !effect()->controls()->isViewVisible() )
if( !m_subWindow->isVisible() )
{
m_subWindow->show();
m_subWindow->raise();

View File

@@ -2,7 +2,7 @@
* pixmap_button.cpp - implementation of pixmap-button (often used as "themed"
* checkboxes/radiobuttons etc)
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -57,7 +57,7 @@ void pixmapButton::paintEvent( QPaintEvent * )
{
QPainter p( this );
if( model()->value() || m_pressed )
if( ( model() != NULL && model()->value() ) || m_pressed )
{
if( !m_activePixmap.isNull() )
{

View File

@@ -221,6 +221,18 @@ void InstrumentTrack::processInEvent( const midiEvent & _me,
const midiTime & _time )
{
engine::getMixer()->lock();
// in the special case this event comes from a MIDI port, the instrument
// is MIDI based (VST plugin, Sf2Player etc.) and the user did not set
// a dedicated MIDI output channel, directly pass the MIDI event to the
// instrument plugin
if( _me.isFromMidiPort() && m_instrument->isMidiBased()/* &&
midiPort()->realOutputChannel() < 0 */ )
{
m_instrument->handleMidiEvent( _me, _time );
return;
}
switch( _me.m_type )
{
// we don't send MidiNoteOn, MidiNoteOff and MidiKeyPressure
@@ -315,6 +327,17 @@ void InstrumentTrack::processInEvent( const midiEvent & _me,
m_sustainPedalPressed = false;
}
}
if( _me.controllerNumber() == MidiControllerAllSoundOff ||
_me.controllerNumber() == MidiControllerAllNotesOff ||
_me.controllerNumber() == MidiControllerOmniOn ||
_me.controllerNumber() == MidiControllerOmniOff ||
_me.controllerNumber() == MidiControllerMonoOn ||
_me.controllerNumber() == MidiControllerPolyOn )
{
silenceAllNotes();
}
m_instrument->handleMidiEvent( _me, _time );
break;
case MidiProgramChange:
m_instrument->handleMidiEvent( _me, _time );
@@ -1036,9 +1059,9 @@ void InstrumentTrackView::freeInstrumentTrackWindow()
model()->setHook( NULL );
m_window->setInstrumentTrackView( NULL );
m_window->parentWidget()->hide();
m_window->setModel(
engine::dummyTrackContainer()->
dummyInstrumentTrack() );
//m_window->setModel(
// engine::dummyTrackContainer()->
// dummyInstrumentTrack() );
m_window->updateInstrumentView();
s_windowCache << m_window;
}

View File

@@ -1,7 +1,7 @@
/*
* bb_track.cpp - implementation of class bbTrack and bbTCO
*
* Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2013 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -33,6 +33,7 @@
#include "embed.h"
#include "engine.h"
#include "gui_templates.h"
#include "MainWindow.h"
#include "mixer.h"
#include "rename_dialog.h"
#include "song.h"
@@ -223,10 +224,9 @@ void bbTCOView::paintEvent( QPaintEvent * )
void bbTCOView::openInBBEditor()
{
engine::getBBTrackContainer()->setCurrentBB( bbTrack::numOfBBTrack(
m_bbTCO->getTrack() ) );
engine::getBBEditor()->show();
engine::getBBEditor()->setFocus();
engine::getBBTrackContainer()->setCurrentBB( bbTrack::numOfBBTrack( m_bbTCO->getTrack() ) );
engine::mainWindow()->toggleBBEditorWin( true );
}