diff -Nru mixxx-1.6.0/COPYING mixxx-1.6.1/COPYING
--- mixxx-1.6.0/COPYING 2007-02-25 18:50:59.000000000 -0600
+++ mixxx-1.6.1/COPYING 2008-09-20 18:05:46.000000000 -0500
@@ -1,3 +1,3 @@
-Mixxx is Copyright (C) 2000-2007 by its respective authors. This version
+Mixxx is Copyright (C) 2000-2008 by its respective authors. This version
of the program is distributed under the General Public Licence version 2,
as described in the file LICENSE distributed with the program.
diff -Nru mixxx-1.6.0/debian/changelog mixxx-1.6.1/debian/changelog
--- mixxx-1.6.0/debian/changelog 2008-11-15 15:24:51.000000000 -0600
+++ mixxx-1.6.1/debian/changelog 2008-11-15 15:24:55.000000000 -0600
@@ -1,3 +1,16 @@
+mixxx (1.6.1-1ubuntu1) jaunty; urgency=low
+
+ * Merge from debian unstable, remaining changes (LP: #298514):
+ - Update desktop file.
+
+ -- Nathan Handler Sat, 15 Nov 2008 14:13:30 -0600
+
+mixxx (1.6.1-1) unstable; urgency=low
+
+ * New Upstream Version
+
+ -- Free Ekanayaka Sat, 15 Nov 2008 00:00:37 +0100
+
mixxx (1.6.0-1ubuntu1) jaunty; urgency=low
* Merge from debian unstable, remaining changes (LP: #262971):
diff -Nru mixxx-1.6.0/lib/soundtouch/3dnow_win.cpp mixxx-1.6.1/lib/soundtouch/3dnow_win.cpp
--- mixxx-1.6.0/lib/soundtouch/3dnow_win.cpp 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/3dnow_win.cpp 2005-02-10 07:11:55.000000000 -0600
@@ -35,7 +35,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: 3dnow_win.cpp 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/AAFilter.cpp mixxx-1.6.1/lib/soundtouch/AAFilter.cpp
--- mixxx-1.6.0/lib/soundtouch/AAFilter.cpp 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/AAFilter.cpp 2005-02-10 07:11:55.000000000 -0600
@@ -12,7 +12,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: AAFilter.cpp 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/AAFilter.h mixxx-1.6.1/lib/soundtouch/AAFilter.h
--- mixxx-1.6.0/lib/soundtouch/AAFilter.h 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/AAFilter.h 2005-02-10 07:11:55.000000000 -0600
@@ -13,7 +13,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: AAFilter.h 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/cpu_detect.h mixxx-1.6.1/lib/soundtouch/cpu_detect.h
--- mixxx-1.6.0/lib/soundtouch/cpu_detect.h 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/cpu_detect.h 2005-02-10 07:11:55.000000000 -0600
@@ -12,7 +12,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: cpu_detect.h 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/cpu_detect_x86_gcc.cpp mixxx-1.6.1/lib/soundtouch/cpu_detect_x86_gcc.cpp
--- mixxx-1.6.0/lib/soundtouch/cpu_detect_x86_gcc.cpp 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/cpu_detect_x86_gcc.cpp 2005-02-10 07:11:55.000000000 -0600
@@ -12,7 +12,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: cpu_detect_x86_gcc.cpp 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/cpu_detect_x86_win.cpp mixxx-1.6.1/lib/soundtouch/cpu_detect_x86_win.cpp
--- mixxx-1.6.0/lib/soundtouch/cpu_detect_x86_win.cpp 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/cpu_detect_x86_win.cpp 2005-02-10 07:11:55.000000000 -0600
@@ -12,7 +12,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: cpu_detect_x86_win.cpp 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/FIFOSampleBuffer.cpp mixxx-1.6.1/lib/soundtouch/FIFOSampleBuffer.cpp
--- mixxx-1.6.0/lib/soundtouch/FIFOSampleBuffer.cpp 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/FIFOSampleBuffer.cpp 2005-02-10 07:11:55.000000000 -0600
@@ -15,7 +15,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: FIFOSampleBuffer.cpp 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/FIFOSampleBuffer.h mixxx-1.6.1/lib/soundtouch/FIFOSampleBuffer.h
--- mixxx-1.6.0/lib/soundtouch/FIFOSampleBuffer.h 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/FIFOSampleBuffer.h 2005-02-10 07:11:55.000000000 -0600
@@ -15,7 +15,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: FIFOSampleBuffer.h 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/FIFOSamplePipe.h mixxx-1.6.1/lib/soundtouch/FIFOSamplePipe.h
--- mixxx-1.6.0/lib/soundtouch/FIFOSamplePipe.h 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/FIFOSamplePipe.h 2005-02-10 07:11:55.000000000 -0600
@@ -17,7 +17,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: FIFOSamplePipe.h 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/FIRFilter.cpp mixxx-1.6.1/lib/soundtouch/FIRFilter.cpp
--- mixxx-1.6.0/lib/soundtouch/FIRFilter.cpp 2006-08-10 07:08:06.000000000 -0500
+++ mixxx-1.6.1/lib/soundtouch/FIRFilter.cpp 2006-08-10 07:08:06.000000000 -0500
@@ -11,7 +11,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2006-08-10 08:08:06 -0400 (Thu, 10 Aug 2006) $
+// Last changed : $Date: 2006-08-10 05:08:06 -0700 (Thu, 10 Aug 2006) $
// File revision : $Revision: 967 $
//
// $Id: FIRFilter.cpp 967 2006-08-10 12:08:06Z adam_d $
diff -Nru mixxx-1.6.0/lib/soundtouch/FIRFilter.h mixxx-1.6.1/lib/soundtouch/FIRFilter.h
--- mixxx-1.6.0/lib/soundtouch/FIRFilter.h 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/FIRFilter.h 2005-02-10 07:11:55.000000000 -0600
@@ -11,7 +11,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: FIRFilter.h 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/mmx_gcc.cpp mixxx-1.6.1/lib/soundtouch/mmx_gcc.cpp
--- mixxx-1.6.0/lib/soundtouch/mmx_gcc.cpp 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/mmx_gcc.cpp 2005-02-10 07:11:55.000000000 -0600
@@ -15,7 +15,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: mmx_gcc.cpp 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/mmx_win.cpp mixxx-1.6.1/lib/soundtouch/mmx_win.cpp
--- mixxx-1.6.0/lib/soundtouch/mmx_win.cpp 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/mmx_win.cpp 2005-02-10 07:11:55.000000000 -0600
@@ -15,7 +15,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: mmx_win.cpp 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/RateTransposer.cpp mixxx-1.6.1/lib/soundtouch/RateTransposer.cpp
--- mixxx-1.6.0/lib/soundtouch/RateTransposer.cpp 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/RateTransposer.cpp 2005-02-10 07:11:55.000000000 -0600
@@ -10,7 +10,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: RateTransposer.cpp 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/RateTransposer.h mixxx-1.6.1/lib/soundtouch/RateTransposer.h
--- mixxx-1.6.0/lib/soundtouch/RateTransposer.h 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/RateTransposer.h 2005-02-10 07:11:55.000000000 -0600
@@ -14,7 +14,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: RateTransposer.h 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/SoundTouch.cpp mixxx-1.6.1/lib/soundtouch/SoundTouch.cpp
--- mixxx-1.6.0/lib/soundtouch/SoundTouch.cpp 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/SoundTouch.cpp 2005-02-10 07:11:55.000000000 -0600
@@ -41,7 +41,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: SoundTouch.cpp 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/SoundTouch.h mixxx-1.6.1/lib/soundtouch/SoundTouch.h
--- mixxx-1.6.0/lib/soundtouch/SoundTouch.h 2006-08-10 14:32:06.000000000 -0500
+++ mixxx-1.6.1/lib/soundtouch/SoundTouch.h 2006-08-10 14:32:06.000000000 -0500
@@ -41,7 +41,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2006-08-10 15:32:06 -0400 (Thu, 10 Aug 2006) $
+// Last changed : $Date: 2006-08-10 12:32:06 -0700 (Thu, 10 Aug 2006) $
// File revision : $Revision: 975 $
//
// $Id: SoundTouch.h 975 2006-08-10 19:32:06Z adam_d $
diff -Nru mixxx-1.6.0/lib/soundtouch/sse_win.cpp mixxx-1.6.1/lib/soundtouch/sse_win.cpp
--- mixxx-1.6.0/lib/soundtouch/sse_win.cpp 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/sse_win.cpp 2005-02-10 07:11:55.000000000 -0600
@@ -23,7 +23,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: sse_win.cpp 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/STTypes.h mixxx-1.6.1/lib/soundtouch/STTypes.h
--- mixxx-1.6.0/lib/soundtouch/STTypes.h 2008-05-11 10:28:27.000000000 -0500
+++ mixxx-1.6.1/lib/soundtouch/STTypes.h 2008-05-11 10:28:27.000000000 -0500
@@ -8,7 +8,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2008-05-11 11:28:27 -0400 (Sun, 11 May 2008) $
+// Last changed : $Date: 2008-05-11 08:28:27 -0700 (Sun, 11 May 2008) $
// File revision : $Revision: 1981 $
//
// $Id: STTypes.h 1981 2008-05-11 15:28:27Z gamegod $
diff -Nru mixxx-1.6.0/lib/soundtouch/TDStretch.cpp mixxx-1.6.1/lib/soundtouch/TDStretch.cpp
--- mixxx-1.6.0/lib/soundtouch/TDStretch.cpp 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/TDStretch.cpp 2005-02-10 07:11:55.000000000 -0600
@@ -13,7 +13,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: TDStretch.cpp 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/lib/soundtouch/TDStretch.h mixxx-1.6.1/lib/soundtouch/TDStretch.h
--- mixxx-1.6.0/lib/soundtouch/TDStretch.h 2005-02-10 07:11:55.000000000 -0600
+++ mixxx-1.6.1/lib/soundtouch/TDStretch.h 2005-02-10 07:11:55.000000000 -0600
@@ -13,7 +13,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2005-02-10 08:11:55 -0500 (Thu, 10 Feb 2005) $
+// Last changed : $Date: 2005-02-10 05:11:55 -0800 (Thu, 10 Feb 2005) $
// File revision : $Revision: 857 $
//
// $Id: TDStretch.h 857 2005-02-10 13:11:55Z tuehaste $
diff -Nru mixxx-1.6.0/LICENSE mixxx-1.6.1/LICENSE
--- mixxx-1.6.0/LICENSE 2007-11-11 11:51:46.000000000 -0600
+++ mixxx-1.6.1/LICENSE 2008-09-20 18:05:46.000000000 -0500
@@ -1,5 +1,5 @@
-Mixxx version 1.6.0, Digital DJ'ing software.
-Copyright (C) 2001-2007 Haste Andersen and Mixxx developers
+Mixxx version 1.6.1, Digital DJ'ing software.
+Copyright (C) 2001-2008 Mixxx development team
Depending on your platform, you may receive a copy of PortAudio
(http://www.portaudio.com/) which is distributed under the
diff -Nru mixxx-1.6.0/.mixxx_flags.svn mixxx-1.6.1/.mixxx_flags.svn
--- mixxx-1.6.0/.mixxx_flags.svn 2008-08-05 15:43:17.000000000 -0500
+++ mixxx-1.6.1/.mixxx_flags.svn 1969-12-31 18:00:00.000000000 -0600
@@ -1 +0,0 @@
-#define BUILD_FLAGS "hifieq vinylcontrol optimize=1 "
diff -Nru mixxx-1.6.0/Mixxx.nsi mixxx-1.6.1/Mixxx.nsi
--- mixxx-1.6.0/Mixxx.nsi 2008-07-29 10:08:58.000000000 -0500
+++ mixxx-1.6.1/Mixxx.nsi 2008-09-11 23:51:33.000000000 -0500
@@ -15,7 +15,7 @@
BrandingText " "
; The file to write
-OutFile "mixxx-1.6.0-beta4-win.exe"
+OutFile "mixxx-1.6.0-win.exe"
; The default installation directory
InstallDir $PROGRAMFILES\Mixxx
@@ -66,8 +66,9 @@
SetOutPath $INSTDIR\midi
File "dist\midi\*.xml"
- SetOutPath $INSTDIR\promo
- File "dist\promo\*"
+ ;Disabled for initial 1.6.0 release
+ ;SetOutPath $INSTDIR\promo
+ ;File "dist\promo\*"
SetOutPath $INSTDIR\keyboard
File "src\keyboard\Standard.kbd.cfg"
@@ -76,9 +77,6 @@
SetOutPath "$INSTDIR\skins"
File "src\skins\cross.png"
- SetOutPath "$INSTDIR\skins\Natt"
- File "src\skins\Natt\*"
-
SetOutPath "$INSTDIR\skins\Collusion (1280)"
File "src\skins\Collusion (1280)\*"
@@ -1279,7 +1277,6 @@
Delete $INSTDIR\skins\outlineClose\*.*
Delete $INSTDIR\skins\outlineSmall\*.*
Delete $INSTDIR\skins\outlineMini\*.*
- Delete "$INSTDIR\skins\Natt\*.*"
Delete "$INSTDIR\skins\Collusion (1280)\*.*"
Delete "$INSTDIR\skins\Collusion (1280-WS)\*.*"
Delete $INSTDIR\skins\hercules\*.*
@@ -1288,12 +1285,11 @@
Delete $INSTDIR\skins\*.*
Delete $INSTDIR\keyboard\*.*
Delete $INSTDIR\midi\*.*
- Delete $INSTDIR\promo\*.*
+ ;Delete $INSTDIR\promo\*.*
RMDir "$INSTDIR\skins\outline"
RMDir "$INSTDIR\skins\outlineClose"
RMDir "$INSTDIR\skins\outlineSmall"
RMDir "$INSTDIR\skins\outlineMini"
- RMDir "$INSTDIR\skins\Natt"
RMDir "$INSTDIR\skins\Collusion (1280)"
RMDir "$INSTDIR\skins\Collusion (1280-WS)"
RMDir "$INSTDIR\skins\hercules"
@@ -1302,7 +1298,7 @@
RMDir "$INSTDIR\skins"
RMDir "$INSTDIR\midi"
RMDir "$INSTDIR\keyboard"
- RMDir "$INSTDIR\promo"
+ ;RMDir "$INSTDIR\promo"
; Remove shortcuts, if any
diff -Nru mixxx-1.6.0/.mixxx_version.svn mixxx-1.6.1/.mixxx_version.svn
--- mixxx-1.6.0/.mixxx_version.svn 2008-08-05 15:43:17.000000000 -0500
+++ mixxx-1.6.1/.mixxx_version.svn 1969-12-31 18:00:00.000000000 -0600
@@ -1 +0,0 @@
-#define BUILD_REV ""
diff -Nru mixxx-1.6.0/README mixxx-1.6.1/README
--- mixxx-1.6.0/README 2008-07-06 12:21:19.000000000 -0500
+++ mixxx-1.6.1/README 2008-09-20 18:05:46.000000000 -0500
@@ -1,4 +1,4 @@
-Mixxx 1.6.0
+Mixxx 1.6.1
* HOMEPAGE *************************************************
http://www.mixxx.org
@@ -17,46 +17,8 @@
* NEWS *****************************************************
-Since Mixxx 1.5.0 was released (March 4th, 2007), the following changes have been made:
-
-* New MIDI mappings for Tascam US-428, M-Audio X-Session Pro, Evolution X-Session, FaderFox DJ2, and the M-Audio Torq Xponent
-* ALSA Sequencer MIDI support courtesy of Cedric Gestes
-* A couple of MIDI bug fixes (knobs now center properly, thanks to Sacha Berger)
-* Added support for 14-bit MIDI pitch wheel controllers (thanks to Adam Sugerman)
-* Hercules support on Linux improved (jog wheels work again)
-* New nCut skin from Frank Willascheck
-* Big stability improvements (3 bug fixes)
-* Multiple soundcards can now be used for output (master/headphones), in case you don't have a soundcard with 4 outputs on it.
-* Adam's wicked colour scheme support for skins
-* Can now change skins without restarting Mixxx (more hard work from Adam)
-* Channel VU meters are now pre-fader
-* VU meters are now much more smooth
-* Added clipping indicators (courtesy of John Sully)
-* Higher quality EQs and other sound quality improvements (also from John Sully)
-* New MIDI mapping format now in XML, supports controlling LEDs
-* Better Hercules support on Windows and Linux
-* Initial support for recording output
-* New BPM detection algorithm (Micah Lee/GSoC)
-* New media library (Nathan Prado/GSoC)
-* LADSPA effects support (Pawel Bartkiewicz/GSoC)
-* BPM Tap tempo
-* Library search function
-* Ported to QT4 (!)
-* Moved build system to SCONS
-* Redesigned preferences dialogs
-* Rewritten audio core (Albert)
-* Vinyl control support for Serato, Traktor Scratch, and FinalScratch (FS needs work, but the others are good)
-* Software preamp for vinyl control (can use turntables without a preamp)
-* Track info editor (double-click in library)
-* New library browse mode (CTAF)
-* Starts in fullscreen mode if launched with the -f flag.
-* Several MP3 decoder performance and stability improvements (John Sully)
-* Support for merengue
-* Reorganized "File" menu
-* NEXT mode now works as expected (plays the next track in the table)
-* Partial play queue
-* Lots of little OS X improvements
-* Improved consistency of fullscreen mode
+Check the Mixxx blog to find out what's new in this version:
+http://mixxxblog.blogspot.com
* UPGRADING ************************************************
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/.sconsign.tmp and /tmp/MHYQbGTmm3/mixxx-1.6.1/.sconsign.tmp differ
diff -Nru mixxx-1.6.0/src/bpmdetect.cpp mixxx-1.6.1/src/bpmdetect.cpp
--- mixxx-1.6.0/src/bpmdetect.cpp 2008-05-11 10:27:38.000000000 -0500
+++ mixxx-1.6.1/src/bpmdetect.cpp 2008-08-14 00:23:43.000000000 -0500
@@ -81,6 +81,8 @@
#include "cmetrics.h"
#endif
+#include
+
using namespace soundtouch;
#define INPUT_BLOCK_SAMPLES 2048
@@ -165,6 +167,7 @@
outcount = 0;
for (count = 0; count < numsamples; count++)
{
+// qDebug() << "======"<< "count:"<< count << "numsamples:"<_TrackInfoObject = pTrackInfoObject;
package->_BpmReceiver = pBpmReceiver;
-
+
// Read
minBpm = m_Config->getValueString(ConfigKey("[BPM]","BPMRangeStart")).toInt();
maxBpm = m_Config->getValueString(ConfigKey("[BPM]","BPMRangeEnd")).toInt();
entire = (bool)m_Config->getValueString(ConfigKey("[BPM]","AnalyzeEntireSong")).toInt();
-
+
package->_Scheme = new BpmScheme("Default", minBpm, maxBpm, entire);
-
+
m_qQueue.enqueue(package);
m_qMutex.unlock();
m_qWait.wakeAll();
@@ -112,6 +116,8 @@
int channels = 2;
float frequency = 44100;
+ qDebug() << "BPM detection starting for" << pTrackInfoObject->getFilename();
+
if(pTrackInfoObject->getSampleRate())
{
frequency = pTrackInfoObject->getSampleRate();
@@ -122,7 +128,7 @@
}
length = pSoundSource->length();
-
+ if (length <= 0) return;
if(!pScheme->getAnalyzeEntireSong())
{
length = length / 2;
@@ -191,14 +197,14 @@
#ifdef __C_METRICS__
cm_writemsg_ascii(1, "BPM detection failed, setting to 0.");
#endif
-
+
if(pBpmReceiver){
pBpmReceiver->setComplete(pTrackInfoObject, true, BPM);
- }
-
+ }
+
delete pSoundSource;
return;
- }
+ }
}
@@ -212,7 +218,7 @@
//The fallback is broken and is causing crashes. This will break us out and set the BPM to 0
//Remove these lines if you get the old BPM detection working
-
+
//qDebug() << "BPM detection failed the first time. Trying old version.";
@@ -281,7 +287,7 @@
pPeaks->update(0, iBeatBlockLength);
// Initialize beat probability vector
- ProbabilityVector * bpv = new ProbabilityVector(60.f/(float)pScheme->getMaxBpm(),
+ ProbabilityVector * bpv = new ProbabilityVector(60.f/(float)pScheme->getMaxBpm(),
60.f/(float)pScheme->getMinBpm(), kiBeatBins);
// Calculate BPM
@@ -328,7 +334,6 @@
qDebug() << "BPM detection successful for" << pTrackInfoObject->getFilename();
-
}
void BpmDetector::run()
diff -Nru mixxx-1.6.0/src/bpmdetector.h mixxx-1.6.1/src/bpmdetector.h
--- mixxx-1.6.0/src/bpmdetector.h 2008-06-13 21:35:45.000000000 -0500
+++ mixxx-1.6.1/src/bpmdetector.h 2008-08-14 00:23:43.000000000 -0500
@@ -66,6 +66,7 @@
/** Puts an TrackInfoObject into the queue of BPM detection. Thread safe, blocking. */
void enqueue(TrackInfoObject *pTrackInfoObject, BpmReceiver *pBpmReceiver=NULL);
void enqueue(TrackInfoObject *pTrackInfoObject, BpmScheme *scheme, BpmReceiver *pBpmReceiver=NULL);
+ int queueCount();
protected:
/** Main thread loop */
diff -Nru mixxx-1.6.0/src/defs_audiofiles.h mixxx-1.6.1/src/defs_audiofiles.h
--- mixxx-1.6.0/src/defs_audiofiles.h 2008-03-02 00:35:46.000000000 -0600
+++ mixxx-1.6.1/src/defs_audiofiles.h 2008-08-24 01:38:08.000000000 -0500
@@ -8,9 +8,9 @@
#define __DEFS_AUDIOFILES_H__
/** The types of audio files we support */
-#define MIXXX_SUPPORTED_AUDIO_FILETYPES "*.wav *.mp3 *.ogg *.aiff *.aif *.flac"
+#define MIXXX_SUPPORTED_AUDIO_FILETYPES "*.wav *.mp3 *.m4a *.ogg *.aiff *.aif *.flac"
/** A regex for the types of audio files we support */
-#define MIXXX_SUPPORTED_AUDIO_FILETYPES_REGEX "\\.(mp3|ogg|aiff|aif|wav|flac)"
+#define MIXXX_SUPPORTED_AUDIO_FILETYPES_REGEX "\\.(mp3|m4a|ogg|aiff|aif|wav|flac)"
#endif
diff -Nru mixxx-1.6.0/src/defs.h mixxx-1.6.1/src/defs.h
--- mixxx-1.6.0/src/defs.h 2008-07-29 18:51:22.000000000 -0500
+++ mixxx-1.6.1/src/defs.h 2008-09-20 18:05:46.000000000 -0500
@@ -17,7 +17,7 @@
#ifndef DEFS_H
#define DEFS_H
-#define VERSION "1.6.0"
+#define VERSION "1.6.1"
#define MIXXX_PROMO_DIR "promo"
#include
diff -Nru mixxx-1.6.0/src/dlgpreferences.h mixxx-1.6.1/src/dlgpreferences.h
--- mixxx-1.6.0/src/dlgpreferences.h 2008-01-30 17:44:00.000000000 -0600
+++ mixxx-1.6.1/src/dlgpreferences.h 2008-08-11 03:57:49.000000000 -0500
@@ -31,7 +31,6 @@
class MixxxApp;
class MixxxView;
-class PlayerProxy;
class SoundManager;
class Track;
class DlgPrefSound;
diff -Nru mixxx-1.6.0/src/dlgprefsound.cpp mixxx-1.6.1/src/dlgprefsound.cpp
--- mixxx-1.6.0/src/dlgprefsound.cpp 2008-07-06 13:11:20.000000000 -0500
+++ mixxx-1.6.1/src/dlgprefsound.cpp 2008-08-11 05:02:03.000000000 -0500
@@ -16,7 +16,6 @@
***************************************************************************/
#include "dlgprefsound.h"
-//#include "playerproxy.h"
#include
#include
#include
@@ -41,7 +40,6 @@
ConfigObject * _config) : QWidget(parent), Ui::DlgPrefSoundDlg()
{
m_bLatencySliderDrag = false;
- //player = _player;
m_pSoundManager = _soundman;
config = _config;
m_parent = parent;
@@ -125,7 +123,6 @@
// API's
ComboBoxSoundApi->clear();
ComboBoxSoundApi->insertItem(0, "None");
- //QStringList api = player->getSoundApiList();
QList apis = m_pSoundManager->getHostAPIList();
QListIterator api_it(apis);
QString api;
@@ -192,7 +189,6 @@
// Sample rate
ComboBoxSamplerates->clear();
- //QStringList srates = player->getSampleRates();
QList srates = m_pSoundManager->getSamplerateList();
QListIterator srate_it(srates);
QString srate;
@@ -293,7 +289,6 @@
qDebug() << "request msec " << getSliderLatencyMsec(SliderLatency->value());
// Close devices, and open using config data
- //player->close();
m_pSoundManager->closeDevices();
// Not much to do if the API is None...
diff -Nru mixxx-1.6.0/src/dlgprefsound.h mixxx-1.6.1/src/dlgprefsound.h
--- mixxx-1.6.0/src/dlgprefsound.h 2007-12-07 21:04:36.000000000 -0600
+++ mixxx-1.6.1/src/dlgprefsound.h 2008-08-11 03:57:49.000000000 -0500
@@ -60,8 +60,7 @@
int getSliderLatencyMsec(int);
/** Transform latency value in msec to slider value */
int getSliderLatencyVal(int);
- /** Pointer to player device */
- //PlayerProxy *player;
+ /** Pointer to the sound manager */
SoundManager* m_pSoundManager;
/** Pointer to config object */
ConfigObject *config;
diff -Nru mixxx-1.6.0/src/dlgprefvinyl.cpp mixxx-1.6.1/src/dlgprefvinyl.cpp
--- mixxx-1.6.0/src/dlgprefvinyl.cpp 2008-04-30 11:12:24.000000000 -0500
+++ mixxx-1.6.1/src/dlgprefvinyl.cpp 2008-08-11 05:02:03.000000000 -0500
@@ -23,7 +23,6 @@
#include
#include
#include "dlgprefvinyl.h"
-#include "playerproxy.h"
#include
#include
#include
@@ -42,7 +41,6 @@
DlgPrefVinyl::DlgPrefVinyl(QWidget * parent, SoundManager * soundman,
ConfigObject * _config) : QWidget(parent), Ui::DlgPrefVinylDlg()
{
- //player = _player;
m_pSoundManager = soundman;
config = _config;
@@ -247,7 +245,6 @@
// Apply Soundcard options
- //player->close();
//m_pSoundManager->closeDevices();
//NOTE: Soundcard options (input device selection) is applied by DlgPrefSound...
diff -Nru mixxx-1.6.0/src/enginebuffer.cpp mixxx-1.6.1/src/enginebuffer.cpp
--- mixxx-1.6.0/src/enginebuffer.cpp 2008-07-29 19:01:33.000000000 -0500
+++ mixxx-1.6.1/src/enginebuffer.cpp 2008-08-11 05:02:03.000000000 -0500
@@ -33,7 +33,6 @@
#include "enginebufferscalesrc.h"
#include "enginebufferscaledummy.h"
#include "mathstuff.h"
-#include "player.h"
#include "enginebuffercue.h"
// Static default values for rate buttons
diff -Nru mixxx-1.6.0/src/enginebuffercue.cpp mixxx-1.6.1/src/enginebuffercue.cpp
--- mixxx-1.6.0/src/enginebuffercue.cpp 2008-07-03 22:58:51.000000000 -0500
+++ mixxx-1.6.1/src/enginebuffercue.cpp 2008-08-11 05:02:03.000000000 -0500
@@ -18,7 +18,6 @@
#include "controlobject.h"
#include "enginebuffercue.h"
#include "enginebuffer.h"
-#include "player.h"
#include "mathstuff.h"
EngineBufferCue::EngineBufferCue(const char * group, EngineBuffer * pEngineBuffer)
diff -Nru mixxx-1.6.0/src/libraryscanner.cpp mixxx-1.6.1/src/libraryscanner.cpp
--- mixxx-1.6.0/src/libraryscanner.cpp 2008-01-26 00:34:52.000000000 -0600
+++ mixxx-1.6.1/src/libraryscanner.cpp 2008-08-14 00:24:33.000000000 -0500
@@ -31,7 +31,7 @@
{
m_qLibraryPlaylist = library_playlist;
m_qLibraryPath = libraryPath;
-
+
qDebug() << "Constructed LibraryScanner!!!";
}
@@ -41,15 +41,15 @@
}
void LibraryScanner::run()
-{
+{
//m_pProgress->slotStartTiming();
-
+
//Start scanning the library.
m_qLibraryPlaylist->addPath(m_qLibraryPath);
-
+
qDebug() << "Scan finished cleanly";
//m_pProgress->slotStopTiming();
-
+
emit(scanFinished());
}
@@ -63,13 +63,13 @@
//we need the signals to get processed immediately, we have to use BlockingQueuedConnection. (DirectConnection isn't an
//option for sending signals across threads.)
connect(m_qLibraryPlaylist, SIGNAL(startedLoading()), m_pProgress, SLOT(slotStartTiming()), Qt::BlockingQueuedConnection);
- connect(m_qLibraryPlaylist, SIGNAL(finishedLoading()), m_pProgress, SLOT(slotStopTiming()), Qt::BlockingQueuedConnection);
+ connect(m_qLibraryPlaylist, SIGNAL(finishedLoading()), m_pProgress, SLOT(slotStopTiming()), Qt::BlockingQueuedConnection);
connect(m_qLibraryPlaylist, SIGNAL(progressLoading(QString)), m_pProgress, SLOT(slotCheckTiming(QString)), Qt::BlockingQueuedConnection);
-
+
//connect(m_pProgress, SIGNAL(scanCancelled()), this, SLOT(terminate())); //This causes a deadlock, don't use it.
connect(m_pProgress, SIGNAL(scanCancelled()), m_qLibraryPlaylist, SLOT(slotCancelLibraryScan()));
-
- //connect(m_qPlaylists->at(0), SIGNAL(finishedLoading()), this, SIGNAL(scanFinished()), Qt::BlockingQueuedConnection);
+
+ //connect(m_qPlaylists->at(0), SIGNAL(finishedLoading()), this, SIGNAL(scanFinished()), Qt::BlockingQueuedConnection);
scan();
}
diff -Nru mixxx-1.6.0/src/main.cpp mixxx-1.6.1/src/main.cpp
--- mixxx-1.6.0/src/main.cpp 2008-07-13 22:21:19.000000000 -0500
+++ mixxx-1.6.1/src/main.cpp 2008-08-18 23:31:42.000000000 -0500
@@ -37,7 +37,8 @@
#include
#endif
-#ifdef A_THING_THAT_IS_NOT_DEFFED //Q_WS_WIN
+#ifdef Q_WS_WIN
+#ifdef DEBUGCONSOLE
#include // Debug Console
#include
@@ -62,7 +63,8 @@
setvbuf( stderr, NULL, _IONBF, 0 );
}
}
-#endif
+#endif // DEBUGCONSOLE
+#endif // Q_WS_WIN
QApplication * a;
@@ -131,11 +133,11 @@
#ifdef Q_WS_WIN
// For windows write all debug messages to a logfile:
Logfile.setName( "mixxx.log" );
-#ifndef QT3_SUPPORT
+ #ifndef QT3_SUPPORT
Logfile.open(IO_WriteOnly | IO_Translate);
-#else
+ #else
Logfile.open(QIODevice::WriteOnly | QIODevice::Text);
-#endif
+ #endif
#ifdef DEBUGCONSOLE
InitDebugConsole();
qInstallMsgHandler( MessageOutput );
diff -Nru mixxx-1.6.0/src/midi/Hercules DJ Console Rmx.midi.xml mixxx-1.6.1/src/midi/Hercules DJ Console Rmx.midi.xml
--- mixxx-1.6.0/src/midi/Hercules DJ Console Rmx.midi.xml 2008-04-05 23:52:11.000000000 -0500
+++ mixxx-1.6.1/src/midi/Hercules DJ Console Rmx.midi.xml 2008-09-18 23:42:45.000000000 -0500
@@ -71,7 +71,7 @@
Ctrl
0x14
-
+
@@ -79,12 +79,18 @@
PrevTrack
Ctrl
0x09
+
+
+
[Channel1]
NextTrack
Ctrl
0x0A
+
+
+
@@ -150,7 +156,7 @@
Ctrl
0x18
-
+
@@ -158,12 +164,18 @@
PrevTrack
Ctrl
0x21
+
+
+
[Channel2]
NextTrack
Ctrl
0x22
+
+
+
@@ -171,93 +183,104 @@
[Channel1]
filterHighKill
- Key
+ Ctrl
0x0E
- 1
+
+
+
[Channel2]
filterHighKill
- Key
+ Ctrl
0x26
- 1
+
+
+
[Channel1]
filterMidKill
- Key
+ Ctrl
0x0F
- 1
+
+
+
[Channel2]
filterMidKill
- Key
+ Ctrl
0x27
- 1
+
+
+
[Channel1]
filterLowKill
- Key
+ Ctrl
0x10
- 1
+
+
+
[Channel2]
filterLowKill
- Key
+ Ctrl
0x28
- 1
+
+
+
[Channel1]
beatsync
- Key
+ Ctrl
0x07
- 1
[Channel2]
beatsync
- Key
+ Ctrl
0x1B
- 1
-
[Playlist]
- SelectNextTrack
- Key
+ SelectPrevTrack
+ Ctrl
0x2A
- 1
[Playlist]
- SelectPrevTrack
- Key
+ SelectNextTrack
+ Ctrl
0x2B
- 1
[Channel1]
LoadSelectedTrack
- Key
+ Ctrl
0x12
- 1
+
+
+
[Channel2]
LoadSelectedTrack
- Key
+ Ctrl
0x16
- 1
+
+
+
@@ -275,6 +298,7 @@
+
[Master]
@@ -329,6 +353,7 @@
+
[Channel1]
diff -Nru mixxx-1.6.0/src/midiledhandler.cpp mixxx-1.6.1/src/midiledhandler.cpp
--- mixxx-1.6.0/src/midiledhandler.cpp 2008-08-05 10:59:27.000000000 -0500
+++ mixxx-1.6.1/src/midiledhandler.cpp 2008-09-15 22:45:48.000000000 -0500
@@ -10,15 +10,16 @@
double max, unsigned char status, unsigned char byte1)
: m_min(min), m_max(max), m_midi(midi), m_status(status), m_byte1(byte1) {
+ //OMGWTFBBQ: Massive hack to temporarily fix LP #254564 for the 1.6.0 release.
+ // Something's funky with our blocks handling? -- Albert 08/05/2008
+ if (group.isEmpty() || name.isEmpty()) return;
+
m_cobj = ControlObject::getControl(ConfigKey(group, name));
-
-
- //OMGWTFBBQ: Massive hack to temporarily fix LP #254564 for the 1.6.0 release.
- // Something's funky with our blocks handling? -- Albert 08/05/2008
- if (group.isEmpty() || name.isEmpty()) return;
-
+
//m_cobj should never be null, so Q_ASSERT here to make sure that we hear about it if it is null.
- Q_ASSERT(m_cobj);
+ // Q_ASSERT(m_cobj);
+ Q_ASSERT_X(m_cobj, "MidiLedHandler", "Invalid config group: '" + group + "' name:'" + name + "'");
+
connect(m_cobj, SIGNAL(valueChangedFromEngine(double)), this, SLOT(controlChanged(double)));
connect(m_cobj, SIGNAL(valueChanged(double)), this, SLOT(controlChanged(double)));
}
@@ -37,12 +38,12 @@
if (!node.isNull() && node.isElement()) {
QDomNode light = node.firstChild();
-
- while (!light.isNull()) {
+
+ while (!light.isNull()) {
if(light.nodeName() == "light") {
QString group = WWidget::selectNodeQString(light, "group");
QString key = WWidget::selectNodeQString(light, "key");
-
+
unsigned char status = (unsigned char)WWidget::selectNodeInt(light, "status");
unsigned char midino = (unsigned char)WWidget::selectNodeInt(light, "midino");
float min = 0.0f;
@@ -56,9 +57,9 @@
if (!light.firstChildElement("maximum").isNull()) {
max = WWidget::selectNodeFloat(light, "maximum");
}
-
- allhandlers.append(new MidiLedHandler(group, key, midi, min, max, status, midino));
- }
+
+ allhandlers.append(new MidiLedHandler(group, key, midi, min, max, status, midino));
+ }
light = light.nextSibling();
}
}
diff -Nru mixxx-1.6.0/src/midiobjectwin.cpp mixxx-1.6.1/src/midiobjectwin.cpp
--- mixxx-1.6.0/src/midiobjectwin.cpp 2008-04-06 19:24:52.000000000 -0500
+++ mixxx-1.6.1/src/midiobjectwin.cpp 2008-09-18 00:26:57.000000000 -0500
@@ -18,6 +18,7 @@
#include "midiobjectwin.h"
#include "midiledhandler.h"
#include
+#include
#include
#ifdef __WIN__
@@ -124,8 +125,11 @@
void MidiObjectWin::handleMidi(char channel, char midicontrol, char midivalue)
{
- qDebug() << QString("midi miditype: ") << QString(channel& 240) << QString(" ch: ") << QString(channel&15) << QString(", ctrl: ") << QString(midicontrol) << QString(", val: ") << QString(midivalue);
- send((MidiCategory)(channel & 240), channel&15, midicontrol, midivalue);
+ qDebug() << QString("midi miditype: %1 ch: %2, ctrl: %3, val: %4").arg(QString::number(channel& 240, 16).toUpper())
+ .arg(QString::number(channel&15, 16).toUpper())
+ .arg(QString::number(midicontrol, 16).toUpper())
+ .arg(QString::number(midivalue, 16).toUpper());
+ receive((MidiCategory)(channel & 240), channel&15, midicontrol, midivalue, device); // void receive(MidiCategory category, char channel, char control, char value, QString device);
}
// C/C++ wrapper function
diff -Nru mixxx-1.6.0/src/mixxx.cpp mixxx-1.6.1/src/mixxx.cpp
--- mixxx-1.6.0/src/mixxx.cpp 2008-07-15 22:46:38.000000000 -0500
+++ mixxx-1.6.1/src/mixxx.cpp 2008-09-23 01:52:28.000000000 -0500
@@ -41,7 +41,6 @@
#include "log.h"
#include "dlgabout.h"
-#include "playerproxy.h"
#include "soundmanager.h"
#include "defs_urls.h"
#include "defs_audiofiles.h"
@@ -93,7 +92,6 @@
#endif
//Reset pointer to players
- //player = 0;
soundmanager = 0;
m_pTrack = 0;
prefDlg = 0;
@@ -204,8 +202,6 @@
master = new EngineMaster(config, buffer1, buffer2, channel1, channel2, "[Master]");
// Initialize player device
- //Player::setMaster(master);
- //player = new PlayerProxy(config);
soundmanager = new SoundManager(config, master);
soundmanager->queryDevices();
@@ -242,7 +238,7 @@
view=new MixxxView(frame, kbdconfig, qSkinPath, config);
- // TODO : Move this to WaveformViewerFactory or something.
+ // TODO rryan : Move this to WaveformViewerFactory or something.
/*
if (bVisualsWaveform && !view->activeWaveform())
{
@@ -255,20 +251,6 @@
}
*/
- // Tell EngineBuffer to notify the visuals if they are WVisualWaveform
- if (view->activeWaveform())
- {
- // Dynamic zoom on visuals
- if (view->m_bZoom)
- {
- // TODO rryan : USE THESE CONTROLOBJECTS IN THE NEWVISUAL CODE
- //ControlObject::connectControls(ConfigKey("[Channel1]", "rate"), ConfigKey("[Channel1]", "VisualLengthScale-marks"));
- //ControlObject::connectControls(ConfigKey("[Channel1]", "rate"), ConfigKey("[Channel1]", "VisualLengthScale-signal"));
- //ControlObject::connectControls(ConfigKey("[Channel2]", "rate"), ConfigKey("[Channel2]", "VisualLengthScale-marks"));
- //ControlObject::connectControls(ConfigKey("[Channel2]", "rate"), ConfigKey("[Channel2]", "VisualLengthScale-signal"));
- }
- }
-
// Verify path for xml track file.
QFile trackfile(config->getValueString(ConfigKey("[Playlist]","Listfile")));
if ((config->getValueString(ConfigKey("[Playlist]","Listfile")).length()<1) || (!trackfile.exists()))
@@ -334,9 +316,6 @@
#endif
// Try open player device If that fails, the preference panel is opened.
- //if (!player->open())
- // prefDlg->setHidden(false);
-
if (soundmanager->setupDevices() != 0)
{
@@ -377,15 +356,7 @@
// Initialize visualization of temporal effects
channel1->setEngineBuffer(buffer1);
channel2->setEngineBuffer(buffer2);
-
- // Dynamic scaling of temporal effect curves
- if (view->m_bZoom)
- {
- // TODO rryan, use these!
- //ControlObject::connectControls(ConfigKey("[Channel1]", "rate"), ConfigKey("[Channel1]", "VisualLengthScale-temporal"));
- //ControlObject::connectControls(ConfigKey("[Channel2]", "rate"), ConfigKey("[Channel2]", "VisualLengthScale-temporal"));
- }
-
+
#ifdef __SCRIPT__
scriptEng = new ScriptEngine(this, m_pTrack);
#endif
@@ -437,10 +408,6 @@
qDebug() << "Write track xml, " << qTime.elapsed();
m_pTrack->writeXML(config->getValueString(ConfigKey("[Playlist]","Listfile")));
- //qDebug() << "close player, " << qTime.elapsed();
- //player->close();
- //qDebug() << "player->close() done";
-
qDebug() << "close soundmanager" << qTime.elapsed();
soundmanager->closeDevices();
qDebug() << "soundmanager->close() done";
@@ -449,8 +416,6 @@
config->set(ConfigKey("[Controls]","TrackEndModeCh1"), ConfigValue((int)ControlObject::getControl(ConfigKey("[Channel1]","TrackEndMode"))->get()));
config->set(ConfigKey("[Controls]","TrackEndModeCh2"), ConfigValue((int)ControlObject::getControl(ConfigKey("[Channel2]","TrackEndMode"))->get()));
- //qDebug() << "delete player, " << qTime.elapsed();
- //delete player;
qDebug() << "delete soundmanager, " << qTime.elapsed();
delete soundmanager;
qDebug() << "delete master, " << qTime.elapsed();
@@ -521,6 +486,10 @@
playlistsImport->setShortcut(tr("Ctrl+I"));
playlistsImport->setShortcutContext(Qt::ApplicationShortcut);
+ batchBpmDetect = new QAction(tr("Batch BPM Detect (up to 100 songs per run)"), this);
+ connect(batchBpmDetect, SIGNAL(activated()), m_pTrack, SLOT(slotBatchBPMDetection()));
+
+
#ifdef __IPOD__
iPodToggle = new QAction(tr("iPod &Active"), this);
iPodToggle->setShortcut(tr("Ctrl+A"));
@@ -676,6 +645,7 @@
libraryMenu->addSeparator();
libraryMenu->addAction(playlistsNew);
libraryMenu->addAction(playlistsImport);
+ //libraryMenu->addAction(batchBpmDetect);
#ifdef __IPOD__
libraryMenu->addSeparator();
@@ -888,7 +858,8 @@
void MixxxApp::slotOptionsFullScreen(bool toggle)
{
- // Making a fullscreen window on linux and windows is harder than you could possibly imagine...
+
+// Making a fullscreen window on linux and windows is harder than you could possibly imagine...
if (toggle)
{
#ifdef __LINUX__
@@ -1076,6 +1047,8 @@
"Ulrich Heske
"
"James Hagerman
"
"quil0m80
"
+"Michael Pujos
"
+"Mark Glines
"
"
"
"And special thanks to:
"
""
diff -Nru mixxx-1.6.0/src/mixxx.h mixxx-1.6.1/src/mixxx.h
--- mixxx-1.6.0/src/mixxx.h 2008-07-13 22:21:19.000000000 -0500
+++ mixxx-1.6.1/src/mixxx.h 2008-08-14 00:23:43.000000000 -0500
@@ -159,7 +159,6 @@
EngineChannel *channel1, *channel2;
EngineMaster *master;
- //PlayerProxy *player;
SoundManager *soundmanager;
MidiObject *midi;
ControlObject *control;
@@ -212,6 +211,8 @@
QAction *iPodToggle;
+ QAction *batchBpmDetect;
+
QAction *libraryRescan;
QAction *optionsBeatMark;
diff -Nru mixxx-1.6.0/src/mixxx.vcproj mixxx-1.6.1/src/mixxx.vcproj
--- mixxx-1.6.0/src/mixxx.vcproj 2007-06-27 16:37:06.000000000 -0500
+++ mixxx-1.6.1/src/mixxx.vcproj 2008-08-11 05:02:03.000000000 -0500
@@ -530,18 +530,6 @@
>
-
-
-
-
-
-
@@ -1835,18 +1823,6 @@
>
-
-
-
-
-
-
diff -Nru mixxx-1.6.0/src/mixxxview.cpp mixxx-1.6.1/src/mixxxview.cpp
--- mixxx-1.6.0/src/mixxxview.cpp 2008-07-29 10:16:10.000000000 -0500
+++ mixxx-1.6.1/src/mixxxview.cpp 2008-09-16 21:12:45.000000000 -0500
@@ -99,7 +99,6 @@
m_pNumberPosCh2 = 0;
m_pSliderRateCh1 = 0;
m_pSliderRateCh2 = 0;
- m_bZoom = false;
m_bVisualWaveform = false;
m_pOverviewCh1 = 0;
m_pOverviewCh2 = 0;
@@ -590,8 +589,6 @@
((QWidget*)m_pVisualCh2)->repaint();
}
- if (!WWidget::selectNode(node, "Zoom").isNull() && WWidget::selectNodeQString(node, "Zoom")=="true")
- m_bZoom = true;
}
diff -Nru mixxx-1.6.0/src/mixxxview.h mixxx-1.6.1/src/mixxxview.h
--- mixxx-1.6.0/src/mixxxview.h 2008-07-13 22:21:19.000000000 -0500
+++ mixxx-1.6.1/src/mixxxview.h 2008-09-16 21:12:45.000000000 -0500
@@ -74,8 +74,6 @@
WNumberPos *m_pNumberPosCh1, *m_pNumberPosCh2;
/** Pointer to rate slider widgets */
WSliderComposed *m_pSliderRateCh1, *m_pSliderRateCh2;
- /** Allow dynamic zoom on visuals */
- bool m_bZoom;
/** Pointer to ComboBox*/
QComboBox *m_pComboBox;
//WComboBox *m_pComboBox;
diff -Nru mixxx-1.6.0/src/old/playeralsa.cpp mixxx-1.6.1/src/old/playeralsa.cpp
--- mixxx-1.6.0/src/old/playeralsa.cpp 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/playeralsa.cpp 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,757 @@
+/***************************************************************************
+ playeralsa.cpp - description
+ -------------------
+ begin : Wed Feb 20 2002
+ copyright : (C) 2002 by Tue and Ken Haste Andersen
+ email :
+***************************************************************************/
+
+/***************************************************************************
+* *
+* 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. *
+* *
+***************************************************************************/
+
+#include "playeralsa.h"
+#include "controlobject.h"
+
+#ifndef PLAYERTEST
+#include "rtthread.h"
+#endif
+
+// Tutorials /home/peter/pad-alsa-audio.html /home/peter/alsa090_howto.html
+// Docs /usr/share/doc/alsa-lib-1.0.4/doxygen/html/index.html
+// Example /usr/share/doc/alsa-lib-1.0.4/doxygen/html/_2test_2pcm_8c-example.html
+// QT /usr/share/doc/qt-devel-3.1.1/html/index.html
+
+/** Maximum frame size used with ALSA. Used to determine no of buffers
+ * * when setting latency */
+const int kiMaxFrameSize = 512;
+
+
+#ifndef PLAYERTEST
+PlayerALSA::PlayerALSA(ConfigObject * config) : Player(config)
+#else
+PlayerALSA::PlayerALSA()
+#endif
+{
+ int err;
+
+ handle = 0;
+ err = snd_pcm_hw_params_malloc(&hwparams);
+ if (err < 0)
+ qCritical("Couldn't allocate memory for hw params: %s\n", snd_strerror(err));
+
+ err = snd_pcm_sw_params_malloc(&swparams);
+ if (err < 0)
+ qCritical("Couldn't allocate memory for sw params: %s\n", snd_strerror(err));
+
+ err = snd_pcm_sw_params_malloc(&swparams);
+ if (err < 0)
+ qCritical("Couldn't allocate memory for sw params: %s\n", snd_strerror(err));
+
+ isopen = false;
+ masterleft = masterright = -1;
+ headleft = headright = -1;
+ twrite = false;
+ m_iChannels = alsa_channels;
+ qDebug() << "Alsa constructed";
+}
+
+PlayerALSA::~PlayerALSA()
+{
+ if (isopen) close();
+
+ qDebug() << "Alsa destroying...";
+ if (hwparams)
+ {
+ snd_pcm_hw_params_free(hwparams);
+ }
+ if (swparams)
+ {
+ snd_pcm_sw_params_free(swparams);
+ }
+ qDebug() << "Alsa destroyed";
+}
+
+bool PlayerALSA::initialize()
+{
+ qDebug() << "Alsa initialized";
+
+ return true;
+}
+
+bool PlayerALSA::open()
+{
+#ifndef PLAYERTEST
+ Player::open();
+#endif
+ QString name;
+ QString devname, devtmp;
+ int err;
+
+#ifndef PLAYERTEST
+ QRegExp rx("(\\S+) \\(ch (\\d+)\\)");
+
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]", "DeviceMasterLeft"));
+ if (name != "None")
+ {
+ if (rx.search(name) < 0)
+ qWarning() << "can't find device name or channel number in" << name;
+
+ devname = rx.cap(1);
+ }
+ else
+ {
+ setDefaults(); // initialise defaults
+ return open();
+ }
+#else
+ devname = QString("surround40:0");
+#endif
+
+ // If no device was selected return false
+ if (!devname)
+ return false;
+
+ qDebug() << "Alsa opening pcm_open:" << devname;
+
+ if ((err = snd_pcm_open(&handle, devname.ascii(),
+ SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
+ // AD: Try for default device instead
+ if ((err = snd_pcm_open(&handle, "default",
+ SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
+ qWarning("Playback open error: %s\n", snd_strerror(err));
+ return false;
+ } else {
+ qWarning("Using default ALSA device, you may want to set up a ~/.asoundrc to enable all the features of your sound card");
+ }
+ }
+
+ qDebug() << "Alsa setting hw";
+ if ((err = set_hwparams()) < 0)
+ {
+ qWarning("Setting of hwparams failed: %s\n", snd_strerror(err));
+ snd_pcm_close(handle);
+ return false;
+ }
+
+ qDebug() << "Alsa setting sw";
+ if ((err = set_swparams()) < 0)
+ {
+ qWarning("Setting of swparams failed: %s\n", snd_strerror(err));
+ snd_pcm_close(handle);
+ return false;
+ }
+
+ masterleft = masterright = -1;
+ headleft = headright = -1;
+
+#ifndef PLAYERTEST
+ int temp;
+
+ // master left
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]", "DeviceMasterLeft"));
+ qDebug() << "Alsa opening..." << name;
+ if (name != "None")
+ {
+ if (rx.search(name) < 0)
+ {
+ qWarning() << "can't find device name or channel number in" << name;
+ }
+// devname = rx.cap(1);
+ temp = rx.cap(2).toInt();
+ if (temp > 0 && temp <= m_iChannels)
+ {
+ masterleft = temp - 1;
+ }
+ }
+ qDebug() << "Alsa opening...ML " << masterleft;
+
+ // master right
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]", "DeviceMasterRight"));
+ if (name != "None")
+ {
+ if (rx.search(name) < 0)
+ {
+ qWarning() << "can't find device name or channel number in" << name;
+ }
+ devtmp = rx.cap(1);
+ if (devname != devtmp)
+ {
+ qWarning("device name mismatch, only one device supported");
+ }
+ temp = rx.cap(2).toInt();
+ if (temp > 0 && temp <= m_iChannels)
+ {
+ masterright = temp - 1;
+ }
+ }
+ qDebug() << "Alsa opening...MR " << masterright;
+
+ // head left
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]", "DeviceHeadLeft"));
+ if (name != "None")
+ {
+ if (rx.search(name) < 0)
+ {
+ qWarning() << "can't find device name or channel number in" << name;
+ }
+ devtmp = rx.cap(1);
+ if (devname != devtmp)
+ {
+ qWarning("device name mismatch, only one device supported");
+ }
+ temp = rx.cap(2).toInt();
+ if (temp > 0 && temp <= m_iChannels)
+ {
+ headleft = temp - 1;
+ }
+ }
+ qDebug() << "Alsa opening...HL " << headleft;
+
+ // head right
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]", "DeviceHeadRight"));
+ if (name != "None")
+ {
+ if (rx.search(name) < 0)
+ {
+ qWarning() << "can't find device name or channel number in" << name;
+ }
+ devtmp = rx.cap(1);
+ if (devname != devtmp)
+ {
+ qWarning("device name mismatch, only one device supported");
+ }
+ temp = rx.cap(2).toInt();
+ if (temp > 0 && temp <= m_iChannels)
+ {
+ headright = temp - 1;
+ }
+ }
+
+ qDebug() << "Alsa opening...HR " << headright;
+ // Check if any of the devices in the config database needs to be set to "None"
+ if (masterleft < 0)
+ m_pConfig->set(ConfigKey("[Soundcard]", "DeviceMasterLeft"), ConfigValue("None"));
+ if (masterright < 0)
+ m_pConfig->set(ConfigKey("[Soundcard]", "DeviceMasterRight"), ConfigValue("None"));
+ if (headleft < 0)
+ m_pConfig->set(ConfigKey("[Soundcard]", "DeviceHeadLeft"), ConfigValue("None"));
+ if (headright < 0)
+ m_pConfig->set(ConfigKey("[Soundcard]", "DeviceHeadRight"), ConfigValue("None"));
+
+#else
+ masterleft = 0;
+ masterright = 1;
+ headleft = 2;
+ headright = 3;
+#endif
+
+ twrite = true;
+ isopen = true;
+
+ QThread::start();
+
+ return true;
+}
+
+/*
+ * Underrun and suspend recovery
+ */
+int PlayerALSA::xrun_recovery(int err)
+{
+ if (err == -EPIPE) { /* under-run */
+ err = snd_pcm_prepare(handle);
+ if (err < 0)
+ qWarning("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err));
+ return 0;
+ }
+ else if (err == -ESTRPIPE)
+ {
+ while ((err = snd_pcm_resume(handle)) == -EAGAIN)
+ sleep(1);/* wait until the suspend flag is released */
+ if (err < 0)
+ {
+ err = snd_pcm_prepare(handle);
+ if (err < 0)
+ qWarning("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err));
+ }
+ return 0;
+ }
+ return err;
+}
+
+/**
+ * thread for writing samples out
+ */
+void PlayerALSA::run()
+{
+ CSAMPLE * sptr;
+ int err, ctr;
+
+#ifndef PLAYERTEST
+ rtThread();
+#endif
+
+ if (isformatfloat) {
+ float * optr, * output;
+
+ output = new float[buffer_size * m_iChannels];
+ qDebug() << "Alsa allocating output buffer (FLOAT) " << output;
+
+ while (twrite)
+ {
+ sptr = prepareBuffer((int) period_size);
+ optr = output;
+ for (int i = 0; i < (int) period_size; i++)
+ {
+ for (int j = 0; j < m_iChannels; j++) optr[j] = 0;
+ if (masterleft >= 0) optr[masterleft] = *sptr / 32768.;
+ sptr++;
+ if (masterright >= 0) optr[masterright] = *sptr / 32768.;
+ sptr++;
+ if (headleft >= 0) optr[headleft] = *sptr / 32768.;
+ sptr++;
+ if (headright >= 0) optr[headright] = *sptr / 32768.;
+ sptr++;
+ optr += m_iChannels;
+ }
+ ctr = period_size;
+ optr = output;
+ while (ctr > 0)
+ {
+ err = snd_pcm_writei(handle, optr, ctr);
+ if (err == -EAGAIN) continue;
+ if (err < 0)
+ {
+ if (xrun_recovery(err) < 0)
+ qCritical("Write error: %s\n", snd_strerror(err));
+
+ break;
+ }
+ optr += err*m_iChannels;
+ ctr -= err;
+ }
+ }
+ if (output)
+ delete output;
+ }
+ else
+ {
+ short int * optr, * output;
+
+ output = new short int[buffer_size * m_iChannels];
+ qDebug() << "Alsa allocating output buffer (S16) " << output;
+
+ while (twrite)
+ {
+ sptr = prepareBuffer((int) period_size);
+ optr = output;
+ for (int i = 0; i < (int) period_size; i++)
+ {
+ for (int j = 0; j < m_iChannels; j++) optr[j] = 0;
+ if (masterleft >= 0) optr[masterleft] = (short int) *sptr;
+ sptr++;
+ if (masterright >= 0) optr[masterright] = (short int) *sptr;
+ sptr++;
+ if (headleft >= 0) optr[headleft] = (short int) *sptr;
+ sptr++;
+ if (headright >= 0) optr[headright] = (short int) *sptr;
+ sptr++;
+ optr += m_iChannels;
+ }
+ ctr = period_size;
+ optr = output;
+ while (ctr > 0)
+ {
+ err = snd_pcm_writei(handle, optr, ctr);
+ if (err == -EAGAIN) continue;
+ if (err < 0)
+ {
+ if (xrun_recovery(err) < 0)
+ qCritical("Write error: %s\n", snd_strerror(err));
+ break;
+ }
+ optr += err*m_iChannels;
+ ctr -= err;
+ }
+ }
+ if (output) delete output;
+ }
+ qDebug() << "Alsa leaving thread";
+}
+
+#ifdef PLAYERTEST
+/**
+ * generate a middle A slowly shifting across the channels
+ */
+CSAMPLE * PlayerALSA::prepareBuffer(int count)
+{
+ const double freq = 440.;
+ const unsigned int rate = 44100;
+ static CSAMPLE * out = 0;
+
+ static double phase = 0;
+ double max_phase = 1.0 / freq;
+ double step = 1.0 / (double) rate;
+ double res;
+ CSAMPLE * sptr;
+ int chn;
+ static int channel = 0;
+ static int ccount = 0;
+
+ if (out == 0)
+ out = new CSAMPLE[80000];
+ sptr = out;
+ while (count-- > 0)
+ {
+ res = 32768. * sin((phase * 2 * M_PI) / max_phase - M_PI);
+ for (chn = 0; chn < alsa_channels; chn++)
+ {
+ if (chn == channel)
+ *sptr = res;
+ else
+ *sptr = 0;
+ sptr++;
+ }
+ phase += step;
+ if (phase >= max_phase)
+ {
+ phase -= max_phase;
+ ccount++;
+ if (ccount == (3 * 440))
+ {
+ ccount = 0;
+ channel++;
+ if (channel == alsa_channels) channel = 0;
+ }
+ }
+ }
+ return out;
+}
+#endif
+
+void PlayerALSA::close()
+{
+ if (!isopen)
+ return;
+
+ qDebug() << "Alsa closing";
+ twrite = false;
+ qDebug() << "Alsa waiting for thread for close";
+ QThread::wait();
+
+ snd_pcm_drop(handle);
+ snd_pcm_close(handle);
+
+ isopen = false;
+}
+
+void PlayerALSA::setDefaults()
+{
+ qDebug() << "Alsa setdefs";
+#ifndef PLAYERTEST
+ // Get list of interfaces
+ QStringList interfaces = getInterfaces();
+
+ // Set first interfaces to master left
+ QStringList::iterator it = interfaces.begin();
+ if (*it)
+ m_pConfig->set(ConfigKey("[Soundcard]", "DeviceMasterLeft"), ConfigValue((*it)));
+ else
+ m_pConfig->set(ConfigKey("[Soundcard]", "DeviceMasterLeft"), ConfigValue("None"));
+
+ // Set second interface to master right
+ ++it;
+ if (*it)
+ m_pConfig->set(ConfigKey("[Soundcard]", "DeviceMasterRight"), ConfigValue((*it)));
+ else
+ m_pConfig->set(ConfigKey("[Soundcard]", "DeviceMasterRight"), ConfigValue("None"));
+
+ // Set head left and right to none
+ m_pConfig->set(ConfigKey("[Soundcard]", "DeviceHeadLeft"), ConfigValue("None"));
+ m_pConfig->set(ConfigKey("[Soundcard]", "DeviceHeadRight"), ConfigValue("None"));
+
+ // Set default sample rate
+ QStringList srates = getSampleRates();
+ it = srates.begin();
+ while (*it)
+ {
+ m_pConfig->set(ConfigKey("[Soundcard]", "Samplerate"), ConfigValue((*it)));
+ if ((*it).toInt() >= 44100)
+ break;
+ ++it;
+ }
+
+ // Set currently used latency in config database
+ m_pConfig->set(ConfigKey("[Soundcard]", "Latency"), ConfigValue(default_latency));
+#endif
+}
+
+QStringList PlayerALSA::getInterfaces()
+{
+ qDebug() << "Alsa getinter";
+ QStringList result;
+
+ result.append("mixxx (ch 1)");
+ result.append("mixxx (ch 2)");
+ result.append("mixxx (ch 3)");
+ result.append("mixxx (ch 4)");
+
+ return result;
+}
+
+QStringList PlayerALSA::getSampleRates()
+{
+ qDebug() << "Alsa getsample";
+ QStringList result;
+ result.append("11025");
+ result.append("22050");
+ result.append("44100");
+ result.append("48000");
+ return result;
+}
+
+QString PlayerALSA::getSoundApi()
+{
+ qDebug() << "Alsa getapi";
+ return QString("Alsa");
+}
+
+int PlayerALSA::set_hwparams()
+{
+ unsigned int rate, rrate;
+ unsigned int buffer_time = 500000; /* ring buffer length in us */
+ unsigned int period_time = 100000; /* period time in us */
+
+ int err, dir;
+
+ /* choose all parameters */
+ err = snd_pcm_hw_params_any(handle, hwparams);
+ if (err < 0)
+ {
+ qWarning("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* set the interleaved read/write format */
+ err = snd_pcm_hw_params_set_access(handle, hwparams, alsa_access);
+ if (err < 0)
+ {
+ qWarning("Access type not available for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* set the sample format */
+ err = snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_FLOAT);
+ if (err < 0)
+ {
+ qWarning("Sample format (FLOAT) not available for playback: %s\n", snd_strerror(err));
+ qWarning("Falling back to S16");
+ err = snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_S16);
+ if (err < 0)
+ {
+ qWarning("Sample format (S16) not available for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ isformatfloat = false;
+ } else {
+ isformatfloat = true;
+ }
+
+ /* find min and max number of channels */
+ err = snd_pcm_hw_params_get_channels_min(hwparams, &rate);
+ if (err < 0)
+ {
+ qWarning("Channels count (%i) not available for playbacks: %s\n", rate, snd_strerror(err));
+ }
+ qDebug() << "Channels min " << rate;
+ err = snd_pcm_hw_params_get_channels_max(hwparams, &rate);
+ if (err < 0)
+ {
+ qWarning("Channels count (%i) not available for playbacks: %s\n", rate, snd_strerror(err));
+ }
+ qDebug() << "Channels max " << rate;
+ m_iChannels = math_min(rate, alsa_channels);
+ qDebug() << "Set channels = " << m_iChannels;
+
+ /* set the count of channels */
+ err = snd_pcm_hw_params_set_channels(handle, hwparams, m_iChannels);
+ if (err < 0)
+ {
+ qWarning("Channels count (%i) not available for playbacks: %s\n", m_iChannels, snd_strerror(err));
+ return err;
+ }
+ /* set the stream rate */
+#ifndef PLAYERTEST
+ rate = m_pConfig->getValueString(ConfigKey("[Soundcard]", "Samplerate")).toUInt();
+#else
+ rate = 44100;
+#endif
+ rrate = rate;
+ err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rrate, 0);
+ if (err < 0)
+ {
+ qWarning("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
+ return err;
+ }
+ if (rrate != rate)
+ {
+ qWarning("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
+ return -EINVAL;
+ }
+
+#ifndef PLAYERTEST
+// setPlaySrate(rrate);
+// m_pControlObjectSampleRate->queueFromThread((double)rrate);
+
+ // Update SRATE and Latency ControlObjects
+ m_pControlObjectSampleRate->queueFromThread((double)rrate);
+// m_pControlObjectLatency->queueFromThread((double)iLatencyMSec);
+//
+#endif
+
+ /* set the buffer time */
+#ifndef PLAYERTEST
+ buffer_time = m_pConfig->getValueString(ConfigKey("[Soundcard]", "Latency")).toUInt() * 1000;
+#else
+ buffer_time = 50000;
+#endif
+ /* figure out size and make it even */
+ buffer_size = (int) rrate*(1e-6*buffer_time) + 1;
+
+ snd_pcm_uframes_t max = 0;
+ snd_pcm_uframes_t min = 0;
+
+ // FIXME: Should check return values to be on the safe side
+ snd_pcm_hw_params_get_buffer_size_max(hwparams, &max);
+ snd_pcm_hw_params_get_buffer_size_min(hwparams, &min);
+ qDebug() << "Allowed buffer size range: " << min << "i -> " << max << "i";
+
+ // Make sure buffer size we're aiming for is really allowed
+ if (buffer_size < min) { buffer_size = (int)min; }
+ if (buffer_size > max) { buffer_size = (int)max; }
+
+ buffer_size -= (buffer_size & 1);
+
+ if (buffer_size < min) { buffer_size += 2; }
+
+ /* test buffer size first */
+ err = snd_pcm_hw_params_test_buffer_size(handle, hwparams, buffer_size);
+ if (err < 0) {
+ qWarning("Unable to test buffer size %d", buffer_size);
+ return err;
+ }
+ err = snd_pcm_hw_params_set_buffer_size(handle, hwparams, buffer_size);
+ if (err < 0)
+ {
+ qWarning("Unable to set buffer size for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ qWarning("Buffer %dus [actual %dus] (size: %d)", (int) buffer_time, (int) (1e6*buffer_size/rrate), buffer_size);
+
+ /*
+ * work out maximum number of periods so that only kiMaxFrameSize is
+ * written out at a time, then use this as a starting point to find
+ * period that works
+ */
+ int period_no_start = 2;
+
+ if (buffer_size/kiMaxFrameSize>2)
+ period_no_start = buffer_size/kiMaxFrameSize;
+
+ for (period_no = period_no_start; period_no > 1; period_no--)
+ {
+ unsigned int period_time = buffer_time / period_no;
+ qWarning("Period %dus (no: %d)", (int) period_time, period_no);
+
+ int dir = 0;
+ err = snd_pcm_hw_params_test_periods(handle, hwparams, period_no, dir);
+ if (err < 0)
+ {
+ qWarning("Unable to test periods %i (dir %d) for playback: %s\n", period_no, dir,
+ snd_strerror(err));
+ }
+ else
+ {
+ err = snd_pcm_hw_params_set_periods(handle, hwparams, period_no, dir);
+ if (err < 0)
+ {
+ qWarning("Unable to set periods %i for playback: %s\n", period_no, snd_strerror(err));
+ return err;
+ }
+ err = snd_pcm_hw_params_get_period_size(hwparams, &period_size, &dir);
+ if (err < 0)
+ {
+ qWarning("Unable to get period size for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ qWarning("Period %df, buffer %df", (int) period_size, (int) buffer_size);
+ break;
+ }
+ }
+
+ if (period_no == 1)
+ return -1;
+
+ /* write the parameters to device */
+ err = snd_pcm_hw_params(handle, hwparams);
+ if (err < 0)
+ {
+ qWarning("Unable to set hw params for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ qWarning("Rate: %d, buf %df (%dus), per %df (%dus)", rrate,
+ (int) buffer_size, (int) (buffer_size / (rrate * 1e-6)),
+ (int) period_size, (int) (period_size / (rrate * 1e-6)));
+
+ // Update SRATE and Latency ControlObjects
+ m_pControlObjectSampleRate->queueFromThread((double)rrate);
+ m_pControlObjectLatency->queueFromThread((double)buffer_time/1000.);
+
+ return 0;
+}
+
+int PlayerALSA::set_swparams()
+{
+ int err;
+
+ /* get the current swparams */
+ err = snd_pcm_sw_params_current(handle, swparams);
+ if (err < 0)
+ {
+ qWarning("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* start the transfer when the buffer is full */
+ err = snd_pcm_sw_params_set_start_threshold(handle, swparams, (buffer_size/period_size)*period_size);
+ if (err < 0)
+ {
+ qWarning("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* allow the transfer when at least period_size samples can be processed */
+ err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_size);
+ if (err < 0)
+ {
+ qWarning("Unable to set avail min for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* align all transfers to 1 sample */
+ err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1);
+ if (err < 0)
+ {
+ qWarning("Unable to set transfer align for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* write the parameters to the playback device */
+ err = snd_pcm_sw_params(handle, swparams);
+ if (err < 0)
+ {
+ qWarning("Unable to set sw params for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ return 0;
+}
diff -Nru mixxx-1.6.0/src/old/playeralsa.h mixxx-1.6.1/src/old/playeralsa.h
--- mixxx-1.6.0/src/old/playeralsa.h 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/playeralsa.h 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,107 @@
+/***************************************************************************
+ playeralsa.h - description
+ -------------------
+ begin : Wed Feb 20 2002
+ copyright : (C) 2002 by Tue and Ken Haste Andersen
+ email :
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PLAYERALSA_H
+#define PLAYERALSA_H
+
+/**
+ *@author Tue and Ken Haste Andersen, Peter Chang
+ */
+
+#ifndef PLAYERTEST
+#include "player.h"
+#else
+// some definitions to avoid using player.h in test mode
+
+#include
+
+#include
+#include
+
+typedef float CSAMPLE; // defines the CSAMPLE type used for intermediate calculations
+#endif
+
+#include
+#include
+#include
+
+/**
+ * there are two independent defines S16_OUTPUT and DIRECT_OUTPUT
+ * 1) S16_OUTPUT makes the class output short integers to ALSA
+ * 2) DIRECT_OUTPUT uses mmapped output
+ *
+ * NB by default, these are not defined and so the class uses floats via the
+ * plug plugin. Defining S16_OUTPUT allows the bare hw to be used (via surround40).
+ * XXX: Mmapped output doesn't seem to work with the plug plugin...
+ */
+
+#ifndef PLAYERTEST
+class PlayerALSA : public Player, public QThread
+{
+public:
+ PlayerALSA(ConfigObject *config);
+#else
+class PlayerALSA : public QThread {
+public:
+ PlayerALSA();
+#endif
+ ~PlayerALSA();
+ bool initialize();
+ bool open();
+ void close();
+ void setDefaults();
+ QStringList getInterfaces();
+ QStringList getSampleRates();
+ static QString getSoundApi();
+ QString getSoundApiName() { return getSoundApi(); };
+ /** Satisfy virtual declaration in EngineObject */
+ void process(const CSAMPLE *, const CSAMPLE *, const int) {};
+
+ /** Main loop of player. Executed in a separate thread by QT */
+ void run();
+
+protected:
+/** ALSA parameters */
+ snd_pcm_t *handle;
+ snd_pcm_hw_params_t *hwparams;
+ snd_pcm_sw_params_t *swparams;
+
+ snd_pcm_uframes_t buffer_size;
+ snd_pcm_uframes_t period_size;
+ unsigned int period_no;
+ bool isformatfloat;
+
+ /** True if devices are open */
+ bool isopen;
+ int masterleft, masterright, headleft, headright;
+
+#ifdef PLAYERTEST
+ CSAMPLE *prepareBuffer(int nframes);
+#endif
+ int setPeriodSize(bool setMinimum);
+ int set_hwparams();
+ int set_swparams();
+ int xrun_recovery(int err);
+
+ bool twrite; // flag for thread
+
+private:
+ static const snd_pcm_access_t alsa_access = SND_PCM_ACCESS_RW_INTERLEAVED;
+ static const int alsa_channels = 4;
+ static const int default_latency = 200;
+};
+#endif
diff -Nru mixxx-1.6.0/src/old/playerasio.cpp mixxx-1.6.1/src/old/playerasio.cpp
--- mixxx-1.6.0/src/old/playerasio.cpp 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/playerasio.cpp 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,670 @@
+/***************************************************************************
+ PlayerAsio.cpp - description
+ -------------------
+ begin : Thu June 02 2005
+ copyright : (C) 2005 by Ingo Kossyk
+ email :
+***************************************************************************/
+
+/***************************************************************************
+* *
+* 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. *
+* *
+***************************************************************************/
+
+
+// PlayerAsio.cpp: implementation of the PlayerAsio class.
+//
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+// ToDo:
+// - Implement all conversion routines for the different drivers
+// - Testing on different soundcards
+// - Correctly (???) setting the latency in the preferences and locking it
+// - Samplerate Changed needs to be implemented if changed in the Preferences
+//////////////////////////////////////////////////////////////////////
+
+#include "qstringlist.h"
+#include "PlayerAsio.h"
+#include "playerproxy.h"
+#include "controlobject.h"
+//////////////////////////////////////////////////////////////////////
+// External Declarations
+//////////////////////////////////////////////////////////////////////
+
+__declspec(dllimport) AsioDrivers* asioDrivers;
+ASIOCallbacks asioCallbacks;
+DriverInfo asioDriverInfo;
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+const int MAX_DRIVER_NAME_LENGTH = 32;
+
+PlayerAsio::PlayerAsio(ConfigObject * config) : Player(config)
+
+{
+ m_pTempBuffer = 0;
+ m_reenter = 0;
+ bufferLength = 0;
+ driverIsLoaded = false;
+
+ for (int i = 0 ; i < 32 ; ++i) {
+ driverList[i] =static_cast(malloc(32));
+
+ /* check memory */
+ if(!driverList[i]) qDebug() << "ERROR: Could not allocate Memory!";
+ }
+
+
+ loadAsioDriver("dummy");
+
+ drvNum = asioDrivers->getDriverNames(driverList,32);
+
+}
+
+PlayerAsio::~PlayerAsio()
+{
+
+ ASIOStop();
+ ASIOExit();
+
+}
+//////////////////////////////////////////////////////////////////////
+// Class functions
+//////////////////////////////////////////////////////////////////////
+
+/*******
+ *
+ * Conversion of different Ouputtypes
+ *
+ ********/
+const double fScaler24 = (double)0xffff;
+
+void PlayerAsio::float32toInt24inPlace(float * buffer, long frames, bool swap)
+{
+ double sc = fScaler24 + .5;
+ long a;
+ char * b = (char *)(buffer);
+ char * aa = (char *)(&a);
+
+ while(--frames >= 0)
+ {
+ a = static_cast(static_cast(*buffer++) *sc);
+
+
+ if (swap)
+ {
+ *b++ = aa[3];
+ *b++ = aa[2];
+ *b++ = aa[1];
+ }
+ else
+ {
+ *b++ = aa[1];
+ *b++ = aa[2];
+ *b++ = aa[3];
+ }
+ }
+}
+
+
+void PlayerAsio::Output_Float32_Int24(int channelNumber, float * inputBuffer, float * outputBuffer, bool swap)
+{
+ for(int i=0; i < bufferLength; i++)
+ {
+ m_pTempBuffer[i] = inputBuffer[i*sizeof(float) + channelNumber];
+ }
+
+ float32toInt24inPlace(m_pTempBuffer,bufferLength,swap);
+ memcpy(outputBuffer,m_pTempBuffer,bufferLength*3);
+
+}
+
+void PlayerAsio::Output_Float32_Int32(int channelNumber, float * inputBuffer, float * outputBuffer, bool swap)
+{
+ for(int i=0; i < bufferLength; i++)
+ {
+ m_pTempBuffer[i] = inputBuffer[i*sizeof(float) + channelNumber];
+ }
+
+ float32toInt32inPlace(static_cast(m_pTempBuffer),bufferLength,swap);
+ memcpy(outputBuffer,m_pTempBuffer,bufferLength*4);
+
+}
+
+const double fScaler32 = (double)0xffff;
+
+void PlayerAsio::float32toInt32inPlace(float * buffer, long frames,bool swap)
+{
+ double sc = fScaler32 + .49999;
+ long a;
+ char * b = (char *)(buffer);
+ char * aa = (char *)(&a);
+
+ while(--frames >= 0)
+ {
+ a = static_cast(static_cast(*buffer++) * sc);
+
+
+ if(swap){
+ *b++ = aa[3];
+ *b++ = aa[2];
+ *b++ = aa[1];
+ *b++ = aa[0];
+ }
+ else
+ {
+ *b++ = aa[0];
+ *b++ = aa[1];
+ *b++ = aa[2];
+ *b++ = aa[3];
+ }
+ }
+}
+
+void PlayerAsio::Output_Float32_Int16(int channelNumber, float * inputBuffer, short * outputBuffer, bool swap)
+{
+ short temp;
+ for (int i=0; i < bufferLength; i++)
+ {
+ temp = static_cast(inputBuffer[i*sizeof(float) + channelNumber]);
+ outputBuffer[i] = static_cast(temp);
+ if (swap) SwapBuffer(&outputBuffer[i]);
+ }
+}
+
+void PlayerAsio::SwapBuffer(short * buffer)
+{
+ short a;
+
+ char * b = (char *)(buffer);
+ char * aa = (char *)(&a);
+
+ a = *buffer;
+
+ *b++ = aa[1];
+ *b++ = aa[0];
+
+}
+/*******
+ *
+ * Init
+ *
+ ********/
+
+bool PlayerAsio::initialize() {
+ return true;
+}
+
+bool PlayerAsio::initDriver()
+{
+
+
+ if (ASIOInit (&asioDriverInfo.driverInfo) == ASE_OK ){
+
+
+ return true;
+ }
+ return false;
+
+
+}
+
+
+int PlayerAsio::getBufferSize(void)
+{
+ return asioDriverInfo.preferredSize;
+}
+
+
+int PlayerAsio::getChannelCount(void)
+{
+ return asioDriverInfo.outputChannels;
+}
+
+
+int PlayerAsio::getSampleRate(void)
+{
+ return asioDriverInfo.sampleRate;
+}
+
+
+QStringList PlayerAsio::getSampleRates() {
+ QStringList result;
+ result.append("44100");
+ return result;
+}
+
+
+QStringList PlayerAsio::getInterfaces() {
+ QStringList result;
+ LPASIODRVSTRUCT lpdrv = asioDrivers->lpdrvlist;
+ while(lpdrv) {
+ result.append(lpdrv->drvname);
+ lpdrv = lpdrv->next;
+ }
+ return result;
+}
+
+long PlayerAsio::init_asio_static_data (DriverInfo * asioDriverInfo)
+{
+
+ if(ASIOGetChannels(&asioDriverInfo->inputChannels, &asioDriverInfo->outputChannels) == ASE_OK)
+ {
+
+
+ // get the usable buffer sizes
+ if(ASIOGetBufferSize(&asioDriverInfo->minSize, &asioDriverInfo->maxSize, &asioDriverInfo->preferredSize, &asioDriverInfo->granularity) == ASE_OK)
+ {
+
+ // get the currently selected sample rate
+ if(ASIOGetSampleRate(&asioDriverInfo->sampleRate) == ASE_OK)
+ {
+ //Get SampleRate From Preferences
+ int sampleRate = m_pConfig->getValueString(ConfigKey("[Soundcard]", "Samplerate")).toInt();
+ //Calculate Latency
+ int iLatencyMSec = (1000*asioDriverInfo->preferredSize*4)/(sampleRate);
+
+ if (asioDriverInfo->sampleRate <= 0.0 || asioDriverInfo->sampleRate > 96000.0)
+ {
+
+ if(ASIOSetSampleRate(sampleRate) == ASE_OK)
+ {
+ if(ASIOGetSampleRate(&asioDriverInfo->sampleRate) == ASE_OK)
+ qDebug() << "Asio State : SAMPLERATE CHANGED";
+ else
+ return -6;
+ }
+ else
+ return -5;
+ } else if(asioDriverInfo->sampleRate != m_pConfig->getValueString(ConfigKey("[Soundcard]","Samplerate")).toInt())
+ {
+
+ if(ASIOSetSampleRate(sampleRate) == ASE_OK)
+ {
+ if(ASIOGetSampleRate(&asioDriverInfo->sampleRate) == ASE_OK)
+ qDebug() << "Asio State : SAMPLERATE CHANGED";
+ else
+ return -6;
+ }
+ else
+ return -5;
+ }
+
+
+ // Driver does not store it's internal sample rate, so set it to a know one.
+ // Usually you should check beforehand, that the selected sample rate is valid
+ // with ASIOCanSampleRate().
+ // Update SRATE and Latency ControlObjects
+ m_pControlObjectSampleRate->queueFromThread(static_cast(sampleRate));
+ m_pControlObjectLatency->queueFromThread(static_cast(iLatencyMSec));
+ m_pConfig->set(ConfigKey("[Soundcard]","Latency"), iLatencyMSec);
+ qDebug() << "Asio State: SAMPLERATE SET";
+
+ // check wether the driver requires the ASIOOutputReady() optimization
+ // (can be used by the driver to reduce output latency by one block)
+ if(ASIOOutputReady() == ASE_OK)
+ asioDriverInfo->postOutput = true;
+ else
+ asioDriverInfo->postOutput = false;
+
+
+ return 0;
+ }
+ return -3;
+ }
+ return -2;
+ }
+ return -1;
+}
+
+ASIOError PlayerAsio::create_asio_buffers (DriverInfo * asioDriverInfo)
+{
+
+ long i=0;
+ ASIOError result;
+
+ bufferLength = asioDriverInfo->preferredSize;
+ m_pTempBuffer = static_cast(malloc(bufferLength*4));
+
+ // fill the bufferInfos from the start without a gap
+ ASIOBufferInfo * info = asioDriverInfo->bufferInfos;
+
+ asioDriverInfo->inputBuffers = 0;
+
+ // prepare inputs (Though this is not necessaily required, no opened inputs will work, too
+ if (asioDriverInfo->inputChannels > kMaxInputChannels)
+ asioDriverInfo->inputBuffers = kMaxInputChannels;
+ else
+ asioDriverInfo->inputBuffers = asioDriverInfo->inputChannels;
+
+ for(i = 0; i < asioDriverInfo->inputBuffers; i++, info++)
+ {
+ info->isInput = ASIOTrue;
+ info->channelNum = i;
+ info->buffers[0] = info->buffers[1] = 0;
+ }
+ // prepare outputs
+ if (asioDriverInfo->outputChannels > kMaxOutputChannels)
+ asioDriverInfo->outputBuffers = kMaxOutputChannels;
+ else
+ asioDriverInfo->outputBuffers = asioDriverInfo->outputChannels;
+
+ qDebug(QString::number(asioDriverInfo->outputChannels));
+
+ // prepare outputs
+ if (asioDriverInfo->outputChannels > kMaxOutputChannels)
+ asioDriverInfo->outputBuffers = kMaxOutputChannels;
+ else
+ asioDriverInfo->outputBuffers = asioDriverInfo->outputChannels;
+ for(i = 0; i < asioDriverInfo->outputBuffers; i++, info++)
+ {
+ info->isInput = ASIOFalse;
+ info->channelNum = i;
+ info->buffers[0] = info->buffers[1] = 0;
+ }
+
+ // create and activate buffers
+ result = ASIOCreateBuffers(asioDriverInfo->bufferInfos,
+ asioDriverInfo->outputBuffers+asioDriverInfo->inputBuffers,
+ asioDriverInfo->preferredSize, &asioCallbacks);
+
+ if (result == ASE_OK)
+ {
+ // now get all the buffer details, sample word length, name, word clock group and activation
+ for (i = 0; i < asioDriverInfo->inputBuffers + asioDriverInfo->outputBuffers; i++)
+ {
+ asioDriverInfo->channelInfos[i].channel = asioDriverInfo->bufferInfos[i].channelNum;
+ asioDriverInfo->channelInfos[i].isInput = asioDriverInfo->bufferInfos[i].isInput;
+
+ result = ASIOGetChannelInfo(&asioDriverInfo->channelInfos[i]);
+
+ if (result != ASE_OK){
+ qDebug() << "ERROR: Buffer init failed !";
+ break;
+ }
+ }
+
+ if (result == ASE_OK)
+ {
+ // get the input and output latencies
+ // Latencies often are only valid after ASIOCreateBuffers()
+ // (input latency is the age of the first sample in the currently returned audio block)
+ // (output latency is the time the first sample in the currently returned audio block requires to get to the output)
+ result = ASIOGetLatencies(&asioDriverInfo->inputLatency, &asioDriverInfo->outputLatency);
+ //if (result == ASE_OK)
+ //emit(initBuffers(asioDriverInfo->preferredSize));
+ }
+ }
+ return result;
+}
+
+/*******
+ *
+ * Open / Close Calls
+ *
+ ********/
+bool PlayerAsio::open()
+{
+ if (driverIsLoaded)
+ close();
+
+ QString name;
+
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterLeft"));
+
+ char driverName[MAX_DRIVER_NAME_LENGTH];
+ strcpy(driverName, name.latin1());
+
+ if (loadAsioDriver(driverName))
+ {
+ qDebug() << "Asio State: DRIVER LOADED";
+ if(initDriver()){
+ qDebug() << "Asio State: DRIVER INITIALIZED";
+ init_asio_static_data (&asioDriverInfo);
+ asioCallbacks.bufferSwitch = bufferSwitch;
+ asioCallbacks.sampleRateDidChange = sampleRateChanged;
+ asioCallbacks.asioMessage = asioMessages;
+ asioCallbacks.bufferSwitchTimeInfo = bufferSwitchTimeInfo;
+ create_asio_buffers(&asioDriverInfo);
+ startAsio();
+ return true;
+ }
+ }
+ return false;
+}
+
+void PlayerAsio::startAsio()
+{
+ if (ASIOStart() == ASE_OK)
+ {
+ driverIsLoaded = true;
+ qDebug() << "Asio streaming started";
+ }
+}
+
+void PlayerAsio::close()
+{
+ if(ASIOStop() == ASE_OK)
+ {
+ driverIsLoaded = false;
+ qDebug() << "Asio streaming stopped";
+ }
+
+ if(ASIOExit() == ASE_OK)
+ {
+ qDebug() << "Asio exited";
+ }
+}
+
+void PlayerAsio::setDefaults()
+{
+ // Get list of interfaces
+ QStringList interfaces = getInterfaces();
+
+ // Set first interfaces to master left
+ QStringList::iterator it = interfaces.begin();
+ if (it!=interfaces.end())
+ {
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue((*it)));
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue((*it)));
+ }
+ else
+ {
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
+ }
+
+ // Set head left and right to none
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
+
+}
+
+/*******
+ *
+ * Asio and mixxx Callbacks
+ *
+ ********/
+
+//----------------------------------------------------------------------------------
+void bufferSwitch(long index, ASIOBool processNow)
+{ // the actual processing callback.
+
+ ASIOTime timeInfo;
+ memset (&timeInfo, 0, sizeof (timeInfo));
+
+
+ bufferSwitchTimeInfo (&timeInfo, index, processNow);
+
+}
+
+
+//----------------------------------------------------------------------------------
+void sampleRateChanged(ASIOSampleRate sRate)
+{
+ // do whatever you need to do if the sample rate changed
+ // usually this only happens during external sync.
+ // Audio processing is not stopped by the driver, actual sample rate
+ // might not have even changed, maybe only the sample rate status of an
+ // AES/EBU or S/PDIF digital input at the audio device.
+ // You might have to update time/sample related conversion routines, etc.
+}
+
+//----------------------------------------------------------------------------------
+long asioMessages(long selector, long value, void * message, double * opt)
+{
+ // currently the parameters "value", "message" and "opt" are not used.
+ long ret = 0;
+ switch(selector)
+ {
+ case kAsioSelectorSupported:
+ if(value == kAsioResetRequest
+ || value == kAsioEngineVersion
+ || value == kAsioResyncRequest
+ || value == kAsioLatenciesChanged
+ // the following three were added for ASIO 2.0, you don't necessarily have to support them
+ || value == kAsioSupportsTimeInfo
+ || value == kAsioSupportsTimeCode
+ || value == kAsioSupportsInputMonitor)
+ ret = 1L;
+ break;
+ case kAsioResetRequest:
+ // defer the task and perform the reset of the driver during the next "safe" situation
+ // You cannot reset the driver right now, as this code is called from the driver.
+ // Reset the driver is done by completely destruct is. I.e. ASIOStop(), ASIODisposeBuffers(), Destruction
+ // Afterwards you initialize the driver again.
+ //asioDriverInfo.stopped; // In this sample the processing will just stop
+ ret = 1L;
+ break;
+ case kAsioResyncRequest:
+ // This informs the application, that the driver encountered some non fatal data loss.
+ // It is used for synchronization purposes of different media.
+ // Added mainly to work around the Win16Mutex problems in Windows 95/98 with the
+ // Windows Multimedia system, which could loose data because the Mutex was hold too long
+ // by another thread.
+ // However a driver can issue it in other situations, too.
+ ret = 1L;
+ break;
+ case kAsioLatenciesChanged:
+ // This will inform the host application that the drivers were latencies changed.
+ // Beware, it this does not mean that the buffer sizes have changed!
+ // You might need to update internal delay data.
+ ret = 1L;
+ break;
+ case kAsioEngineVersion:
+ // return the supported ASIO version of the host application
+ // If a host applications does not implement this selector, ASIO 1.0 is assumed
+ // by the driver
+ ret = 2L;
+ break;
+ case kAsioSupportsTimeInfo:
+ // informs the driver wether the asioCallbacks.bufferSwitchTimeInfo() callback
+ // is supported.
+ // For compatibility with ASIO 1.0 drivers the host application should always support
+ // the "old" bufferSwitch method, too.
+ ret = 1;
+ break;
+ case kAsioSupportsTimeCode:
+ // informs the driver wether application is interested in time code info.
+ // If an application does not need to know about time code, the driver has less work
+ // to do.
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+void PlayerAsio::processCallback(long bufferIndex) {
+
+ float * inputBuffer = prepareBuffer(bufferLength);
+ // perform the processing
+ for (int i = 0; i < asioDriverInfo.inputBuffers + asioDriverInfo.outputBuffers; i++)
+ {
+ if (asioDriverInfo.bufferInfos[i].isInput == false)
+ {
+ ASIOBufferInfo * bufferInfo = &asioDriverInfo.bufferInfos[i];
+
+ m_reenter++;
+ if (m_reenter > 1) {
+ qDebug() << "ASIO : reentered callback ???!!!";
+ return;
+ }
+
+ if (!driverIsLoaded) {
+ qDebug() << "ASIO : callback and not started ???!!!";
+ }
+
+
+ bool swap = true;
+
+
+ void * outputBuffer = bufferInfo->buffers[bufferIndex];
+ ASIOSampleType bufferType = asioDriverInfo.channelInfos[i].type;
+ switch (bufferType) {
+ case ASIOSTInt16LSB:
+ Output_Float32_Int16(i, inputBuffer, static_cast(outputBuffer), !swap);
+ break;
+ case ASIOSTInt16MSB:
+ Output_Float32_Int16(i, inputBuffer, static_cast(outputBuffer), swap);
+ break;
+ case ASIOSTInt32LSB:
+ Output_Float32_Int32(i, inputBuffer, static_cast(outputBuffer), !swap);
+ break;
+ case ASIOSTInt32MSB:
+ Output_Float32_Int32(i, inputBuffer, static_cast(outputBuffer), swap);
+ break;
+ case ASIOSTFloat32LSB:
+ //Output_Float32_Float32(i, inputBuffer, static_cast(outputBuffer), swap);
+ break;
+ case ASIOSTFloat32MSB:
+ //Output_Float32_Float32(i, inputBuffer, static_cast(outputBuffer), !swap);
+ memset(static_cast(outputBuffer),0,bufferLength*4);
+ break;
+ case ASIOSTInt24LSB: // used for 20 bits as well
+ Output_Float32_Int24(i, inputBuffer,static_cast(outputBuffer), !swap);
+ //memset(static_cast(outputBuffer),0,bufferLength*4);
+ break;
+ case ASIOSTInt24MSB: // used for 20 bits as well
+ case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
+ case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
+
+ // these are used for 32 bit data buffer, with different alignment of the data inside
+ // 32 bit PCI bus systems can more easily used with these
+
+ case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment
+ case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment
+ case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment
+ case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment
+
+
+ case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment
+ case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment
+ case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment
+ case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment
+ // not implemented !!
+
+ break;
+
+
+ }
+
+ m_reenter--;
+ }
+ }
+ if (asioDriverInfo.postOutput)
+ ASIOOutputReady();
+}
+
+ASIOTime * bufferSwitchTimeInfo(ASIOTime * timeInfo, long index, ASIOBool processNow)
+{
+ ((PlayerAsio *)(PlayerProxy::getPlayer()))->processCallback(index);
+
+ return 0L;
+}
diff -Nru mixxx-1.6.0/src/old/playerasio.h mixxx-1.6.1/src/old/playerasio.h
--- mixxx-1.6.0/src/old/playerasio.h 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/playerasio.h 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,133 @@
+// PlayerAsio.h: interface for the PlayerAsio class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include
+#include
+#include
+#include
+#include
+#include "player.h"
+#include "asiosys.h"
+#include "asio.h"
+#include "asiodrivers.h"
+
+
+#if !defined(PlayerAsio_H)
+#define PlayerAsio_H
+
+void __cdecl bufferSwitch(long index, ASIOBool processNow);
+long __cdecl asioMessages(long selector, long value, void* message, double* opt);
+void __cdecl sampleRateChanged(ASIOSampleRate sRate);
+ASIOTime* __cdecl bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow);
+
+enum {
+ // number of input and outputs supported by the host application
+ // you can change these to higher or lower values
+ kMaxInputChannels = 0,
+ kMaxOutputChannels = 4
+};
+
+
+// internal data storage
+typedef struct DriverInfo
+{
+
+ ASIODriverInfo driverInfo;
+
+
+ long inputChannels;
+ long outputChannels;
+
+
+ long minSize;
+ long maxSize;
+ long preferredSize;
+ long granularity;
+
+
+ ASIOSampleRate sampleRate;
+
+
+ bool postOutput;
+
+
+ long inputLatency;
+ long outputLatency;
+
+
+ long inputBuffers; // becomes number of actual created input buffers
+ long outputBuffers; // becomes number of actual created output buffers
+ ASIOBufferInfo bufferInfos[kMaxInputChannels + kMaxOutputChannels]; // buffer info's
+
+ // ASIOGetChannelInfo()
+ ASIOChannelInfo channelInfos[kMaxInputChannels + kMaxOutputChannels]; // channel info's
+
+
+ double nanoSeconds;
+ double samples;
+ double tcSamples; // time code samples
+
+
+ ASIOTime tInfo; // time info state
+ unsigned long sysRefTime; // system reference time, when bufferSwitch() was called
+
+
+} DriverInfo;
+
+
+class PlayerAsio : public Player
+{
+
+public:
+
+
+ PlayerAsio(ConfigObject *config);
+ virtual ~PlayerAsio();
+
+ bool initialize();
+ bool open();
+ void close();
+ void startAsio();
+
+ int getBufferSize(void);
+ int getSampleRate(void);
+ int getChannelCount(void);
+
+ QStringList getInterfaces();
+ QStringList getSampleRates();
+
+ void setDefaults();
+
+ static QString getSoundApi() { return "ASIO"; }
+ QString getSoundApiName() { return getSoundApi(); };
+
+ void process(const CSAMPLE *, const CSAMPLE *, const int) { };
+ void processCallback(long bufferIndex);
+
+
+private:
+ bool initDriver(void);
+
+ void Output_Float32_Int16(int channelNumber, float* inputBuffer, short* outputBuffer, bool swap);
+ void Output_Float32_Int32(int channelNumber, float* inputBuffer, float* outputBuffer, bool swap);
+ void Output_Float32_Int24(int channelNumber, float* inputBuffer, float* outputBuffer, bool swap);
+ void float32toInt24inPlace(float* buffer, long frames, bool swap);
+ void float32toInt32inPlace(float* buffer, long frames, bool swap);
+ void SwapBuffer(short* buffer);
+
+ ASIOError create_asio_buffers (DriverInfo *asioDriverInfo);
+ long init_asio_static_data (DriverInfo *asioDriverInfo);
+
+ AsioDrivers* driver;
+ int m_reenter;
+ bool driverIsLoaded;
+ int drvNum;
+ int bufferLength;
+ char* driverList[32];
+ /** Used in sample convertion */
+ float *m_pTempBuffer;
+
+};
+
+#endif
diff -Nru mixxx-1.6.0/src/old/player.cpp mixxx-1.6.1/src/old/player.cpp
--- mixxx-1.6.0/src/old/player.cpp 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/player.cpp 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,151 @@
+/***************************************************************************
+ player.cpp - description
+ -------------------
+ begin : Wed Feb 20 2002
+ copyright : (C) 2002 by Tue and Ken Haste Andersen
+ email :
+***************************************************************************/
+
+/***************************************************************************
+* *
+* 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. *
+* *
+***************************************************************************/
+
+#include "player.h"
+#include "enginemaster.h"
+#include "controlobject.h"
+
+#ifdef RECORD_OUTPUT
+// HACK TO RECORD OUTPUT. WRITTEN TO FILE AT PROGRAM EXIT
+ #include
+ #include
+typedef struct {
+ short int * pBuffer;
+ int size;
+} recordObject;
+Q3PtrList m_qRecordList;
+#endif
+
+//Static variable memory allocation
+short int Player::m_iBufferSize = 0;
+short int Player::m_iChannels[MAX_AUDIODEVICES];
+EngineMaster * Player::m_pMaster = 0;
+
+
+
+/* -------- ------------------------------------------------------
+ Purpose: Initializes the audio hardware.
+ Input: Size of the output buffer in samples
+ Output: Pointer to internal synthesis data structure.
+ -------- ------------------------------------------------------ */
+Player::Player(ConfigObject * pConfig)
+{
+ m_pConfig = pConfig;
+ m_pBuffer = new CSAMPLE[MAX_BUFFER_LEN];
+ m_pControlObjectSampleRate = ControlObject::getControl(ConfigKey("[Master]","samplerate"));
+ m_pControlObjectLatency = new ControlObject(ConfigKey("[Master]","latency"));;
+
+ for (int i = 0; i < MAX_AUDIODEVICES; i++)
+ {
+ m_iChannels[i] = 0;
+ }
+}
+
+/* -------- ------------------------------------------------------
+ Purpose: Terminate and deallocate the synthesis system
+ Input: -
+ Output: -
+ -------- ------------------------------------------------------ */
+Player::~Player()
+{
+ delete [] m_pBuffer;
+
+#ifdef RECORD_OUTPUT
+ //
+ // HACK: Write recorded sound
+ //
+
+ qDebug() << "Writing output to file... please wait!";
+
+ // Setup file format
+ AFfilesetup outputSetup = afNewFileSetup();
+ afInitFileFormat(outputSetup, AF_FILE_WAVE);
+ afInitRate(outputSetup, AF_DEFAULT_TRACK, m_pControlObjectSampleRate->get());
+ afInitChannels(outputSetup, AF_DEFAULT_TRACK, 2);
+ afInitSampleFormat (outputSetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
+ //afInitByteOrder (outputSetup, AF_DEFAULT_TRACK, AF_BYTEORDER_BIGENDIAN);
+
+ // Open file handle
+ AFfilehandle fh = afOpenFile("output.wav","w",outputSetup);
+ if (!fh)
+ qCritical("Could not write wave output file");
+ recordObject * r;
+ for (r = m_qRecordList.first(); r; r=m_qRecordList.next())
+ {
+ afWriteFrames(fh,AF_DEFAULT_TRACK,r->pBuffer,r->size/2);
+ }
+ afCloseFile(fh);
+#endif
+}
+
+/*
+ short int Player::getBufferSize()
+ {
+ // if (m_iChannels>0)
+ // return m_iBufferSize/m_iChannels;
+ // else
+ return m_iBufferSize;
+ }
+ */
+
+void Player::setMaster(EngineMaster * pMaster)
+{
+ m_pMaster = pMaster;
+}
+
+bool Player::open()
+{
+ if (m_pConfig->getValueString(ConfigKey("[Soundcard]","PitchIndpTimeStretch")).toInt())
+ qDebug() << "pitch true";
+
+ // Set sound scale method
+ if (m_pMaster)
+ m_pMaster->setPitchIndpTimeStretch(m_pConfig->getValueString(ConfigKey("[Soundcard]","PitchIndpTimeStretch")).toInt());
+
+ return true;
+}
+
+/* -------- ------------------------------------------------------
+ Purpose: Internal callback function used for preparing samples
+ for playback. This is where the synthesis is done.
+ Input: Number of samples for each channel (4 channels in all)
+ Output: pointer to resulting buffer of samples
+ -------- ------------------------------------------------------ */
+CSAMPLE * Player::prepareBuffer(int iBufferSize)
+{
+ // First, sync control parameters with changes from GUI thread
+ ControlObject::sync();
+
+ // Process a block of samples for output. iBufferSize is the
+ // number of samples for one channel, but the EngineObject
+ // architecture expects number of samples for two channels
+ // as input so...
+ m_pMaster->process(0, m_pBuffer, iBufferSize*2);
+
+#ifdef RECORD_OUTPUT
+ // HACK: RECORD SOUND
+ recordObject * r = new recordObject;
+ m_qRecordList.append(r);
+ r->size = iBufferSize*2;
+ r->pBuffer = new short int[r->size];
+ for (int j=0; jsize; ++j)
+ r->pBuffer[j] = (short int)(m_pBuffer[j]);
+#endif
+
+ return m_pBuffer;
+}
+
diff -Nru mixxx-1.6.0/src/old/player.h mixxx-1.6.1/src/old/player.h
--- mixxx-1.6.0/src/old/player.h 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/player.h 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,79 @@
+/***************************************************************************
+ player.h - description
+ -------------------
+ begin : Wed Feb 20 2002
+ copyright : (C) 2002 by Tue and Ken Haste Andersen
+ email :
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PLAYER_H
+#define PLAYER_H
+
+#include "configobject.h"
+#include
+#include "engineobject.h"
+#include
+
+#define MAX_AUDIODEVICES 2
+
+class EngineMaster;
+class ControlObject;
+
+class Player : public EngineObject
+{
+public:
+ Player(ConfigObject *pConfig);
+ virtual ~Player();
+ /** Initialize the API. Returns true on success. No other methods in a Player
+ * class can be called before this method returns true. Called by the proxy
+ * class. */
+ virtual bool initialize() = 0;
+ /** Returns the current buffer size (total latency) used by the playback system */
+ //static short int getBufferSize();
+ /** Set EngineMaster object */
+ static void setMaster(EngineMaster *pMaster);
+ /** Open devices according to config database, and start audio stream.
+ * Returns true on success. */
+ virtual bool open();
+ /** Close devices, and stop audio stream */
+ virtual void close() = 0;
+ /** Store default configuration in config database */
+ virtual void setDefaults() = 0;
+ /** Return list of interfaces */
+ virtual QStringList getInterfaces() = 0;
+ /** Return list of input interfaces */
+ virtual QStringList getInputInterfaces() = 0;
+ /** Return list of sample rates */
+ virtual QStringList getSampleRates() = 0;
+ /** Return name of sound api */
+ virtual QString getSoundApiName() = 0;
+
+protected:
+ /** Prepares one buffer of sound by calling the engine */
+ CSAMPLE *prepareBuffer(int iBufferSize);
+
+ /** Pointer to config database */
+ ConfigObject *m_pConfig;
+ /** Pointer to EngineMaster object */
+ static EngineMaster *m_pMaster;
+ CSAMPLE *m_pBuffer;
+ /** Current buffer size in use. */
+ static short int m_iBufferSize;
+ /** Current number of channels in use */
+ static short int m_iChannels[MAX_AUDIODEVICES];
+ /** Pointer to object holding sample rate */
+ ControlObject *m_pControlObjectSampleRate;
+ /** Pointer to object holding latency */
+ ControlObject *m_pControlObjectLatency;
+};
+
+#endif
diff -Nru mixxx-1.6.0/src/old/playerjack.cpp mixxx-1.6.1/src/old/playerjack.cpp
--- mixxx-1.6.0/src/old/playerjack.cpp 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/playerjack.cpp 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,370 @@
+/***************************************************************************
+ playerjack.cpp - description
+ -------------------
+ begin : Sat Nov 15 2003
+ copyright : (C) 2003 by Tue Haste Andersen
+ email :
+***************************************************************************/
+
+/***************************************************************************
+* *
+* 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. *
+* *
+***************************************************************************/
+
+#include "playerjack.h"
+#include "controlobject.h"
+#include
+#include
+#include
+#include "controlobject.h"
+
+PlayerJack::PlayerJack(ConfigObject * config) : Player(config) //, mLibJack("libjack.so")
+{
+ ports = 0;
+ m_bOpen = false;
+
+/*
+ //mLibJack = new QLibrary("jack");
+ if (!mLibJack.load())
+ qDebug() << "JACK lib path" << mLibJack.library();
+
+ //if (mLibJack.isLoaded())
+ {
+ jack_set_error_function = (jack_set_error_function_t) mLibJack.resolve("jack_set_error_function");
+ jack_port_unregister = (jack_port_unregister_t) mLibJack.resolve("jack_port_unregister");
+ jack_client_close = (jack_client_close_t) mLibJack.resolve("jack_client_close");
+ jack_client_new = (jack_client_new_t) mLibJack.resolve("jack_client_new");
+ jack_set_process_callback = (jack_set_process_callback_t) mLibJack.resolve("jack_set_process_callback");
+ jack_set_sample_rate_callback = (jack_set_sample_rate_callback_t) mLibJack.resolve("jack_set_sample_rate_callback");
+ jack_on_shutdown =(jack_on_shutdown_t) mLibJack.resolve("jack_on_shutdown");
+ jack_port_register =(jack_port_register_t) mLibJack.resolve("jack_port_register");
+ jack_activate =(jack_activate_t) mLibJack.resolve("jack_activate");
+ jack_connect =(jack_connect_t) mLibJack.resolve("jack_connect");
+ jack_port_name =(jack_port_name_t) mLibJack.resolve("jack_port_name");
+ jack_deactivate =(jack_deactivate_t) mLibJack.resolve("jack_deactivate");
+ jack_get_ports =(jack_get_ports_t) mLibJack.resolve("jack_get_ports");
+ jack_get_sample_rate =(jack_get_sample_rate_t) mLibJack.resolve("jack_get_sample_rate");
+ jack_port_get_buffer =(jack_port_get_buffer_t) mLibJack.resolve("jack_port_get_buffer");
+ }
+ */
+}
+
+PlayerJack::~PlayerJack()
+{
+// if (!mLibJack.isLoaded())
+// return;
+
+ close();
+
+ if (client)
+ {
+ jack_port_unregister(client, output_master_left);
+ jack_port_unregister(client, output_master_right);
+ jack_port_unregister(client, output_head_left);
+ jack_port_unregister(client, output_head_right);
+
+ jack_client_close(client);
+ }
+
+ if (ports)
+ free(ports);
+}
+
+bool PlayerJack::initialize()
+{
+ // Verify that library is loaded, and all function pointers has been retreived
+ /*
+ if (!mLibJack.isLoaded())
+ {
+ qDebug() << "lib not loaded";
+ return false;
+ }
+ else
+ if (!jack_set_error_function |
+ !jack_port_unregister |
+ !jack_client_close |
+ !jack_client_new |
+ !jack_set_process_callback |
+ !jack_set_sample_rate_callback |
+ !jack_on_shutdown |
+ !jack_port_register |
+ !jack_activate |
+ !jack_connect |
+ !jack_port_name |
+ !jack_deactivate |
+ !jack_get_ports |
+ !jack_get_sample_rate |
+ !jack_port_get_buffer)
+ {
+ qDebug() << "API function pointer error";
+ return false;
+ }
+ */
+
+ jack_set_error_function(jackError);
+
+ if ((client = jack_client_new("Mixxx")) == 0)
+ return false;
+
+ jack_set_process_callback(client, jackProcess, this);
+ jack_set_sample_rate_callback(client, jackSrate, this);
+ jack_on_shutdown(client, jackShutdown, this);
+
+ output_master_left = jack_port_register(client, "Master left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+ output_master_right = jack_port_register(client, "Master right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+ output_head_left = jack_port_register(client, "Head left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+ output_head_right = jack_port_register(client, "Head right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+
+ return true;
+}
+
+bool PlayerJack::open()
+{
+ Player::open();
+
+ /* tell the JACK server that we are ready to roll */
+ if (jack_activate(client))
+ {
+ qDebug() << "Jack: Cannot activate client";
+ return false;
+ }
+
+ // Connect to the ports
+ QString name;
+ m_iChannels = 0;
+
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterLeft"));
+ if (name != "None")
+ {
+ qDebug() << "connecting" << name << "to master left";
+ if (jack_connect(client, jack_port_name(output_master_left), name.latin1()))
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
+ else
+ {
+ m_iBufferSize = jack_port_get_total_latency(client, output_master_left);
+ m_iChannels++;
+ }
+ }
+
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterRight"));
+ if (name != "None")
+ {
+ qDebug() << "connecting" << name << "to master right";
+ if (jack_connect(client, jack_port_name(output_master_right), name.latin1()))
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
+ else
+ {
+ m_iBufferSize = jack_port_get_total_latency(client, output_master_right);
+ m_iChannels++;
+ }
+ }
+
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceHeadLeft"));
+ if (name != "None")
+ {
+ qDebug() << "connecting" << name << "to head left";
+ if (jack_connect(client, jack_port_name(output_head_left), name.latin1()))
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
+ else
+ {
+ m_iBufferSize = jack_port_get_total_latency(client, output_head_left);
+ m_iChannels++;
+ }
+ }
+
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceHeadRight"));
+ if (name != "None")
+ {
+ qDebug() << "connecting" << name << "to head right";
+ if (jack_connect(client, jack_port_name(output_head_right), name.latin1()))
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
+ else
+ {
+ m_iBufferSize = jack_port_get_total_latency(client, output_head_right);
+ m_iChannels++;
+ }
+ }
+
+ qDebug() << "channels " << m_iChannels << ", latency " << m_iBufferSize;
+
+
+ // Update the config database with the used sample rate
+ QStringList srates = getSampleRates();
+ QStringList::iterator it = srates.begin();
+ if (*it)
+ {
+ m_pConfig->set(ConfigKey("[Soundcard]","Samplerate"),ConfigValue((*it)));
+
+ // Set currently used latency in config database
+ int msec = (int)(1000.*(float)m_iBufferSize/((float)(*it).toInt()));
+ m_pConfig->set(ConfigKey("[Soundcard]","Latency"), ConfigValue(msec));
+
+ // Update SRATE and Latency ControlObjects
+ m_pControlObjectSampleRate->queueFromThread((double)((*it).toInt()));
+ m_pControlObjectLatency->queueFromThread((double)msec);
+
+ }
+
+ m_bOpen = true;
+ return true;
+}
+
+void PlayerJack::close()
+{
+ // Deactivate jack and disconnect all ports
+ if (m_bOpen && client)
+ jack_deactivate(client);
+ m_bOpen = false;
+}
+
+void PlayerJack::setDefaults()
+{
+ // Get list of interfaces
+ QStringList interfaces = getInterfaces();
+
+ // Set first interfaces to master left
+ QStringList::iterator it = interfaces.begin();
+ if (*it)
+ {
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue((*it)));
+ }
+ else
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
+
+ // Set second interface to master right
+ if (*it) ++it;
+ if (*it)
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue((*it)));
+ else
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
+
+ // Set head left and right to none
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
+
+ // Set default sample rate
+ QStringList srates = getSampleRates();
+ it = srates.begin();
+ if (*it)
+ {
+ m_pConfig->set(ConfigKey("[Soundcard]","Samplerate"),ConfigValue((*it)));
+
+ // Set currently used latency in config database
+ int msec = 1000*m_iBufferSize/(4*(*it).toInt());
+ m_pConfig->set(ConfigKey("[Soundcard]","Latency"), ConfigValue(msec));
+ }
+}
+
+QStringList PlayerJack::getInterfaces()
+{
+ QStringList result;
+
+ if (!client && !initialize())
+ {
+ qDebug() << "Jack: Failed to reinitialize the connection to Jack";
+ return result;
+ }
+
+ if ((ports = jack_get_ports (client, 0, 0, JackPortIsPhysical|JackPortIsInput)) == 0)
+ qDebug() << "Jack: Cannot find any physical playback ports";
+ else
+ {
+ int i=0;
+ while (ports[i]!=0)
+ {
+ result.append(ports[i]);
+ ++i;
+ }
+ }
+
+ return result;
+}
+
+QStringList PlayerJack::getSampleRates()
+{
+ QStringList result;
+
+ if (client)
+ result.append(QString("%1").arg((int)jack_get_sample_rate(client)));
+
+ return result;
+}
+
+QString PlayerJack::getSoundApi()
+{
+ return QString("Jack");
+}
+
+int PlayerJack::callbackProcess(int iBufferSize)
+{
+// qDebug() << "buffer size " << iBufferSize;
+ jack_default_audio_sample_t * out_ml = (jack_default_audio_sample_t *)jack_port_get_buffer(output_master_left, iBufferSize);
+ jack_default_audio_sample_t * out_mr = (jack_default_audio_sample_t *)jack_port_get_buffer(output_master_right, iBufferSize);
+ jack_default_audio_sample_t * out_hl = (jack_default_audio_sample_t *)jack_port_get_buffer(output_head_left, iBufferSize);
+ jack_default_audio_sample_t * out_hr = (jack_default_audio_sample_t *)jack_port_get_buffer(output_head_right, iBufferSize);
+
+ if (m_bOpen)
+ {
+ CSAMPLE * buffer = prepareBuffer(iBufferSize);
+
+ for (int i=0; iqueueFromThread((double)srate);
+}
+
+void PlayerJack::callbackSetBufferSize(int iBufferSize)
+{
+ m_iBufferSize = iBufferSize;
+}
+
+void PlayerJack::callbackShutdown()
+{
+ m_pConfig->set(ConfigKey("[Soundcard]","SoundApi"), ConfigValue("None"));
+
+ qWarning("Jack connection was killed.\n\nThis could be due to a high CPU load. Try increasing the latency\nwhen starting the Jack sound server.");
+}
+
+void jackError(const char * desc)
+{
+ qDebug() << "Jack experienced an error:" << desc;
+}
+
+int jackProcess(jack_nframes_t nframes, void * arg)
+{
+ ((PlayerJack *)arg)->callbackProcess(nframes);
+ return 0;
+}
+
+int jackSrate(jack_nframes_t nframes, void * arg)
+{
+ // Update SRATE in EngineObject
+ ((PlayerJack *)arg)->callbackSetSrate(nframes);
+ return 0;
+}
+
+void jackShutdown(void * arg)
+{
+ ((PlayerJack *)arg)->callbackShutdown();
+}
+
+void jackBufferSize(jack_nframes_t nframes, void * arg)
+{
+ ((PlayerJack *)arg)->callbackSetBufferSize(nframes);
+}
diff -Nru mixxx-1.6.0/src/old/playerjack.h mixxx-1.6.1/src/old/playerjack.h
--- mixxx-1.6.0/src/old/playerjack.h 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/playerjack.h 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,120 @@
+/***************************************************************************
+ playerjack.h - description
+ -------------------
+ begin : Sat Nov 15 2003
+ copyright : (C) 2003 by Tue Haste Andersen
+ email :
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PLAYERJACK_H
+#define PLAYERJACK_H
+
+#include "player.h"
+#include
+#include
+
+/**
+ *@author Tue and Ken Haste Andersen
+ */
+
+class PlayerJack : public Player
+{
+public:
+ PlayerJack(ConfigObject *config);
+ ~PlayerJack();
+ bool initialize();
+ bool open();
+ void close();
+ void setDefaults();
+ QStringList getInterfaces();
+ QStringList getSampleRates();
+ static QString getSoundApi();
+ QString getSoundApiName() { return getSoundApi(); };
+ /** Satisfy virtual declaration in EngineObject */
+ void process(const CSAMPLE *, const CSAMPLE *, const int) {};
+ /** Process samples. Called from jack callback */
+ int callbackProcess(int iBufferSize);
+ /** Used to set sample rate from Jack callback */
+ void callbackSetSrate(int iSrate);
+ /** Used to set current buffer size */
+ void callbackSetBufferSize(int iBufferSize);
+ /** Used to reinitialize when shut down by Jack server */
+ void callbackShutdown();
+
+protected:
+ /** Pointer to QLibrary object */
+ //QLibrary mLibJack;
+ /** Pointer to client info */
+ jack_client_t *client;
+ /** Null terminated array of port names */
+ const char **ports;
+ /** Playback ports */
+ jack_port_t *output_master_left, *output_master_right, *output_head_left, *output_head_right;
+ /** True if devices are open */
+ bool m_bOpen;
+
+/*
+ typedef void (*jack_set_error_function_t)(void (*func)(const char *));
+ jack_set_error_function_t jack_set_error_function;
+
+ typedef int (*jack_port_unregister_t)(jack_client_t *, jack_port_t *);
+ jack_port_unregister_t jack_port_unregister;
+
+ typedef int (*jack_client_close_t)(jack_client_t *client);
+ jack_client_close_t jack_client_close;
+
+ typedef jack_client_t* (*jack_client_new_t)(const char *client_name);
+ jack_client_new_t jack_client_new;
+
+ typedef int (*jack_set_process_callback_t)(jack_client_t *client,JackProcessCallback process_callback,void *arg);
+ jack_set_process_callback_t jack_set_process_callback;
+
+ typedef int (*jack_set_sample_rate_callback_t)(jack_client_t *client,JackSampleRateCallback srate_callback,void *arg);
+ jack_set_sample_rate_callback_t jack_set_sample_rate_callback;
+
+ typedef void (*jack_on_shutdown_t)(jack_client_t *client, void (*function)(void *arg), void *arg);
+ jack_on_shutdown_t jack_on_shutdown;
+
+ typedef jack_port_t* (*jack_port_register_t)(jack_client_t *,const char *port_name,const char *port_type,unsigned long flags,unsigned long buffer_size);
+ jack_port_register_t jack_port_register;
+
+ typedef int (*jack_activate_t)(jack_client_t *client);
+ jack_activate_t jack_activate;
+
+ typedef int (*jack_connect_t)(jack_client_t *,const char *source_port,const char *destination_port);
+ jack_connect_t jack_connect;
+
+ typedef const char* (*jack_port_name_t)(const jack_port_t *port);
+ jack_port_name_t jack_port_name;
+
+ typedef int (*jack_deactivate_t)(jack_client_t *client);
+ jack_deactivate_t jack_deactivate;
+
+ typedef const char** (*jack_get_ports_t)(jack_client_t *,const char *port_name_pattern,const char *type_name_pattern,unsigned long flags);
+ jack_get_ports_t jack_get_ports;
+
+ typedef jack_nframes_t (*jack_get_sample_rate_t)(jack_client_t *);
+ jack_get_sample_rate_t jack_get_sample_rate;
+
+ typedef void* (*jack_port_get_buffer_t)(jack_port_t *, jack_nframes_t);
+ jack_port_get_buffer_t jack_port_get_buffer;
+*/
+};
+
+// Jack callbacks:
+void jackError(const char *desc);
+int jackProcess(jack_nframes_t nframes, void *arg);
+int jackSrate(jack_nframes_t nframes, void *arg);
+void jackShutdown(void *arg);
+void jackBufferSize(jack_nframes_t nframes, void *arg);
+
+#endif
diff -Nru mixxx-1.6.0/src/old/playerportaudio.cpp mixxx-1.6.1/src/old/playerportaudio.cpp
--- mixxx-1.6.0/src/old/playerportaudio.cpp 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/playerportaudio.cpp 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,938 @@
+/***************************************************************************
+ playerportaudiov19.cpp - description
+ -------------------
+ begin : Wed Feb 20 2002
+ copyright : (C) 2002 by Tue and Ken Haste Andersen
+ (C) 2006/2007 by Albert Santoni
+ (C) 2006 by Adam Davison
+ email :
+***************************************************************************/
+
+/***************************************************************************
+* *
+* 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. *
+* *
+***************************************************************************/
+
+#include "playerportaudio.h"
+#include "controlobject.h"
+
+// Mathstuff required for Win32
+#include "mathstuff.h"
+//Added by qt3to4:
+#include
+#include
+#include
+
+bool PlayerPortAudio::m_painited = false;
+
+PlayerPortAudio::PlayerPortAudio(ConfigObject * config, QString api_name) : Player(config)
+{
+ for (int i = 0; i < MAX_AUDIODEVICES; i++)
+ {
+ m_devId[i] = -1;
+ m_inputDevId[i] = -1;
+ m_pStream[i] = 0;
+ m_iChannels[i] = -1;
+ }
+
+ m_iNumberOfBuffers = 2;
+ m_iMasterLeftCh = -1;
+ m_iMasterRigthCh = -1;
+ m_iHeadLeftCh = -1;
+ m_iHeadRightCh = -1;
+ m_iNumActiveDevices = 0;
+ m_iPreviousDevIndex = -1;
+#ifdef __VINYLCONTROL__
+ m_VinylControl[0] = NULL;
+ m_VinylControl[1] = NULL;
+#endif
+
+ m_HostAPI = api_name;
+ m_bInit = false;
+}
+
+PlayerPortAudio::~PlayerPortAudio()
+{
+ //Close all the audio devices.
+ close();
+
+ if (m_bInit) {
+ Pa_Terminate();
+ m_painited = false;
+ }
+}
+
+bool PlayerPortAudio::initialize()
+{
+ PaError err = Pa_Initialize();
+ if (err!=paNoError)
+ {
+ qDebug() << "PortAudio error: " << Pa_GetErrorText(err);
+ m_bInit = false;
+ }
+ else
+ m_bInit = true;
+
+ return m_bInit;
+}
+
+bool PlayerPortAudio::open()
+{
+ Player::open();
+
+#ifdef __VINYLCONTROL__
+ //Create a new VinylControl object so that it updates it's settings.
+ //TODO: FIX THIS SAMPLERATE HACKAGE
+ int iTempSrate = m_pConfig->getValueString(ConfigKey("[Soundcard]","Samplerate")).toInt();
+ if (iTempSrate <= 0)
+ iTempSrate = 44100;
+ m_VinylControl[0] = new VinylControlProxy(m_pConfig, "[Channel1]", iTempSrate);
+ m_VinylControl[1] = new VinylControlProxy(m_pConfig, "[Channel2]", 44100);
+#endif
+
+ // Find out which device to open. Select the first one listed as either Master Left,
+ // Master Right, Head Left, Head Right. If other devices are requested for opening
+ // than the one selected here, set them to "None" in the config database
+
+ // For the record, with MAX_AUDIODEVICES currently set to 2, we're referring to
+ // Master Left/Right as device 1 and Headphones as device 2 (unless Master and
+ // Headphones are on the same device, then we only use device 1.)
+ PaDeviceIndex id[MAX_AUDIODEVICES];
+ PaDeviceIndex id_input[MAX_AUDIODEVICES];
+ int iChannelMax[MAX_AUDIODEVICES]; /** Maximum number of channels needed */
+ PaDeviceIndex temp_id = -1;
+ QString name;
+
+ for (int i = 0; i < MAX_AUDIODEVICES; i++)
+ {
+ iChannelMax[i] = -1;
+ id[i] = -1;
+ id_input[i] = -1;
+ }
+
+ m_iMasterLeftCh = -1;
+ m_iMasterRigthCh = -1;
+ m_iHeadLeftCh = -1;
+ m_iHeadRightCh = -1;
+
+ waitForNextOutput.wakeAll();
+
+ // Master left
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterLeft"));
+ temp_id = getDeviceID(name);
+ if (temp_id >= 0)
+ {
+ if (getChannelNo(name)>=0)
+ {
+ id[0] = temp_id;
+ iChannelMax[0] = getChannelNo(name);
+ m_iMasterLeftCh = getChannelNo(name)-1;
+ }
+ }
+
+ // Master right
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterRight"));
+ temp_id = getDeviceID(name);
+ if (getChannelNo(name)>=0 //Make sure we got a valid number of channels
+ && ((id[0]==-1 && temp_id>=0) //Make sure the left channel and this (right) channel IDs are valid
+ || (temp_id!=-1 && id[0]==temp_id))) //No idea...
+ {
+ id[0] = math_max(temp_id, id[0]);
+ iChannelMax[0] = math_max(iChannelMax[0], getChannelNo(name));
+ m_iMasterRigthCh = getChannelNo(name)-1;
+ }
+
+ // Head left
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceHeadLeft"));
+ temp_id = getDeviceID(name);
+ if (getChannelNo(name)>=0 && ((id[1]==-1 && temp_id>=0) || (temp_id!=-1 && id[1]==temp_id)))
+ {
+ id[1] = temp_id;
+ iChannelMax[1] = math_max(iChannelMax[1], getChannelNo(name));
+ m_iHeadLeftCh = getChannelNo(name)-1;
+ }
+
+ // Head right
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceHeadRight"));
+ temp_id = getDeviceID(name);
+ if (getChannelNo(name)>=0 && ((id[1]==-1 && temp_id>=0) || (temp_id!=-1 && id[1]==temp_id)))
+ {
+ id[1] = temp_id;
+ iChannelMax[1] = math_max(iChannelMax[1], getChannelNo(name));
+ m_iHeadRightCh = getChannelNo(name)-1;
+ }
+
+ // Inputs
+ name = m_pConfig->getValueString(ConfigKey("[VinylControl]","DeviceInputDeck1"));
+ temp_id = getInputDeviceID(name);
+ if (temp_id != -1)
+ id_input[0] = temp_id;
+
+ name = m_pConfig->getValueString(ConfigKey("[VinylControl]","DeviceInputDeck2"));
+ temp_id = getInputDeviceID(name);
+ if (temp_id != -1)
+ id_input[1] = temp_id;
+
+ // Check if any of the devices in the config database needs to be set to "None"
+ if (m_iMasterLeftCh<0)
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
+ if (m_iMasterRigthCh<0)
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
+ if (m_iHeadLeftCh<0)
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
+ if (m_iHeadRightCh<0)
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
+
+ // Number of channels to open
+ int iChannels[MAX_AUDIODEVICES];
+ if (id[0] == id[1]) //Check if we're supposed to use the same soundcard for both Master and Headphone output
+ {
+ iChannels[0] = math_max(iChannelMax[0], iChannelMax[1]);
+ iChannels[1] = -1;
+ }
+ else
+ {
+ iChannels[0] = iChannelMax[0];
+ iChannels[1] = iChannelMax[1];
+ }
+
+ // Sample rate
+ int iSrate = m_pConfig->getValueString(ConfigKey("[Soundcard]","Samplerate")).toInt();
+ if (iSrate <= 0)
+ iSrate = 44100;
+
+ // Get latency in msec
+ int iLatencyMSec = m_pConfig->getValueString(ConfigKey("[Soundcard]","Latency")).toInt();
+
+ if (iLatencyMSec <= 0) //Make sure we don't get a crazy latency value.
+ iLatencyMSec = 100;
+
+ // Latency in samples
+ //int iLatencySamples = (int)((float)(iSrate*iChannels)/1000.f*(float)iLatencyMSec); //Pre-multisoundcard output
+ int iLatencySamples = (int)((float)(iSrate*math_max(iChannels[0], iChannels[1]))/1000.f*(float)iLatencyMSec);
+
+ // Round to the nearest multiple of 4.
+ iLatencySamples -= (iLatencySamples % 4);
+ iLatencySamples += 4;
+
+ qDebug() << "iLatencySamples: " << iLatencySamples;
+
+ // Apply simple rule to determine number of buffers
+ if (iLatencySamples/kiMaxFrameSize<2)
+ m_iNumberOfBuffers = 2;
+ else
+ m_iNumberOfBuffers = iLatencySamples/kiMaxFrameSize;
+
+ // Frame size...
+ int iFramesPerBuffer = iLatencySamples/m_iNumberOfBuffers;
+
+ // Ensure the chosen configuration is valid
+ //TODO: Fix this in our PortAudio-v19 implementation. PA19 ditches the Pa_GetMinNumBuffers() function, as it's
+ // not needed anymore.
+ /*
+ if (m_iNumberOfBuffersset(ConfigKey("[Soundcard]","Latency"), ConfigValue(iLatencyMSec));
+ }
+ */
+
+ // Callback function to use
+ PaStreamCallback * callback = paV19Callback;
+ qDebug() << "PortAudio: kiMaxFrameSize: " << kiMaxFrameSize << ", iLatencyMSec: " << iLatencyMSec;
+ qDebug() << "PortAudio: id[0] " << id[0] << ", sr " << iSrate << ", ch[0] " << iChannels[0] << ", bufsize " << iFramesPerBuffer << ", bufno " << m_iNumberOfBuffers << ", req. latency " << iLatencyMSec << " msec";
+ qDebug() << "PortAudio: id[1] " << id[1] << ", sr " << iSrate << ", ch[1] " << iChannels[1] << ", bufsize " << iFramesPerBuffer << ", bufno " << m_iNumberOfBuffers << ", req. latency " << iLatencyMSec << " msec";
+
+ qDebug() << "Device 1 indices (id[0]: " << id[0] << ", id_input[0]: " << id_input[0] << ")";
+ qDebug() << "Device 2 indices (id[1]: " << id[1] << ", id_input[1]: " << id_input[1] << ")";
+
+
+ //If all devices are set to "None", then just return.
+ if ((id[0] < 0) && (id[1] < 0))
+ return false;
+
+ PaStreamParameters outputParams[MAX_AUDIODEVICES];
+ PaStreamParameters inputParams[MAX_AUDIODEVICES];
+ bool bDeviceAlreadyOpened = false;
+
+ //Set up and open each soundcard that we need!
+ for (int i = 0; i < MAX_AUDIODEVICES; i++)
+ {
+ bDeviceAlreadyOpened = false;
+
+ for (int j = 0; j < i; j++) //Check to see if we've already opened this device (eg. Maybe we're already using it for Master output)
+ {
+ if (j != i)
+ {
+ if (id[j] == id[i] && id[j] != -1) {
+ bDeviceAlreadyOpened = true;
+ }
+ }
+ }
+ if (((id[i] != -1) && !bDeviceAlreadyOpened) || (id_input[i] != -1)) //Make sure we're supposed to open this device...
+ {
+ qDebug() << "PortAudio: Trying to open device id " << id[i] << ", with channels " << iChannels[i] << " at samplerate " << iSrate;
+ PaStreamParameters * p_outputParams;
+ outputParams[i].device = id[i];
+ outputParams[i].channelCount = iChannels[i];
+ outputParams[i].sampleFormat = paFloat32;
+ outputParams[i].suggestedLatency = ((float)iLatencyMSec) / 1000.0f; //Latency in seconds.
+ outputParams[i].hostApiSpecificStreamInfo = NULL;
+
+ PaStreamParameters * p_inputParams; //TODO: Does this need to be made an array like inputParams?
+ inputParams[i].device = id_input[i]; //TODO: Isn't the "input" device always the same as the output device? (if there is an output device?)
+ // Maybe that should be restricted in the preferences GUI...
+ // NO, it's not always the same as the output device! Consider using 4 outputs on your
+ // master soundcard, and a different soundcard for input. The master's id is the same as the first
+ // for the second stream, but the input id for the second stream is something different.
+ inputParams[i].channelCount = 2;
+ inputParams[i].sampleFormat = paInt16; //As needed by scratchlib
+ inputParams[i].suggestedLatency = ((float)iLatencyMSec) / 1000.0f; //Latency in seconds.
+ inputParams[i].hostApiSpecificStreamInfo = NULL;
+
+ if (id[i] < 0 || (i > 0 && (id[1] == id[0]))) //TODO: comment this the same as the below input one.... kinda
+ p_outputParams = NULL;
+ else
+ p_outputParams = &(outputParams[i]);
+
+ if (id_input[i] < 0) //If we're not supposed to open an input device, set the pointer to be null.
+ p_inputParams = NULL; //NULL input params in Pa_OpenStream means don't open the device for input.
+ else
+ p_inputParams = &(inputParams[i]);
+
+ PaError err = paNoError;
+
+ // Set up a struct containing all the data we want to pass back to the callback
+ callbackStuff[i].player = this;
+ callbackStuff[i].devIndex = i; //The audio device's index (NOT THE PORTAUDIO ID!!!)
+
+ // Try open device using iChannelMax
+ err = Pa_OpenStream(&m_pStream[i],
+ p_inputParams, // Input parameters
+ p_outputParams, // Output parameters
+ iSrate, // Sample rate
+ iFramesPerBuffer, // Frames per buffer
+ paClipOff, // Stream flags
+ callback, // Stream callback
+ &(callbackStuff[i])); // Pointer passed to the callback function
+
+ if (err == paNoError)
+ m_iChannels[i] = iChannels[i];
+ else
+ {
+ // Try open device using maximum supported channels by soundcard
+ iChannels[i] = Pa_GetDeviceInfo(id[i])->maxOutputChannels;
+ outputParams[i].channelCount = iChannels[i];
+ err = Pa_OpenStream(&m_pStream[i],
+ p_inputParams, // Input parameters
+ p_outputParams, // Output parameters
+ iSrate, // Sample rate
+ iFramesPerBuffer, // Frames per buffer
+ paClipOff, // Stream flags
+ callback, // Stream callback
+ &(callbackStuff[i])); // Pointer passed to the callback function
+ if (err==paNoError)
+ m_iChannels[i] = iChannels[i];
+ }
+
+ if( err != paNoError ) //*** TODO/WARNING: I don't think this block makes any sense whatsoever... - Albert April 21/07
+ {
+ // Try open device using only two channels
+ outputParams[i].channelCount = 2;
+ err = Pa_OpenStream(&m_pStream[i],
+ p_inputParams, // Input parameters
+ p_outputParams, // Output parameters
+ iSrate, // Sample rate
+ iFramesPerBuffer, // Frames per buffer
+ paClipOff, // Stream flags
+ callback, // Stream callback
+ &(callbackStuff[i])); // Pointer passed to the callback function
+ if (err==paNoError)
+ {
+ m_iChannels[i] = 2;
+
+ // Update channel variables and config database
+ if (m_iMasterLeftCh>1)
+ {
+ m_iMasterLeftCh = -1;
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
+ }
+ if (m_iMasterRigthCh>1)
+ {
+ m_iMasterRigthCh = -1;
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
+ }
+ if (m_iHeadLeftCh>1)
+ {
+ m_iHeadLeftCh = -1;
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
+ }
+ if (m_iHeadRightCh>1)
+ {
+ m_iHeadRightCh = -1;
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
+ }
+ }
+ }
+
+ if( err != paNoError ) //Make sure we opened the soundcard successfully.
+ {
+ qDebug() << "PortAudio: Open stream error: " << Pa_GetErrorText(err);
+ qDebug() << "PortAudio: More error info: " << Pa_GetLastHostErrorInfo()->errorText;
+
+ m_devId[i] = -1;
+ m_inputDevId[i] = -1;
+ m_iChannels[i] = -1;
+
+ return false;
+ }
+
+ m_devId[i] = id[i];
+ m_inputDevId[i] = id_input[i];
+
+ // Update SRATE and Latency ControlObjects
+ m_pControlObjectSampleRate->queueFromThread((double)iSrate);
+ m_pControlObjectLatency->queueFromThread((double)iLatencyMSec);
+
+ // Start stream
+ err = Pa_StartStream(m_pStream[i]);
+ if (err != paNoError)
+ {
+ qDebug() << "PortAudio: Start stream " << i << " error: " << Pa_GetErrorText(err);
+ m_pStream[i] = 0;
+ }
+ else
+ qDebug() << "PortAudio: Started stream " << i << " successfully";
+
+ //If the Master and Headphone devices are the same, or the Headphone device is set to "None",
+ //then we can just break out of this loop:
+ /*if ((id[0] == id[1]) || (id[1] == -1))
+ {
+ calculateNumActiveDevices();
+ return true;
+ }*/
+ }
+ }
+
+ /*
+ //Print out all the information about the soundcards and their channels.
+ qDebug() << "PortAudio: ==Soundcard Summary==";
+ qDebug() << "Device 1 index: " << m_devId[0];
+ qDebug() << "Device 2 index: " << m_devId[1];
+ qDebug() << "Channels for device 1: " << m_iChannels[0];
+ qDebug() << "Channels for device 2: " << m_iChannels[1];
+ qDebug() << "m_iMasterLeftCh: " << m_iMasterLeftCh;
+ qDebug() << "m_iMasterRightCh: " << m_iMasterRigthCh;
+ qDebug() << "m_iHeadLeftCh: " << m_iHeadLeftCh;
+ qDebug() << "m_iHeadRightCh: " << m_iHeadRightCh;
+ */
+
+ calculateNumActiveDevices();
+ return true;
+}
+
+//Find out how many active/open soundcards there are.
+void PlayerPortAudio::calculateNumActiveDevices()
+{
+ int count = 0;
+
+ for (int i = 0; i < MAX_AUDIODEVICES; i++)
+ {
+ if (m_devId[i] != -1)
+ count++;
+ }
+ m_iNumActiveDevices = count;
+}
+
+void PlayerPortAudio::close()
+{
+ //waitForNextOutput.wakeAll();
+
+ for (int i = 0; i < MAX_AUDIODEVICES; i++)
+ {
+ m_devId[i] = -1;
+ m_iChannels[i] = 0;
+
+ // Stop streams
+ if (m_pStream[i])
+ {
+ PaError err = Pa_StopStream(m_pStream[i]);
+ if( err != paNoError )
+ qDebug() << "PortAudio: Stop stream " << i << " error: " << Pa_GetErrorText(err) << ",";
+
+ // Close streams
+ err = Pa_CloseStream(m_pStream[i]);
+ if( err != paNoError )
+ qDebug() << "PortAudio: Close stream " << i << " error: " << Pa_GetErrorText(err);
+ }
+
+ m_pStream[i] = 0;
+ waitForNextOutput.wakeAll();
+ calculateNumActiveDevices();
+ }
+
+ //waitForNextOutput.wakeAll();
+
+ m_iMasterLeftCh = -1;
+ m_iMasterRigthCh = -1;
+ m_iHeadLeftCh = -1;
+ m_iHeadRightCh = -1;
+}
+
+void PlayerPortAudio::setDefaults()
+{
+ // Get list of interfaces
+ QStringList interfaces = getInterfaces();
+
+ // Set first interfaces to master left
+ QStringListIterator it(interfaces);
+
+ if (it.hasNext())
+ {
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue((it.next())));
+ }
+ else
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
+
+ // Set second interface to master right
+ if (it.hasNext())
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue((it.next())));
+ else
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
+
+ // Set head left and right to none
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
+
+ // Set default sample rate
+ QStringList srates = getSampleRates();
+ QStringListIterator itSRates(srates);
+ while (it.hasNext())
+ {
+ QString s;
+ s = itSRates.next();
+ m_pConfig->set(ConfigKey("[Soundcard]","Samplerate"),ConfigValue(s));
+ if ((s).toInt()>=44100)
+ break;
+ }
+
+ // Set currently used latency in config database
+ //int msec = (int)(1000.*(2.*1024.)/(2.*(float)(*it).toInt()));
+ int msec = 100; // More conservative defaults
+
+ m_pConfig->set(ConfigKey("[Soundcard]","Latency"), ConfigValue(msec));
+}
+
+QStringList PlayerPortAudio::getInterfaces()
+{
+ //qDebug() << "PortAudio: getInterfaces()";
+
+ QStringList result;
+ const PaHostApiInfo * apiInfo = NULL;
+ const PaDeviceInfo * devInfo = NULL;
+ QString api;
+
+ if (m_HostAPI == "None")
+ return result;
+
+ PaDeviceIndex numDevices = Pa_GetDeviceCount();
+
+ for (int i = 0; i < numDevices; i++)
+ {
+ devInfo = Pa_GetDeviceInfo(i);
+
+ // Add the device if it is an output device:
+ //if (devInfo != NULL && devInfo->maxOutputChannels > 0)
+ if (devInfo != NULL)
+ {
+ apiInfo = Pa_GetHostApiInfo(devInfo->hostApi);
+ //api = apiInfo->name;
+ //qDebug() << "Api name: " << apiInfo->name;
+ qDebug() << devInfo->name;
+ //qDebug() << "m_HostAPI: " << m_HostAPI << "devInfo->hostApi: " << new QString(devInfo->hostApi);
+
+ //... and make sure the interface matches the API we've selected.
+ if (m_HostAPI == apiInfo->name)
+ {
+ //qDebug() << "name " << devInfo->name << ", API " << devInfo->hostApi << ", maxOutputChannels: " << devInfo->maxOutputChannels;
+
+ for (int j=1; j <= devInfo->maxOutputChannels; ++j)
+ result.append(QString("%1 (channel %2)").arg(devInfo->name).arg(j));
+ }
+ }
+ }
+ //qDebug() << "PortAudio: getInterfaces() end";
+ return result;
+}
+
+/**
+ * Get the audio input/capture interfaces from PortAudio
+ */
+QStringList PlayerPortAudio::getInputInterfaces()
+{
+ qDebug() << "PortAudio: getInputInterfaces()";
+
+ QStringList result;
+ const PaHostApiInfo * apiInfo = NULL;
+ const PaDeviceInfo * devInfo = NULL;
+ QString api;
+
+ if (m_HostAPI == "None")
+ return result;
+
+ PaDeviceIndex numDevices = Pa_GetDeviceCount();
+
+ for (int i = 0; i < numDevices; i++)
+ {
+ devInfo = Pa_GetDeviceInfo(i);
+
+ // Add the device if it is an input device:
+ //if (devInfo != NULL && devInfo->maxOutputChannels > 0)
+ if (devInfo != NULL && (devInfo->maxInputChannels > 0))
+ {
+ apiInfo = Pa_GetHostApiInfo(devInfo->hostApi);
+ //api = apiInfo->name;
+ qDebug() << "Api name: " << apiInfo->name;
+ qDebug(devInfo->name);
+ //qDebug() << "m_HostAPI: " << m_HostAPI << "devInfo->hostApi: " << new QString(devInfo->hostApi);
+
+ //... and make sure the interface matches the API we've selected.
+ if (m_HostAPI == apiInfo->name )
+ {
+ qDebug() << "name " << devInfo->name << ", API " << devInfo->hostApi << ", maxInputChannels: " << devInfo->maxInputChannels;
+
+ result.append(QString("%1").arg(devInfo->name));
+
+ //for (int j=1; j <= devInfo->maxInputChannels; ++j)
+ // result.append(QString("%1 (channel %2)").arg(devInfo->name).arg(j));
+ }
+ }
+ }
+ qDebug() << "PortAudio: getInputInterfaces() end";
+ return result;
+}
+
+
+QStringList PlayerPortAudio::getSampleRates()
+{
+ // Returns a sorted list of supported sample rates of the currently opened device.
+ // If no device is open, return the list of sample rates supported by the
+ // default device
+ qDebug() << "PortAudio: getSampleRates()";
+
+ PaError err;
+ PaDeviceIndex id = m_devId[0]; //TODO: This is a hack to pick the samplerates from the first soundcard....
+ //Figure out something smarter...
+ //Something smarter = poll the samplerates from both soundcards, and
+ //only display the samlerates that are supported by both. - Albert April 30, 2007
+ //The problem with doing this right now is that Pa_IsFormatSupported when using
+ //ALSA takes ages for some reason, and polling both soundcards here would
+ //double this 5 second freeze that Mixxx experiences because of Pa_IsFormatSupported
+ //(buggily) blocking.
+ //qDebug() << "m_devId[0]: " << m_devId[0];
+ if (id<0)
+ id = Pa_GetDefaultOutputDevice();
+
+ //const PaDeviceInfo *devInfo = Pa_GetDeviceInfo(id);
+
+ PaStreamParameters outputParams;
+ outputParams.device = id;
+ outputParams.channelCount = 2;
+ outputParams.sampleFormat = paFloat32;
+ outputParams.suggestedLatency = .150; //Latency in seconds.
+ outputParams.hostApiSpecificStreamInfo = NULL;
+
+ Q3ValueList desiredSampleRates; //A list of all the sample rates we're going to suggest.
+ Q3ValueList validSampleRates; //A list containing all the supported sample rates.
+
+ //Here's all the sample rates we're going to suggest to PortAudio. We check which ones
+ //are actually supported below.
+ desiredSampleRates.append(11025.0);
+ desiredSampleRates.append(22050.0);
+ desiredSampleRates.append(44100.0);
+ desiredSampleRates.append(48000.0);
+ desiredSampleRates.append(96000.0);
+
+ // Sample rates
+ //if (devInfo)
+ {
+ for (unsigned int j=0; j < desiredSampleRates.count(); j++)
+ {
+ //Check if each sample rate is supported, if so, add them to the list of supported sample rates.
+ qDebug() << "PortAudio: checking if sample rate is supported...";
+ err = Pa_IsFormatSupported(NULL, &outputParams, desiredSampleRates[j]);
+ if (err == paFormatIsSupported) //The format IS supported.
+ {
+ validSampleRates.append(desiredSampleRates[j]);
+ qDebug() << "Supported...";
+ }
+ else
+ {
+ qDebug() << "PortAudio error: " << Pa_GetErrorText(err) << ", id was: " << id;
+ }
+ }
+ }
+
+ //If for some reason our enumeration of the sample rates failed, throw
+ //in some default values. (PortAudio might be being sketchy...)
+ if (validSampleRates.count() == 0)
+ {
+ validSampleRates.append(44100.0);
+ validSampleRates.append(48000.0);
+ validSampleRates.append(96000.0);
+ }
+
+ // Sort list
+#ifndef QT3_SUPPORT
+ qSort(validSampleRates);
+#endif
+
+ // Convert srlist to stringlist
+ QStringList result;
+ for (unsigned int i = 0; i < validSampleRates.count(); ++i)
+ result.append(QString("%1").arg((*validSampleRates.at(i))));
+
+ qDebug() << "PortAudio: getSampleRates() end";
+
+ return result;
+}
+
+QStringList PlayerPortAudio::getSoundApiList()
+{
+ //Note: Need to put the active API at the top of the list.
+ QStringList apiList;
+ const PaHostApiInfo * apiInfo = NULL;
+
+ //We need to initialize PortAudio before we find out what APIs are present.
+ //Even if this gets called while PortAudio is already initialized, the docs
+ //say this is OK (I think...).
+
+ PaError err = paNoError;
+
+ // So this little hackfest saves buggy drivers from being really buggy - AD
+ if (!m_painited) {
+ err = Pa_Initialize();
+ m_painited = true;
+ }
+
+ if (err == paNoError)
+ {
+ for (int i = 0; i < Pa_GetHostApiCount(); i++)
+ {
+ apiInfo = Pa_GetHostApiInfo(i);
+ //qDebug() << "Api name: " << apiInfo->name;
+ apiList.append(apiInfo->name);
+ }
+// Pa_Terminate();
+ }
+ else
+ qDebug() << "PortAudio error: " << Pa_GetErrorText(err);
+
+ return apiList;
+
+ /*
+ #ifdef __LINUX__
+ return QStringList("OSS (PA)");
+ #endif
+ #ifdef __MACX__
+ return QStringList("CoreAudio (PA)");
+ #endif
+ #ifdef __WIN__
+ return QStringList("WMME (PA)");
+ #endif
+ */
+
+}
+
+
+PaDeviceIndex PlayerPortAudio::getDeviceID(QString name)
+{
+ //qDebug() << "PortAudio: getDeviceID(" + name + ")";
+ PaDeviceIndex no = Pa_GetDeviceCount();
+ for (int i=0; imaxOutputChannels > 0)
+ {
+ for (int j = 1; j <= devInfo->maxOutputChannels; ++j)
+ if (QString("%1 (channel %2)").arg(devInfo->name).arg(j) == name)
+ {
+ //qDebug() << "PortAudio: getDeviceID(" + name + "), returning device id " << i;
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+
+PaDeviceIndex PlayerPortAudio::getInputDeviceID(QString name)
+{
+ qDebug() << "PortAudio: getInputDeviceID(" + name + ")";
+ PaDeviceIndex no = Pa_GetDeviceCount();
+ for (int i=0; imaxOutputChannels > 0)
+ {
+ for (int j = 1; j <= devInfo->maxInputChannels; ++j)
+ {
+ //qDebug() << "Comparing: " << QString("%1").arg(devInfo->name);
+ //qDebug() << "and: " << name;
+ if (QString("%1").arg(devInfo->name) == name)
+ {
+ qDebug() << "PortAudio: getInputDeviceID(" + name + "), returning device id " << i;
+ return i;
+ }
+ }
+ }
+ }
+ qDebug() << "PortAudio: getInputDeviceID(" + name + "), returning device id -1";
+ return -1;
+}
+
+PaDeviceIndex PlayerPortAudio::getChannelNo(QString name)
+{
+ PaDeviceIndex no = Pa_GetDeviceCount();
+ for (int i=0; imaxOutputChannels > 0)
+ {
+ for (int j=1; j<=devInfo->maxOutputChannels; ++j)
+ if (QString("%1 (channel %2)").arg(devInfo->name).arg(j) == name)
+ return j;
+ }
+ }
+ return -1;
+}
+
+/** -------- ------------------------------------------------------
+ Purpose: This callback function gets called everytime a soundcard runs out of samples to play.
+ This is where the soundcard/PortAudio ask Mixxx for more samples, and get them in
+ an orderly fashion (*thread safety). This is also where the "routing" of audio samples
+ take place.
+ -------- ------------------------------------------------------
+ */
+int PlayerPortAudio::callbackProcess(unsigned long framesPerBuffer, float * out, short * in, int devIndex)
+{
+ //if (m_iBufferSize==0)
+ // m_iBufferSize = iBufferSize*m_iNumberOfBuffers;
+
+ static float * tmp; //Leave this as static - it's shared between two threads.
+ float * output = out;
+ int i;
+
+ /*
+ if (!out)
+ {
+ qDebug() << "output is NULL!";
+ prevDevice.lock();
+ m_iPreviousDevIndex = devIndex; //Save this devIndex as the previous one
+ prevDevice.unlock();
+ waitForNextOutput.wakeAll(); //Allow the other thread to give at 'er
+ return 0;
+ }*/
+
+ prevDevice.lock();
+ int iPreviousDevIndex = m_iPreviousDevIndex;
+ prevDevice.unlock();
+
+ if (iPreviousDevIndex == devIndex && m_iNumActiveDevices > 1)
+ {
+ lockSamples.lock();
+ waitForNextOutput.wait(&lockSamples);
+ lockSamples.unlock();
+ }
+
+ //Only fill the buffer with sound data from Mixxx once.
+ lockSamples.lock();
+ if (devIndex == 0)
+ {
+ tmp = prepareBuffer(iBufferSize);
+ }
+ lockSamples.unlock();
+
+ // Reset sample for each open channel
+ for (i=0; i=0 && m_iChannels[devIndex]>=1) { output[m_iMasterLeftCh] += tmp[(i*4) ]/32768.;}
+ if (m_iMasterRigthCh>=0 && m_iChannels[devIndex]>=2) output[m_iMasterRigthCh] += tmp[(i*4)+1]/32768.;
+ if (m_iHeadLeftCh>=0 && m_iChannels[devIndex]>=3) output[m_iHeadLeftCh] += tmp[(i*4)+2]/32768.;
+ if (m_iHeadRightCh>=0 && m_iChannels[devIndex]>=4) output[m_iHeadRightCh] += tmp[(i*4)+3]/32768.;
+ }
+ else if (devIndex == 1) //If there's a second sound device, route the headphones to it.
+ {
+ //if (m_iMasterLeftCh>=0 && m_iChannels[devIndex]>=1) { output[m_iMasterLeftCh] += tmp[(i*4) ]/32768.;}
+ //if (m_iMasterRigthCh>=0 && m_iChannels[devIndex]>=2) output[m_iMasterRigthCh] += tmp[(i*4)+1]/32768.;
+ //qDebug() << "m_iHeadLeftCh:" << m_iHeadLeftCh << "devIndex: " << devIndex << "tmp[blah]" << tmp[(i*4)+2]/32768.;
+ if (m_iHeadLeftCh>=0 && m_iChannels[devIndex]>=1) output[m_iHeadLeftCh] += tmp[(i*4)+2]/32768.;
+ if (m_iHeadRightCh>=0 && m_iChannels[devIndex]>=2) output[m_iHeadRightCh] += tmp[(i*4)+3]/32768.;
+ //qDebug() << "headphones!";
+ }
+ for (int j=0; j < m_iChannels[devIndex]; ++j)
+ *output++;
+ }
+
+ if (in)
+ {
+#ifdef __VINYLCONTROL__
+ m_VinylControl[devIndex]->AnalyseSamples(in, iBufferSize);
+#endif
+ }
+
+ prevDevice.lock();
+ m_iPreviousDevIndex = devIndex; //Save this devIndex as the previous one
+ prevDevice.unlock();
+ waitForNextOutput.wakeAll(); //Allow the other thread to give at 'er
+
+ return 0;
+}
+
+
+/* -------- ------------------------------------------------------
+ Purpose: Wrapper function to call processing loop function,
+ implemented as a method in a class. Used in PortAudio,
+ which knows nothing about C++.
+ Input: .
+ Output: -
+ -------- ------------------------------------------------------ */
+int paV19Callback(const void * inputBuffer, void * outputBuffer,
+ unsigned long framesPerBuffer,
+ const PaStreamCallbackTimeInfo * timeInfo,
+ PaStreamCallbackFlags statusFlags,
+ void * _callbackStuff)
+{
+ /*
+ //Variables that are used in the human-readable form of function call from hell (below).
+ static PlayerPortAudio* _player;
+ static int devIndex;
+ _player = ((PAPlayerCallbackStuff*)_callbackStuff)->player;
+ devIndex = ((PAPlayerCallbackStuff*)_callbackStuff)->devIndex;
+ */
+
+ //Human-readable form of the function call from hell:
+ //return _player->callbackProcess(framesPerBuffer, (float *)outputBuffer, devIndex);
+
+ //Function call from hell (might provide a little bit of cheapo thread safety to do it this way):
+ return ((PAPlayerCallbackStuff *)_callbackStuff)->player->callbackProcess(framesPerBuffer, (float *)outputBuffer, (short *)inputBuffer, ((PAPlayerCallbackStuff *)_callbackStuff)->devIndex);
+}
+
diff -Nru mixxx-1.6.0/src/old/playerportaudio.h mixxx-1.6.1/src/old/playerportaudio.h
--- mixxx-1.6.0/src/old/playerportaudio.h 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/playerportaudio.h 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,109 @@
+/***************************************************************************
+ playerportaudiov19.h - description
+ -------------------
+ begin : Wed Feb 20 2002
+ copyright : (C) 2002 by Tue and Ken Haste Andersen
+ email :
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PLAYERPORTAUDIO_H
+#define PLAYERPORTAUDIO_H
+
+#include
+#include
+#include
+#include
+#include "player.h"
+#include "portaudio.h"
+#ifdef __VINYLCONTROL__
+#include "vinylcontrolproxy.h"
+#endif
+
+/**
+ *@author Tue and Ken Haste Andersen
+ */
+
+/** Maximum frame size used with PortAudio. Used to determine no of buffers
+ * when setting latency */
+const int kiMaxFrameSize = 1024;
+
+class PlayerPortAudio; //Forward declaration
+
+/** A struct to some stuff we need to pass along to the callback through PortAudio **/
+struct PAPlayerCallbackStuff
+{
+ PlayerPortAudio* player;
+ int devIndex;
+};
+
+class PlayerPortAudio : public Player {
+public:
+ PlayerPortAudio(ConfigObject *config, QString api_name);
+ ~PlayerPortAudio();
+ bool initialize();
+ bool open();
+ void close();
+ void setDefaults();
+ QStringList getInterfaces();
+ QStringList getInputInterfaces();
+ QStringList getSampleRates();
+ static QStringList getSoundApiList();
+ QString getSoundApiName() { return getSoundApiList().front(); };
+ void calculateNumActiveDevices();
+ /** Satisfy virtual declaration in EngineObject */
+ void process(const CSAMPLE *, const CSAMPLE *, const int) {};
+ /** Process samples. Called from PortAudio callback */
+ int callbackProcess(int iBufferSize, float *out, short *in, int devIndex);
+
+ static bool m_painited;
+protected:
+ /** Get id of device with a given name. Returns -1 if device is not found */
+ PaDeviceIndex getDeviceID(QString name);
+ PaDeviceIndex getInputDeviceID(QString name);
+ /** Get channel number of device with a given name. Returns -1 if device is not found */
+ int getChannelNo(QString name);
+
+ /** PortAudio stream */
+ PaStream *m_pStream[MAX_AUDIODEVICES];
+ /** Id of currently open device. -1 if no device is open */
+ PaDeviceIndex m_devId[MAX_AUDIODEVICES];
+ PaDeviceIndex m_inputDevId[MAX_AUDIODEVICES]; //For input devices
+ /** Channels used for each output from Mixxx. Set to -1 when not in use */
+ int m_iMasterLeftCh, m_iMasterRigthCh, m_iHeadLeftCh, m_iHeadRightCh;
+ /** True if PortAudio was sucessfully initialized */
+ bool m_bInit;
+ /** A struct to hold some information/pointers we need to pass to our callback function */
+ PAPlayerCallbackStuff callbackStuff[MAX_AUDIODEVICES];
+ /** Number of buffers */
+ int m_iNumberOfBuffers;
+ /** Number of active/open soundcards **/
+ int m_iNumActiveDevices;
+ /** Name of the current audio API inside PortAudio **/
+ QString m_HostAPI;
+ /** Mutex so that two threads don't try to prepare a new buffer full of samples from Mixxx at the same time */
+ QMutex lockSamples;
+ /** Wait condition that forces multiple PortAudio callbacks in separate threads to play nicely */
+ QWaitCondition waitForNextOutput;
+ QMutex waitMutex;
+ int m_iPreviousDevIndex;
+ QMutex prevDevice;
+#ifdef __VINYLCONTROL__
+ VinylControlProxy *m_VinylControl[2];
+#endif
+};
+
+int paV19Callback(const void *inputBuffer, void *outputBuffer,
+ unsigned long framesPerBuffer,
+ const PaStreamCallbackTimeInfo* timeInfo,
+ PaStreamCallbackFlags statusFlags,
+ void *_player);
+#endif
diff -Nru mixxx-1.6.0/src/old/playerproxy.cpp mixxx-1.6.1/src/old/playerproxy.cpp
--- mixxx-1.6.0/src/old/playerproxy.cpp 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/playerproxy.cpp 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,189 @@
+/***************************************************************************
+ playerproxy.cpp - description
+ -------------------
+ begin : Fri Nov 21 2003
+ copyright : (C) 2003 by Tue and Ken Haste Andersen
+ email :
+***************************************************************************/
+
+/***************************************************************************
+* *
+* 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. *
+* *
+***************************************************************************/
+
+#include "playerproxy.h"
+
+#ifdef __PORTAUDIO__
+ #include "playerportaudio.h"
+#endif
+#ifdef __JACK__
+ #include "playerjack.h"
+#endif
+#ifdef __RTAUDIO__
+ #include "playerrtaudio.h"
+#endif
+#ifdef __ASIO__
+ #include "playerasio.h"
+#endif
+#ifdef __ALSA__
+ #include "playeralsa.h"
+#endif
+
+Player * PlayerProxy::m_pPlayer = 0;
+
+PlayerProxy::PlayerProxy(ConfigObject * pConfig) : Player(pConfig)
+{
+ // Set API based on info stored in config database
+ setSoundApi(m_pConfig->getValueString(ConfigKey("[Soundcard]","SoundApi")));
+
+ if (!m_pPlayer)
+ {
+ // No valid API is stored in the database, so select the default
+ QStringList api = getSoundApiList();
+ QStringList::iterator it = api.begin();
+ while (!m_pPlayer && it!=api.end())
+ {
+ if (setSoundApi((*it)))
+ {
+ m_pConfig->set(ConfigKey("[Soundcard]","SoundApi"), ConfigValue((*it)));
+ m_pPlayer->setDefaults();
+ }
+ *it++;
+ }
+ }
+}
+
+PlayerProxy::~PlayerProxy()
+{
+ if (m_pPlayer)
+ delete m_pPlayer;
+}
+
+bool PlayerProxy::open()
+{
+ if (m_pPlayer)
+ return m_pPlayer->open();
+ else
+ return false;
+}
+
+void PlayerProxy::close()
+{
+ if (m_pPlayer)
+ m_pPlayer->close();
+}
+
+void PlayerProxy::setDefaults()
+{
+ if (m_pPlayer)
+ m_pPlayer->setDefaults();
+}
+
+QStringList PlayerProxy::getInterfaces()
+{
+ if (m_pPlayer)
+ return m_pPlayer->getInterfaces();
+ else
+ return QStringList();
+}
+
+QStringList PlayerProxy::getInputInterfaces()
+{
+ if (m_pPlayer)
+ return m_pPlayer->getInputInterfaces();
+ else
+ return QStringList();
+}
+
+QStringList PlayerProxy::getSampleRates()
+{
+ if (m_pPlayer)
+ return m_pPlayer->getSampleRates();
+ else
+ return QStringList();
+}
+
+QString PlayerProxy::getSoundApiName()
+{
+ if (m_pPlayer)
+ return m_pPlayer->getSoundApiName();
+ else
+ return QString();
+}
+
+
+QStringList PlayerProxy::getSoundApiList()
+{
+ QStringList result;
+#ifdef __PORTAUDIO__
+ result += PlayerPortAudio::getSoundApiList();
+#endif
+#ifdef __JACK__
+ result.append(PlayerJack::getSoundApi());
+#endif
+#ifdef __RTAUDIO__
+ result.append(PlayerRtAudio::getSoundApi());
+#endif
+#ifdef __ASIO__
+ result.append(PlayerAsio::getSoundApi());
+#endif
+#ifdef __ALSA__
+ result.append(PlayerALSA::getSoundApi());
+#endif
+
+ return result;
+}
+
+bool PlayerProxy::setSoundApi(QString name)
+{
+ if (m_pPlayer)
+ delete m_pPlayer;
+ m_pPlayer = 0;
+
+#ifdef __PORTAUDIO__
+ if (PlayerPortAudio::getSoundApiList().contains(name))
+ m_pPlayer = new PlayerPortAudio(m_pConfig, name);
+#endif
+
+#ifdef __JACK__
+ if (name == PlayerJack::getSoundApi())
+ m_pPlayer = new PlayerJack(m_pConfig);
+#endif
+
+#ifdef __RTAUDIO__
+ if (name == PlayerRtAudio::getSoundApi())
+ m_pPlayer = new PlayerRtAudio(m_pConfig);
+#endif
+
+#ifdef __ASIO__
+ if (name == PlayerAsio::getSoundApi())
+ m_pPlayer = new PlayerAsio(m_pConfig);
+#endif
+
+#ifdef __ALSA__
+ if (name == PlayerALSA::getSoundApi())
+ m_pPlayer = new PlayerALSA(m_pConfig);
+#endif
+
+ // Try initializing the selected API
+ bool init = false;
+ if (m_pPlayer)
+ init = m_pPlayer->initialize();
+
+ if (!init)
+ {
+ if (m_pPlayer)
+ delete m_pPlayer;
+ m_pPlayer = 0;
+ }
+
+ if (m_pPlayer)
+ return true;
+ else
+ return false;
+}
+
diff -Nru mixxx-1.6.0/src/old/playerproxy.h mixxx-1.6.1/src/old/playerproxy.h
--- mixxx-1.6.0/src/old/playerproxy.h 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/playerproxy.h 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,54 @@
+/***************************************************************************
+ playerproxy.h - description
+ -------------------
+ begin : Fri Nov 21 2003
+ copyright : (C) 2003 by Tue Haste Andersen
+ email :
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PLAYERPROXY_H
+#define PLAYERPROXY_H
+
+#include "player.h"
+
+class PlayerProxy : public Player
+{
+public:
+ PlayerProxy(ConfigObject *pConfig);
+ ~PlayerProxy();
+ bool initialize() { return false; };
+ bool open();
+ void close();
+ void setDefaults();
+ QStringList getInterfaces();
+ QStringList getInputInterfaces();
+ QStringList getSampleRates();
+ QString getSoundApiName();
+ /** Return list of supported sound api's */
+ static QStringList getSoundApiList();
+ /** Select active sound api */
+ bool setSoundApi(QString name);
+ /** Satisfy virtual declaration in EngineObject */
+ void process(const CSAMPLE *, const CSAMPLE *, const int) {};
+ /** Static function to return active player class. Needed for ASIO implementation */
+ static Player *getPlayer() { return m_pPlayer; }
+
+protected:
+ /** Pointer to active Player class */
+ static Player *m_pPlayer;
+};
+
+#endif
+
+
+
+
diff -Nru mixxx-1.6.0/src/old/playerrtaudio.cpp mixxx-1.6.1/src/old/playerrtaudio.cpp
--- mixxx-1.6.0/src/old/playerrtaudio.cpp 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/playerrtaudio.cpp 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,442 @@
+/***************************************************************************
+ playerrtaudio.cpp - description
+ -------------------
+ begin : Thu May 20 2004
+ copyright : (C) 2002 by Tue and Ken Haste Andersen
+ email :
+***************************************************************************/
+
+/***************************************************************************
+* *
+* 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. *
+* *
+***************************************************************************/
+
+#include "playerrtaudio.h"
+#include "controlobject.h"
+
+/** Maximum frame size used with RtAudio. Used to determine no of buffers
+ * when setting latency */
+const int kiMaxFrameSize = 64;
+
+
+PlayerRtAudio::PlayerRtAudio(ConfigObject * config) : Player(config)
+{
+ m_pRtAudio = 0;
+ m_bInit = false;
+
+ m_devId = -1;
+ m_iNumberOfBuffers = 2;
+ m_iChannels = -1;
+ m_iMasterLeftCh = -1;
+ m_iMasterRigthCh = -1;
+ m_iHeadLeftCh = -1;
+ m_iHeadRightCh = -1;
+}
+
+PlayerRtAudio::~PlayerRtAudio()
+{
+ if (m_devId>=1)
+ {
+ try {
+ m_pRtAudio->stopStream();
+ m_pRtAudio->closeStream();
+ }
+ catch (RtError &error)
+ {
+ error.printMessage();
+ }
+ }
+
+ if (m_bInit)
+ delete m_pRtAudio;
+}
+
+bool PlayerRtAudio::initialize()
+{
+ try {
+ m_pRtAudio = new RtAudio();
+ }
+ catch (RtError &error)
+ {
+ error.printMessage();
+ m_pRtAudio = 0;
+ m_bInit = false;
+ }
+ m_bInit = true;
+
+ return m_bInit;
+}
+
+bool PlayerRtAudio::open()
+{
+ Player::open();
+
+ // Find out which device to open. Select the first one listed as either Master Left,
+ // Master Right, Head Left, Head Right. If other devices are requested for opening
+ // than the one selected here, set them to "None" in the config database
+ int id = -1;
+ int temp = -1;
+ QString name;
+ /** Maximum number of channels needed */
+ int iChannelMax = -1;
+
+ m_iMasterLeftCh = -1;
+ m_iMasterRigthCh = -1;
+ m_iHeadLeftCh = -1;
+ m_iHeadRightCh = -1;
+
+ // Master left
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterLeft"));
+ temp = getDeviceID(name);
+ if (temp>=0)
+ {
+ if (getChannelNo(name)>=0)
+ {
+ id = temp;
+ iChannelMax = getChannelNo(name);
+ m_iMasterLeftCh = getChannelNo(name)-1;
+ }
+ }
+
+ // Master right
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterRight"));
+ temp = getDeviceID(name);
+ if (getChannelNo(name)>=0 && ((id==-1 && temp>=0) || (temp!=-1 && id==temp)))
+ {
+ id = temp;
+ iChannelMax = math_max(iChannelMax, getChannelNo(name));
+ m_iMasterRigthCh = getChannelNo(name)-1;
+ }
+
+ // Head left
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceHeadLeft"));
+ temp = getDeviceID(name);
+ if (getChannelNo(name)>=0 && ((id==-1 && temp>=0) || (temp!=-1 && id==temp)))
+ {
+ id = temp;
+ iChannelMax = math_max(iChannelMax, getChannelNo(name));
+ m_iHeadLeftCh = getChannelNo(name)-1;
+ }
+
+ // Head right
+ name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceHeadRight"));
+ temp = getDeviceID(name);
+ if (getChannelNo(name)>=0 && ((id==-1 && temp>=0) || (temp!=-1 && id==temp)))
+ {
+ id = temp;
+ iChannelMax = math_max(iChannelMax, getChannelNo(name));
+ m_iHeadRightCh = getChannelNo(name)-1;
+ }
+
+ // Check if any of the devices in the config database needs to be set to "None"
+ if (m_iMasterLeftCh<0)
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
+ if (m_iMasterRigthCh<0)
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
+ if (m_iHeadLeftCh<0)
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
+ if (m_iHeadRightCh<0)
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
+
+ // Number of channels to open
+ int iChannels = iChannelMax;
+
+ // Sample rate
+ int iSrate = m_pConfig->getValueString(ConfigKey("[Soundcard]","Samplerate")).toInt();
+
+ // Get latency in msec
+ int iLatencyMSec = m_pConfig->getValueString(ConfigKey("[Soundcard]","Latency")).toInt();
+
+ // Latency in samples
+ int iLatencySamples = (int)((float)(iSrate*iChannels)/1000.f*(float)iLatencyMSec);
+
+ // Apply simple rule to determine number of buffers
+ if (iLatencySamples/kiMaxFrameSize<2)
+ m_iNumberOfBuffers = 2;
+ else
+ m_iNumberOfBuffers = iLatencySamples/kiMaxFrameSize;
+
+ // Frame size...
+ int iFramesPerBuffer = iLatencySamples/m_iNumberOfBuffers;
+
+ qDebug() << "RtAudio: id " << id << ", sr " << iSrate << ", ch " << iChannels << ", bufsize " << iFramesPerBuffer << ", bufno " << m_iNumberOfBuffers;
+
+ if (id<1)
+ {
+ m_devId = -1;
+ return false;
+ }
+
+ // Start playback
+ try
+ {
+ // Update SRATE and Latency ControlObjects
+ m_pControlObjectSampleRate->queueFromThread((double)iSrate);
+ m_pControlObjectLatency->queueFromThread((double)iLatencyMSec);
+
+ // Open stream
+ m_pRtAudio->openStream(id, iChannels, 0, 0, RTAUDIO_FLOAT32, iSrate, &iFramesPerBuffer, m_iNumberOfBuffers);
+
+ // Set callback function
+ m_pRtAudio->setStreamCallback(&rtCallback, (void *)this);
+
+ m_iChannels = iChannels;
+ m_devId = id;
+
+ // Start playback
+ m_pRtAudio->startStream();
+ }
+ catch (RtError &error)
+ {
+ error.printMessage();
+
+ m_devId = -1;
+ m_iChannels = -1;
+
+ return false;
+ }
+
+ return true;
+}
+
+void PlayerRtAudio::close()
+{
+ m_iChannels = 0;
+ m_iMasterLeftCh = -1;
+ m_iMasterRigthCh = -1;
+ m_iHeadLeftCh = -1;
+ m_iHeadRightCh = -1;
+
+ if (m_devId>0)
+ {
+ qDebug() << "close";
+ try
+ {
+ m_pRtAudio->stopStream();
+ m_pRtAudio->closeStream();
+ }
+ catch (RtError &error)
+ {
+ error.printMessage();
+ }
+ }
+ m_devId = -1;
+}
+
+void PlayerRtAudio::setDefaults()
+{
+ // Get list of interfaces
+ QStringList interfaces = getInterfaces();
+
+ // Set first interfaces to master left
+ QStringList::iterator it = interfaces.begin();
+ if (it!=interfaces.end())
+ {
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue((*it)));
+ }
+ else
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
+
+ // Set second interface to master right
+ ++it;
+ if (it!=interfaces.end())
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue((*it)));
+ else
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
+
+ // Set head left and right to none
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
+ m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
+
+ // Set default sample rate
+ QStringList srates = getSampleRates();
+ it = srates.begin();
+ while (it!=srates.end())
+ {
+ m_pConfig->set(ConfigKey("[Soundcard]","Samplerate"),ConfigValue((*it)));
+
+ if ((*it).toInt()>=44100)
+ break;
+
+ ++it;
+ }
+
+ // Set currently used latency in config database
+ int msec = (int)(1000.*(2.*1024.)/(2.*(float)(*it).toInt()));
+ m_pConfig->set(ConfigKey("[Soundcard]","Latency"), ConfigValue(msec));
+}
+
+QStringList PlayerRtAudio::getInterfaces()
+{
+ QStringList result;
+
+ int no = m_pRtAudio->getDeviceCount();
+ RtAudioDeviceInfo info;
+ for (int i=1; i<=no; i++)
+ {
+ bool bGotInfo = false;
+ try {
+ info = m_pRtAudio->getDeviceInfo(i);
+ bGotInfo = true;
+ }
+ catch (RtError &error)
+ {
+ error.printMessage();
+ }
+
+ // Add the device if it is an output device:
+ if (bGotInfo && info.outputChannels > 0)
+ {
+ qDebug() << "name " << info.name.c_str();
+ for (int j=1; j<=info.outputChannels; ++j)
+ result.append(QString("%1 (channel %2)").arg(info.name.c_str()).arg(j));
+ }
+ }
+
+ return result;
+}
+
+QStringList PlayerRtAudio::getSampleRates()
+{
+ // Returns the list of supported sample rates of the currently opened device.
+ // If no device is open, return the list of sample rates supported by the
+ // default device
+ int id = m_devId;
+ if (id<1)
+ id = 1;
+
+ RtAudioDeviceInfo info;
+ try {
+ info = m_pRtAudio->getDeviceInfo(id);
+ }
+ catch (RtError &error)
+ {
+ error.printMessage();
+ return QStringList();
+ }
+
+ // Sample rates
+ QValueList srlist;
+
+ if (info.sampleRates.size() > 0)
+ {
+ for (unsigned int j=0; jgetDeviceCount();
+ for (int i=1; i<=no; i++)
+ {
+ RtAudioDeviceInfo info;
+ try {
+ info = m_pRtAudio->getDeviceInfo(i);
+ }
+ catch (RtError &error)
+ {
+ error.printMessage();
+ return -1;
+ }
+
+ // Add the device if it is an output device:
+ if (info.outputChannels > 0)
+ {
+ for (int j=1; j<=info.outputChannels; ++j)
+ if (QString("%1 (channel %2)").arg(info.name.c_str()).arg(j) == name)
+ return i;
+ }
+ }
+ return -1;
+}
+
+int PlayerRtAudio::getChannelNo(QString name)
+{
+ int no = m_pRtAudio->getDeviceCount();
+ for (int i=1; i<=no; i++)
+ {
+ RtAudioDeviceInfo info;
+ try {
+ info = m_pRtAudio->getDeviceInfo(i);
+ }
+ catch (RtError &error)
+ {
+ error.printMessage();
+ return -1;
+ }
+
+ // Add the device if it is an output device:
+ if (info.outputChannels > 0)
+ {
+ for (int j=1; j<=info.outputChannels; ++j)
+ if (QString("%1 (channel %2)").arg(info.name.c_str()).arg(j) == name)
+ return j;
+ }
+ }
+ return -1;
+}
+
+int PlayerRtAudio::callbackProcess(int iBufferSize, float * out)
+{
+ //m_iBufferSize = iBufferSize*m_iNumberOfBuffers;
+
+ float * tmp = prepareBuffer(iBufferSize);
+ float * output = out;
+ int i;
+
+ // Reset sample for each open channel
+ for (i=0; i=0) output[m_iMasterLeftCh] += tmp[(i*4) ]/32768.;
+ if (m_iMasterRigthCh>=0) output[m_iMasterRigthCh] += tmp[(i*4)+1]/32768.;
+ if (m_iHeadLeftCh>=0) output[m_iHeadLeftCh] += tmp[(i*4)+2]/32768.;
+ if (m_iHeadRightCh>=0) output[m_iHeadRightCh] += tmp[(i*4)+3]/32768.;
+
+ for (int j=0; jcallbackProcess(framesPerBuffer, (float *)outputBuffer);
+}
diff -Nru mixxx-1.6.0/src/old/playerrtaudio.h mixxx-1.6.1/src/old/playerrtaudio.h
--- mixxx-1.6.0/src/old/playerrtaudio.h 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/old/playerrtaudio.h 2008-08-11 05:02:03.000000000 -0500
@@ -0,0 +1,65 @@
+/***************************************************************************
+ playerrtaudio.h - description
+ -------------------
+ begin : Thu May 20 2004
+ copyright : (C) 2002 by Tue and Ken Haste Andersen
+ email :
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PLAYERRTAUDIO_H
+#define PLAYERRTAUDIO_H
+
+#include "player.h"
+#include
+
+/**
+ *@author Tue and Ken Haste Andersen
+ */
+
+
+class PlayerRtAudio : public Player {
+public:
+ PlayerRtAudio(ConfigObject *config);
+ ~PlayerRtAudio();
+ bool initialize();
+ bool open();
+ void close();
+ void setDefaults();
+ QStringList getInterfaces();
+ QStringList getSampleRates();
+ static QString getSoundApi();
+ QString getSoundApiName() { return getSoundApi(); };
+ /** Satisfy virtual declaration in EngineObject */
+ void process(const CSAMPLE *, const CSAMPLE *, const int) {};
+ /** Process samples. Called from RtAudio callback */
+ int callbackProcess(int iBufferSize, float *out);
+
+protected:
+ /** Pointer to RtAudio object */
+ RtAudio *m_pRtAudio;
+ /** Get id of device with a given name. Returns -1 if device is not found */
+ int getDeviceID(QString name);
+ /** Get channel number of device with a given name. Returns -1 if device is no found */
+ int getChannelNo(QString name);
+ /** Id of currently open device. -1 if no device is open */
+ int m_devId;
+ /** Channels used for each output from Mixxx. Set to -1 when not in use */
+ int m_iMasterLeftCh, m_iMasterRigthCh, m_iHeadLeftCh, m_iHeadRightCh;
+ /** True if RtAudio was sucessfully initialized */
+ bool m_bInit;
+ /** Number of buffers */
+ int m_iNumberOfBuffers;
+};
+
+int rtCallback(char *outputBuffer, int framesPerBuffer, void *_player);
+
+#endif
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/osx/VolumeIcon.icns and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/osx/VolumeIcon.icns differ
diff -Nru mixxx-1.6.0/src/playeralsa.cpp mixxx-1.6.1/src/playeralsa.cpp
--- mixxx-1.6.0/src/playeralsa.cpp 2008-03-27 00:04:43.000000000 -0500
+++ mixxx-1.6.1/src/playeralsa.cpp 1969-12-31 18:00:00.000000000 -0600
@@ -1,757 +0,0 @@
-/***************************************************************************
- playeralsa.cpp - description
- -------------------
- begin : Wed Feb 20 2002
- copyright : (C) 2002 by Tue and Ken Haste Andersen
- email :
-***************************************************************************/
-
-/***************************************************************************
-* *
-* 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. *
-* *
-***************************************************************************/
-
-#include "playeralsa.h"
-#include "controlobject.h"
-
-#ifndef PLAYERTEST
-#include "rtthread.h"
-#endif
-
-// Tutorials /home/peter/pad-alsa-audio.html /home/peter/alsa090_howto.html
-// Docs /usr/share/doc/alsa-lib-1.0.4/doxygen/html/index.html
-// Example /usr/share/doc/alsa-lib-1.0.4/doxygen/html/_2test_2pcm_8c-example.html
-// QT /usr/share/doc/qt-devel-3.1.1/html/index.html
-
-/** Maximum frame size used with ALSA. Used to determine no of buffers
- * * when setting latency */
-const int kiMaxFrameSize = 512;
-
-
-#ifndef PLAYERTEST
-PlayerALSA::PlayerALSA(ConfigObject * config) : Player(config)
-#else
-PlayerALSA::PlayerALSA()
-#endif
-{
- int err;
-
- handle = 0;
- err = snd_pcm_hw_params_malloc(&hwparams);
- if (err < 0)
- qCritical("Couldn't allocate memory for hw params: %s\n", snd_strerror(err));
-
- err = snd_pcm_sw_params_malloc(&swparams);
- if (err < 0)
- qCritical("Couldn't allocate memory for sw params: %s\n", snd_strerror(err));
-
- err = snd_pcm_sw_params_malloc(&swparams);
- if (err < 0)
- qCritical("Couldn't allocate memory for sw params: %s\n", snd_strerror(err));
-
- isopen = false;
- masterleft = masterright = -1;
- headleft = headright = -1;
- twrite = false;
- m_iChannels = alsa_channels;
- qDebug() << "Alsa constructed";
-}
-
-PlayerALSA::~PlayerALSA()
-{
- if (isopen) close();
-
- qDebug() << "Alsa destroying...";
- if (hwparams)
- {
- snd_pcm_hw_params_free(hwparams);
- }
- if (swparams)
- {
- snd_pcm_sw_params_free(swparams);
- }
- qDebug() << "Alsa destroyed";
-}
-
-bool PlayerALSA::initialize()
-{
- qDebug() << "Alsa initialized";
-
- return true;
-}
-
-bool PlayerALSA::open()
-{
-#ifndef PLAYERTEST
- Player::open();
-#endif
- QString name;
- QString devname, devtmp;
- int err;
-
-#ifndef PLAYERTEST
- QRegExp rx("(\\S+) \\(ch (\\d+)\\)");
-
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]", "DeviceMasterLeft"));
- if (name != "None")
- {
- if (rx.search(name) < 0)
- qWarning() << "can't find device name or channel number in" << name;
-
- devname = rx.cap(1);
- }
- else
- {
- setDefaults(); // initialise defaults
- return open();
- }
-#else
- devname = QString("surround40:0");
-#endif
-
- // If no device was selected return false
- if (!devname)
- return false;
-
- qDebug() << "Alsa opening pcm_open:" << devname;
-
- if ((err = snd_pcm_open(&handle, devname.ascii(),
- SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
- // AD: Try for default device instead
- if ((err = snd_pcm_open(&handle, "default",
- SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
- qWarning("Playback open error: %s\n", snd_strerror(err));
- return false;
- } else {
- qWarning("Using default ALSA device, you may want to set up a ~/.asoundrc to enable all the features of your sound card");
- }
- }
-
- qDebug() << "Alsa setting hw";
- if ((err = set_hwparams()) < 0)
- {
- qWarning("Setting of hwparams failed: %s\n", snd_strerror(err));
- snd_pcm_close(handle);
- return false;
- }
-
- qDebug() << "Alsa setting sw";
- if ((err = set_swparams()) < 0)
- {
- qWarning("Setting of swparams failed: %s\n", snd_strerror(err));
- snd_pcm_close(handle);
- return false;
- }
-
- masterleft = masterright = -1;
- headleft = headright = -1;
-
-#ifndef PLAYERTEST
- int temp;
-
- // master left
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]", "DeviceMasterLeft"));
- qDebug() << "Alsa opening..." << name;
- if (name != "None")
- {
- if (rx.search(name) < 0)
- {
- qWarning() << "can't find device name or channel number in" << name;
- }
-// devname = rx.cap(1);
- temp = rx.cap(2).toInt();
- if (temp > 0 && temp <= m_iChannels)
- {
- masterleft = temp - 1;
- }
- }
- qDebug() << "Alsa opening...ML " << masterleft;
-
- // master right
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]", "DeviceMasterRight"));
- if (name != "None")
- {
- if (rx.search(name) < 0)
- {
- qWarning() << "can't find device name or channel number in" << name;
- }
- devtmp = rx.cap(1);
- if (devname != devtmp)
- {
- qWarning("device name mismatch, only one device supported");
- }
- temp = rx.cap(2).toInt();
- if (temp > 0 && temp <= m_iChannels)
- {
- masterright = temp - 1;
- }
- }
- qDebug() << "Alsa opening...MR " << masterright;
-
- // head left
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]", "DeviceHeadLeft"));
- if (name != "None")
- {
- if (rx.search(name) < 0)
- {
- qWarning() << "can't find device name or channel number in" << name;
- }
- devtmp = rx.cap(1);
- if (devname != devtmp)
- {
- qWarning("device name mismatch, only one device supported");
- }
- temp = rx.cap(2).toInt();
- if (temp > 0 && temp <= m_iChannels)
- {
- headleft = temp - 1;
- }
- }
- qDebug() << "Alsa opening...HL " << headleft;
-
- // head right
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]", "DeviceHeadRight"));
- if (name != "None")
- {
- if (rx.search(name) < 0)
- {
- qWarning() << "can't find device name or channel number in" << name;
- }
- devtmp = rx.cap(1);
- if (devname != devtmp)
- {
- qWarning("device name mismatch, only one device supported");
- }
- temp = rx.cap(2).toInt();
- if (temp > 0 && temp <= m_iChannels)
- {
- headright = temp - 1;
- }
- }
-
- qDebug() << "Alsa opening...HR " << headright;
- // Check if any of the devices in the config database needs to be set to "None"
- if (masterleft < 0)
- m_pConfig->set(ConfigKey("[Soundcard]", "DeviceMasterLeft"), ConfigValue("None"));
- if (masterright < 0)
- m_pConfig->set(ConfigKey("[Soundcard]", "DeviceMasterRight"), ConfigValue("None"));
- if (headleft < 0)
- m_pConfig->set(ConfigKey("[Soundcard]", "DeviceHeadLeft"), ConfigValue("None"));
- if (headright < 0)
- m_pConfig->set(ConfigKey("[Soundcard]", "DeviceHeadRight"), ConfigValue("None"));
-
-#else
- masterleft = 0;
- masterright = 1;
- headleft = 2;
- headright = 3;
-#endif
-
- twrite = true;
- isopen = true;
-
- QThread::start();
-
- return true;
-}
-
-/*
- * Underrun and suspend recovery
- */
-int PlayerALSA::xrun_recovery(int err)
-{
- if (err == -EPIPE) { /* under-run */
- err = snd_pcm_prepare(handle);
- if (err < 0)
- qWarning("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err));
- return 0;
- }
- else if (err == -ESTRPIPE)
- {
- while ((err = snd_pcm_resume(handle)) == -EAGAIN)
- sleep(1);/* wait until the suspend flag is released */
- if (err < 0)
- {
- err = snd_pcm_prepare(handle);
- if (err < 0)
- qWarning("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err));
- }
- return 0;
- }
- return err;
-}
-
-/**
- * thread for writing samples out
- */
-void PlayerALSA::run()
-{
- CSAMPLE * sptr;
- int err, ctr;
-
-#ifndef PLAYERTEST
- rtThread();
-#endif
-
- if (isformatfloat) {
- float * optr, * output;
-
- output = new float[buffer_size * m_iChannels];
- qDebug() << "Alsa allocating output buffer (FLOAT) " << output;
-
- while (twrite)
- {
- sptr = prepareBuffer((int) period_size);
- optr = output;
- for (int i = 0; i < (int) period_size; i++)
- {
- for (int j = 0; j < m_iChannels; j++) optr[j] = 0;
- if (masterleft >= 0) optr[masterleft] = *sptr / 32768.;
- sptr++;
- if (masterright >= 0) optr[masterright] = *sptr / 32768.;
- sptr++;
- if (headleft >= 0) optr[headleft] = *sptr / 32768.;
- sptr++;
- if (headright >= 0) optr[headright] = *sptr / 32768.;
- sptr++;
- optr += m_iChannels;
- }
- ctr = period_size;
- optr = output;
- while (ctr > 0)
- {
- err = snd_pcm_writei(handle, optr, ctr);
- if (err == -EAGAIN) continue;
- if (err < 0)
- {
- if (xrun_recovery(err) < 0)
- qCritical("Write error: %s\n", snd_strerror(err));
-
- break;
- }
- optr += err*m_iChannels;
- ctr -= err;
- }
- }
- if (output)
- delete output;
- }
- else
- {
- short int * optr, * output;
-
- output = new short int[buffer_size * m_iChannels];
- qDebug() << "Alsa allocating output buffer (S16) " << output;
-
- while (twrite)
- {
- sptr = prepareBuffer((int) period_size);
- optr = output;
- for (int i = 0; i < (int) period_size; i++)
- {
- for (int j = 0; j < m_iChannels; j++) optr[j] = 0;
- if (masterleft >= 0) optr[masterleft] = (short int) *sptr;
- sptr++;
- if (masterright >= 0) optr[masterright] = (short int) *sptr;
- sptr++;
- if (headleft >= 0) optr[headleft] = (short int) *sptr;
- sptr++;
- if (headright >= 0) optr[headright] = (short int) *sptr;
- sptr++;
- optr += m_iChannels;
- }
- ctr = period_size;
- optr = output;
- while (ctr > 0)
- {
- err = snd_pcm_writei(handle, optr, ctr);
- if (err == -EAGAIN) continue;
- if (err < 0)
- {
- if (xrun_recovery(err) < 0)
- qCritical("Write error: %s\n", snd_strerror(err));
- break;
- }
- optr += err*m_iChannels;
- ctr -= err;
- }
- }
- if (output) delete output;
- }
- qDebug() << "Alsa leaving thread";
-}
-
-#ifdef PLAYERTEST
-/**
- * generate a middle A slowly shifting across the channels
- */
-CSAMPLE * PlayerALSA::prepareBuffer(int count)
-{
- const double freq = 440.;
- const unsigned int rate = 44100;
- static CSAMPLE * out = 0;
-
- static double phase = 0;
- double max_phase = 1.0 / freq;
- double step = 1.0 / (double) rate;
- double res;
- CSAMPLE * sptr;
- int chn;
- static int channel = 0;
- static int ccount = 0;
-
- if (out == 0)
- out = new CSAMPLE[80000];
- sptr = out;
- while (count-- > 0)
- {
- res = 32768. * sin((phase * 2 * M_PI) / max_phase - M_PI);
- for (chn = 0; chn < alsa_channels; chn++)
- {
- if (chn == channel)
- *sptr = res;
- else
- *sptr = 0;
- sptr++;
- }
- phase += step;
- if (phase >= max_phase)
- {
- phase -= max_phase;
- ccount++;
- if (ccount == (3 * 440))
- {
- ccount = 0;
- channel++;
- if (channel == alsa_channels) channel = 0;
- }
- }
- }
- return out;
-}
-#endif
-
-void PlayerALSA::close()
-{
- if (!isopen)
- return;
-
- qDebug() << "Alsa closing";
- twrite = false;
- qDebug() << "Alsa waiting for thread for close";
- QThread::wait();
-
- snd_pcm_drop(handle);
- snd_pcm_close(handle);
-
- isopen = false;
-}
-
-void PlayerALSA::setDefaults()
-{
- qDebug() << "Alsa setdefs";
-#ifndef PLAYERTEST
- // Get list of interfaces
- QStringList interfaces = getInterfaces();
-
- // Set first interfaces to master left
- QStringList::iterator it = interfaces.begin();
- if (*it)
- m_pConfig->set(ConfigKey("[Soundcard]", "DeviceMasterLeft"), ConfigValue((*it)));
- else
- m_pConfig->set(ConfigKey("[Soundcard]", "DeviceMasterLeft"), ConfigValue("None"));
-
- // Set second interface to master right
- ++it;
- if (*it)
- m_pConfig->set(ConfigKey("[Soundcard]", "DeviceMasterRight"), ConfigValue((*it)));
- else
- m_pConfig->set(ConfigKey("[Soundcard]", "DeviceMasterRight"), ConfigValue("None"));
-
- // Set head left and right to none
- m_pConfig->set(ConfigKey("[Soundcard]", "DeviceHeadLeft"), ConfigValue("None"));
- m_pConfig->set(ConfigKey("[Soundcard]", "DeviceHeadRight"), ConfigValue("None"));
-
- // Set default sample rate
- QStringList srates = getSampleRates();
- it = srates.begin();
- while (*it)
- {
- m_pConfig->set(ConfigKey("[Soundcard]", "Samplerate"), ConfigValue((*it)));
- if ((*it).toInt() >= 44100)
- break;
- ++it;
- }
-
- // Set currently used latency in config database
- m_pConfig->set(ConfigKey("[Soundcard]", "Latency"), ConfigValue(default_latency));
-#endif
-}
-
-QStringList PlayerALSA::getInterfaces()
-{
- qDebug() << "Alsa getinter";
- QStringList result;
-
- result.append("mixxx (ch 1)");
- result.append("mixxx (ch 2)");
- result.append("mixxx (ch 3)");
- result.append("mixxx (ch 4)");
-
- return result;
-}
-
-QStringList PlayerALSA::getSampleRates()
-{
- qDebug() << "Alsa getsample";
- QStringList result;
- result.append("11025");
- result.append("22050");
- result.append("44100");
- result.append("48000");
- return result;
-}
-
-QString PlayerALSA::getSoundApi()
-{
- qDebug() << "Alsa getapi";
- return QString("Alsa");
-}
-
-int PlayerALSA::set_hwparams()
-{
- unsigned int rate, rrate;
- unsigned int buffer_time = 500000; /* ring buffer length in us */
- unsigned int period_time = 100000; /* period time in us */
-
- int err, dir;
-
- /* choose all parameters */
- err = snd_pcm_hw_params_any(handle, hwparams);
- if (err < 0)
- {
- qWarning("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
- return err;
- }
- /* set the interleaved read/write format */
- err = snd_pcm_hw_params_set_access(handle, hwparams, alsa_access);
- if (err < 0)
- {
- qWarning("Access type not available for playback: %s\n", snd_strerror(err));
- return err;
- }
- /* set the sample format */
- err = snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_FLOAT);
- if (err < 0)
- {
- qWarning("Sample format (FLOAT) not available for playback: %s\n", snd_strerror(err));
- qWarning("Falling back to S16");
- err = snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_S16);
- if (err < 0)
- {
- qWarning("Sample format (S16) not available for playback: %s\n", snd_strerror(err));
- return err;
- }
- isformatfloat = false;
- } else {
- isformatfloat = true;
- }
-
- /* find min and max number of channels */
- err = snd_pcm_hw_params_get_channels_min(hwparams, &rate);
- if (err < 0)
- {
- qWarning("Channels count (%i) not available for playbacks: %s\n", rate, snd_strerror(err));
- }
- qDebug() << "Channels min " << rate;
- err = snd_pcm_hw_params_get_channels_max(hwparams, &rate);
- if (err < 0)
- {
- qWarning("Channels count (%i) not available for playbacks: %s\n", rate, snd_strerror(err));
- }
- qDebug() << "Channels max " << rate;
- m_iChannels = math_min(rate, alsa_channels);
- qDebug() << "Set channels = " << m_iChannels;
-
- /* set the count of channels */
- err = snd_pcm_hw_params_set_channels(handle, hwparams, m_iChannels);
- if (err < 0)
- {
- qWarning("Channels count (%i) not available for playbacks: %s\n", m_iChannels, snd_strerror(err));
- return err;
- }
- /* set the stream rate */
-#ifndef PLAYERTEST
- rate = m_pConfig->getValueString(ConfigKey("[Soundcard]", "Samplerate")).toUInt();
-#else
- rate = 44100;
-#endif
- rrate = rate;
- err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rrate, 0);
- if (err < 0)
- {
- qWarning("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
- return err;
- }
- if (rrate != rate)
- {
- qWarning("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
- return -EINVAL;
- }
-
-#ifndef PLAYERTEST
-// setPlaySrate(rrate);
-// m_pControlObjectSampleRate->queueFromThread((double)rrate);
-
- // Update SRATE and Latency ControlObjects
- m_pControlObjectSampleRate->queueFromThread((double)rrate);
-// m_pControlObjectLatency->queueFromThread((double)iLatencyMSec);
-//
-#endif
-
- /* set the buffer time */
-#ifndef PLAYERTEST
- buffer_time = m_pConfig->getValueString(ConfigKey("[Soundcard]", "Latency")).toUInt() * 1000;
-#else
- buffer_time = 50000;
-#endif
- /* figure out size and make it even */
- buffer_size = (int) rrate*(1e-6*buffer_time) + 1;
-
- snd_pcm_uframes_t max = 0;
- snd_pcm_uframes_t min = 0;
-
- // FIXME: Should check return values to be on the safe side
- snd_pcm_hw_params_get_buffer_size_max(hwparams, &max);
- snd_pcm_hw_params_get_buffer_size_min(hwparams, &min);
- qDebug() << "Allowed buffer size range: " << min << "i -> " << max << "i";
-
- // Make sure buffer size we're aiming for is really allowed
- if (buffer_size < min) { buffer_size = (int)min; }
- if (buffer_size > max) { buffer_size = (int)max; }
-
- buffer_size -= (buffer_size & 1);
-
- if (buffer_size < min) { buffer_size += 2; }
-
- /* test buffer size first */
- err = snd_pcm_hw_params_test_buffer_size(handle, hwparams, buffer_size);
- if (err < 0) {
- qWarning("Unable to test buffer size %d", buffer_size);
- return err;
- }
- err = snd_pcm_hw_params_set_buffer_size(handle, hwparams, buffer_size);
- if (err < 0)
- {
- qWarning("Unable to set buffer size for playback: %s\n", snd_strerror(err));
- return err;
- }
- qWarning("Buffer %dus [actual %dus] (size: %d)", (int) buffer_time, (int) (1e6*buffer_size/rrate), buffer_size);
-
- /*
- * work out maximum number of periods so that only kiMaxFrameSize is
- * written out at a time, then use this as a starting point to find
- * period that works
- */
- int period_no_start = 2;
-
- if (buffer_size/kiMaxFrameSize>2)
- period_no_start = buffer_size/kiMaxFrameSize;
-
- for (period_no = period_no_start; period_no > 1; period_no--)
- {
- unsigned int period_time = buffer_time / period_no;
- qWarning("Period %dus (no: %d)", (int) period_time, period_no);
-
- int dir = 0;
- err = snd_pcm_hw_params_test_periods(handle, hwparams, period_no, dir);
- if (err < 0)
- {
- qWarning("Unable to test periods %i (dir %d) for playback: %s\n", period_no, dir,
- snd_strerror(err));
- }
- else
- {
- err = snd_pcm_hw_params_set_periods(handle, hwparams, period_no, dir);
- if (err < 0)
- {
- qWarning("Unable to set periods %i for playback: %s\n", period_no, snd_strerror(err));
- return err;
- }
- err = snd_pcm_hw_params_get_period_size(hwparams, &period_size, &dir);
- if (err < 0)
- {
- qWarning("Unable to get period size for playback: %s\n", snd_strerror(err));
- return err;
- }
- qWarning("Period %df, buffer %df", (int) period_size, (int) buffer_size);
- break;
- }
- }
-
- if (period_no == 1)
- return -1;
-
- /* write the parameters to device */
- err = snd_pcm_hw_params(handle, hwparams);
- if (err < 0)
- {
- qWarning("Unable to set hw params for playback: %s\n", snd_strerror(err));
- return err;
- }
- qWarning("Rate: %d, buf %df (%dus), per %df (%dus)", rrate,
- (int) buffer_size, (int) (buffer_size / (rrate * 1e-6)),
- (int) period_size, (int) (period_size / (rrate * 1e-6)));
-
- // Update SRATE and Latency ControlObjects
- m_pControlObjectSampleRate->queueFromThread((double)rrate);
- m_pControlObjectLatency->queueFromThread((double)buffer_time/1000.);
-
- return 0;
-}
-
-int PlayerALSA::set_swparams()
-{
- int err;
-
- /* get the current swparams */
- err = snd_pcm_sw_params_current(handle, swparams);
- if (err < 0)
- {
- qWarning("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
- return err;
- }
- /* start the transfer when the buffer is full */
- err = snd_pcm_sw_params_set_start_threshold(handle, swparams, (buffer_size/period_size)*period_size);
- if (err < 0)
- {
- qWarning("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
- return err;
- }
- /* allow the transfer when at least period_size samples can be processed */
- err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_size);
- if (err < 0)
- {
- qWarning("Unable to set avail min for playback: %s\n", snd_strerror(err));
- return err;
- }
- /* align all transfers to 1 sample */
- err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1);
- if (err < 0)
- {
- qWarning("Unable to set transfer align for playback: %s\n", snd_strerror(err));
- return err;
- }
- /* write the parameters to the playback device */
- err = snd_pcm_sw_params(handle, swparams);
- if (err < 0)
- {
- qWarning("Unable to set sw params for playback: %s\n", snd_strerror(err));
- return err;
- }
- return 0;
-}
diff -Nru mixxx-1.6.0/src/playeralsa.h mixxx-1.6.1/src/playeralsa.h
--- mixxx-1.6.0/src/playeralsa.h 2005-03-18 17:01:48.000000000 -0600
+++ mixxx-1.6.1/src/playeralsa.h 1969-12-31 18:00:00.000000000 -0600
@@ -1,107 +0,0 @@
-/***************************************************************************
- playeralsa.h - description
- -------------------
- begin : Wed Feb 20 2002
- copyright : (C) 2002 by Tue and Ken Haste Andersen
- email :
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. *
- * *
- ***************************************************************************/
-
-#ifndef PLAYERALSA_H
-#define PLAYERALSA_H
-
-/**
- *@author Tue and Ken Haste Andersen, Peter Chang
- */
-
-#ifndef PLAYERTEST
-#include "player.h"
-#else
-// some definitions to avoid using player.h in test mode
-
-#include
-
-#include
-#include
-
-typedef float CSAMPLE; // defines the CSAMPLE type used for intermediate calculations
-#endif
-
-#include
-#include
-#include
-
-/**
- * there are two independent defines S16_OUTPUT and DIRECT_OUTPUT
- * 1) S16_OUTPUT makes the class output short integers to ALSA
- * 2) DIRECT_OUTPUT uses mmapped output
- *
- * NB by default, these are not defined and so the class uses floats via the
- * plug plugin. Defining S16_OUTPUT allows the bare hw to be used (via surround40).
- * XXX: Mmapped output doesn't seem to work with the plug plugin...
- */
-
-#ifndef PLAYERTEST
-class PlayerALSA : public Player, public QThread
-{
-public:
- PlayerALSA(ConfigObject *config);
-#else
-class PlayerALSA : public QThread {
-public:
- PlayerALSA();
-#endif
- ~PlayerALSA();
- bool initialize();
- bool open();
- void close();
- void setDefaults();
- QStringList getInterfaces();
- QStringList getSampleRates();
- static QString getSoundApi();
- QString getSoundApiName() { return getSoundApi(); };
- /** Satisfy virtual declaration in EngineObject */
- void process(const CSAMPLE *, const CSAMPLE *, const int) {};
-
- /** Main loop of player. Executed in a separate thread by QT */
- void run();
-
-protected:
-/** ALSA parameters */
- snd_pcm_t *handle;
- snd_pcm_hw_params_t *hwparams;
- snd_pcm_sw_params_t *swparams;
-
- snd_pcm_uframes_t buffer_size;
- snd_pcm_uframes_t period_size;
- unsigned int period_no;
- bool isformatfloat;
-
- /** True if devices are open */
- bool isopen;
- int masterleft, masterright, headleft, headright;
-
-#ifdef PLAYERTEST
- CSAMPLE *prepareBuffer(int nframes);
-#endif
- int setPeriodSize(bool setMinimum);
- int set_hwparams();
- int set_swparams();
- int xrun_recovery(int err);
-
- bool twrite; // flag for thread
-
-private:
- static const snd_pcm_access_t alsa_access = SND_PCM_ACCESS_RW_INTERLEAVED;
- static const int alsa_channels = 4;
- static const int default_latency = 200;
-};
-#endif
diff -Nru mixxx-1.6.0/src/playerasio.cpp mixxx-1.6.1/src/playerasio.cpp
--- mixxx-1.6.0/src/playerasio.cpp 2008-03-27 00:04:43.000000000 -0500
+++ mixxx-1.6.1/src/playerasio.cpp 1969-12-31 18:00:00.000000000 -0600
@@ -1,670 +0,0 @@
-/***************************************************************************
- PlayerAsio.cpp - description
- -------------------
- begin : Thu June 02 2005
- copyright : (C) 2005 by Ingo Kossyk
- email :
-***************************************************************************/
-
-/***************************************************************************
-* *
-* 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. *
-* *
-***************************************************************************/
-
-
-// PlayerAsio.cpp: implementation of the PlayerAsio class.
-//
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-// ToDo:
-// - Implement all conversion routines for the different drivers
-// - Testing on different soundcards
-// - Correctly (???) setting the latency in the preferences and locking it
-// - Samplerate Changed needs to be implemented if changed in the Preferences
-//////////////////////////////////////////////////////////////////////
-
-#include "qstringlist.h"
-#include "PlayerAsio.h"
-#include "playerproxy.h"
-#include "controlobject.h"
-//////////////////////////////////////////////////////////////////////
-// External Declarations
-//////////////////////////////////////////////////////////////////////
-
-__declspec(dllimport) AsioDrivers* asioDrivers;
-ASIOCallbacks asioCallbacks;
-DriverInfo asioDriverInfo;
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-const int MAX_DRIVER_NAME_LENGTH = 32;
-
-PlayerAsio::PlayerAsio(ConfigObject * config) : Player(config)
-
-{
- m_pTempBuffer = 0;
- m_reenter = 0;
- bufferLength = 0;
- driverIsLoaded = false;
-
- for (int i = 0 ; i < 32 ; ++i) {
- driverList[i] =static_cast(malloc(32));
-
- /* check memory */
- if(!driverList[i]) qDebug() << "ERROR: Could not allocate Memory!";
- }
-
-
- loadAsioDriver("dummy");
-
- drvNum = asioDrivers->getDriverNames(driverList,32);
-
-}
-
-PlayerAsio::~PlayerAsio()
-{
-
- ASIOStop();
- ASIOExit();
-
-}
-//////////////////////////////////////////////////////////////////////
-// Class functions
-//////////////////////////////////////////////////////////////////////
-
-/*******
- *
- * Conversion of different Ouputtypes
- *
- ********/
-const double fScaler24 = (double)0xffff;
-
-void PlayerAsio::float32toInt24inPlace(float * buffer, long frames, bool swap)
-{
- double sc = fScaler24 + .5;
- long a;
- char * b = (char *)(buffer);
- char * aa = (char *)(&a);
-
- while(--frames >= 0)
- {
- a = static_cast(static_cast(*buffer++) *sc);
-
-
- if (swap)
- {
- *b++ = aa[3];
- *b++ = aa[2];
- *b++ = aa[1];
- }
- else
- {
- *b++ = aa[1];
- *b++ = aa[2];
- *b++ = aa[3];
- }
- }
-}
-
-
-void PlayerAsio::Output_Float32_Int24(int channelNumber, float * inputBuffer, float * outputBuffer, bool swap)
-{
- for(int i=0; i < bufferLength; i++)
- {
- m_pTempBuffer[i] = inputBuffer[i*sizeof(float) + channelNumber];
- }
-
- float32toInt24inPlace(m_pTempBuffer,bufferLength,swap);
- memcpy(outputBuffer,m_pTempBuffer,bufferLength*3);
-
-}
-
-void PlayerAsio::Output_Float32_Int32(int channelNumber, float * inputBuffer, float * outputBuffer, bool swap)
-{
- for(int i=0; i < bufferLength; i++)
- {
- m_pTempBuffer[i] = inputBuffer[i*sizeof(float) + channelNumber];
- }
-
- float32toInt32inPlace(static_cast(m_pTempBuffer),bufferLength,swap);
- memcpy(outputBuffer,m_pTempBuffer,bufferLength*4);
-
-}
-
-const double fScaler32 = (double)0xffff;
-
-void PlayerAsio::float32toInt32inPlace(float * buffer, long frames,bool swap)
-{
- double sc = fScaler32 + .49999;
- long a;
- char * b = (char *)(buffer);
- char * aa = (char *)(&a);
-
- while(--frames >= 0)
- {
- a = static_cast(static_cast(*buffer++) * sc);
-
-
- if(swap){
- *b++ = aa[3];
- *b++ = aa[2];
- *b++ = aa[1];
- *b++ = aa[0];
- }
- else
- {
- *b++ = aa[0];
- *b++ = aa[1];
- *b++ = aa[2];
- *b++ = aa[3];
- }
- }
-}
-
-void PlayerAsio::Output_Float32_Int16(int channelNumber, float * inputBuffer, short * outputBuffer, bool swap)
-{
- short temp;
- for (int i=0; i < bufferLength; i++)
- {
- temp = static_cast(inputBuffer[i*sizeof(float) + channelNumber]);
- outputBuffer[i] = static_cast(temp);
- if (swap) SwapBuffer(&outputBuffer[i]);
- }
-}
-
-void PlayerAsio::SwapBuffer(short * buffer)
-{
- short a;
-
- char * b = (char *)(buffer);
- char * aa = (char *)(&a);
-
- a = *buffer;
-
- *b++ = aa[1];
- *b++ = aa[0];
-
-}
-/*******
- *
- * Init
- *
- ********/
-
-bool PlayerAsio::initialize() {
- return true;
-}
-
-bool PlayerAsio::initDriver()
-{
-
-
- if (ASIOInit (&asioDriverInfo.driverInfo) == ASE_OK ){
-
-
- return true;
- }
- return false;
-
-
-}
-
-
-int PlayerAsio::getBufferSize(void)
-{
- return asioDriverInfo.preferredSize;
-}
-
-
-int PlayerAsio::getChannelCount(void)
-{
- return asioDriverInfo.outputChannels;
-}
-
-
-int PlayerAsio::getSampleRate(void)
-{
- return asioDriverInfo.sampleRate;
-}
-
-
-QStringList PlayerAsio::getSampleRates() {
- QStringList result;
- result.append("44100");
- return result;
-}
-
-
-QStringList PlayerAsio::getInterfaces() {
- QStringList result;
- LPASIODRVSTRUCT lpdrv = asioDrivers->lpdrvlist;
- while(lpdrv) {
- result.append(lpdrv->drvname);
- lpdrv = lpdrv->next;
- }
- return result;
-}
-
-long PlayerAsio::init_asio_static_data (DriverInfo * asioDriverInfo)
-{
-
- if(ASIOGetChannels(&asioDriverInfo->inputChannels, &asioDriverInfo->outputChannels) == ASE_OK)
- {
-
-
- // get the usable buffer sizes
- if(ASIOGetBufferSize(&asioDriverInfo->minSize, &asioDriverInfo->maxSize, &asioDriverInfo->preferredSize, &asioDriverInfo->granularity) == ASE_OK)
- {
-
- // get the currently selected sample rate
- if(ASIOGetSampleRate(&asioDriverInfo->sampleRate) == ASE_OK)
- {
- //Get SampleRate From Preferences
- int sampleRate = m_pConfig->getValueString(ConfigKey("[Soundcard]", "Samplerate")).toInt();
- //Calculate Latency
- int iLatencyMSec = (1000*asioDriverInfo->preferredSize*4)/(sampleRate);
-
- if (asioDriverInfo->sampleRate <= 0.0 || asioDriverInfo->sampleRate > 96000.0)
- {
-
- if(ASIOSetSampleRate(sampleRate) == ASE_OK)
- {
- if(ASIOGetSampleRate(&asioDriverInfo->sampleRate) == ASE_OK)
- qDebug() << "Asio State : SAMPLERATE CHANGED";
- else
- return -6;
- }
- else
- return -5;
- } else if(asioDriverInfo->sampleRate != m_pConfig->getValueString(ConfigKey("[Soundcard]","Samplerate")).toInt())
- {
-
- if(ASIOSetSampleRate(sampleRate) == ASE_OK)
- {
- if(ASIOGetSampleRate(&asioDriverInfo->sampleRate) == ASE_OK)
- qDebug() << "Asio State : SAMPLERATE CHANGED";
- else
- return -6;
- }
- else
- return -5;
- }
-
-
- // Driver does not store it's internal sample rate, so set it to a know one.
- // Usually you should check beforehand, that the selected sample rate is valid
- // with ASIOCanSampleRate().
- // Update SRATE and Latency ControlObjects
- m_pControlObjectSampleRate->queueFromThread(static_cast(sampleRate));
- m_pControlObjectLatency->queueFromThread(static_cast(iLatencyMSec));
- m_pConfig->set(ConfigKey("[Soundcard]","Latency"), iLatencyMSec);
- qDebug() << "Asio State: SAMPLERATE SET";
-
- // check wether the driver requires the ASIOOutputReady() optimization
- // (can be used by the driver to reduce output latency by one block)
- if(ASIOOutputReady() == ASE_OK)
- asioDriverInfo->postOutput = true;
- else
- asioDriverInfo->postOutput = false;
-
-
- return 0;
- }
- return -3;
- }
- return -2;
- }
- return -1;
-}
-
-ASIOError PlayerAsio::create_asio_buffers (DriverInfo * asioDriverInfo)
-{
-
- long i=0;
- ASIOError result;
-
- bufferLength = asioDriverInfo->preferredSize;
- m_pTempBuffer = static_cast(malloc(bufferLength*4));
-
- // fill the bufferInfos from the start without a gap
- ASIOBufferInfo * info = asioDriverInfo->bufferInfos;
-
- asioDriverInfo->inputBuffers = 0;
-
- // prepare inputs (Though this is not necessaily required, no opened inputs will work, too
- if (asioDriverInfo->inputChannels > kMaxInputChannels)
- asioDriverInfo->inputBuffers = kMaxInputChannels;
- else
- asioDriverInfo->inputBuffers = asioDriverInfo->inputChannels;
-
- for(i = 0; i < asioDriverInfo->inputBuffers; i++, info++)
- {
- info->isInput = ASIOTrue;
- info->channelNum = i;
- info->buffers[0] = info->buffers[1] = 0;
- }
- // prepare outputs
- if (asioDriverInfo->outputChannels > kMaxOutputChannels)
- asioDriverInfo->outputBuffers = kMaxOutputChannels;
- else
- asioDriverInfo->outputBuffers = asioDriverInfo->outputChannels;
-
- qDebug(QString::number(asioDriverInfo->outputChannels));
-
- // prepare outputs
- if (asioDriverInfo->outputChannels > kMaxOutputChannels)
- asioDriverInfo->outputBuffers = kMaxOutputChannels;
- else
- asioDriverInfo->outputBuffers = asioDriverInfo->outputChannels;
- for(i = 0; i < asioDriverInfo->outputBuffers; i++, info++)
- {
- info->isInput = ASIOFalse;
- info->channelNum = i;
- info->buffers[0] = info->buffers[1] = 0;
- }
-
- // create and activate buffers
- result = ASIOCreateBuffers(asioDriverInfo->bufferInfos,
- asioDriverInfo->outputBuffers+asioDriverInfo->inputBuffers,
- asioDriverInfo->preferredSize, &asioCallbacks);
-
- if (result == ASE_OK)
- {
- // now get all the buffer details, sample word length, name, word clock group and activation
- for (i = 0; i < asioDriverInfo->inputBuffers + asioDriverInfo->outputBuffers; i++)
- {
- asioDriverInfo->channelInfos[i].channel = asioDriverInfo->bufferInfos[i].channelNum;
- asioDriverInfo->channelInfos[i].isInput = asioDriverInfo->bufferInfos[i].isInput;
-
- result = ASIOGetChannelInfo(&asioDriverInfo->channelInfos[i]);
-
- if (result != ASE_OK){
- qDebug() << "ERROR: Buffer init failed !";
- break;
- }
- }
-
- if (result == ASE_OK)
- {
- // get the input and output latencies
- // Latencies often are only valid after ASIOCreateBuffers()
- // (input latency is the age of the first sample in the currently returned audio block)
- // (output latency is the time the first sample in the currently returned audio block requires to get to the output)
- result = ASIOGetLatencies(&asioDriverInfo->inputLatency, &asioDriverInfo->outputLatency);
- //if (result == ASE_OK)
- //emit(initBuffers(asioDriverInfo->preferredSize));
- }
- }
- return result;
-}
-
-/*******
- *
- * Open / Close Calls
- *
- ********/
-bool PlayerAsio::open()
-{
- if (driverIsLoaded)
- close();
-
- QString name;
-
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterLeft"));
-
- char driverName[MAX_DRIVER_NAME_LENGTH];
- strcpy(driverName, name.latin1());
-
- if (loadAsioDriver(driverName))
- {
- qDebug() << "Asio State: DRIVER LOADED";
- if(initDriver()){
- qDebug() << "Asio State: DRIVER INITIALIZED";
- init_asio_static_data (&asioDriverInfo);
- asioCallbacks.bufferSwitch = bufferSwitch;
- asioCallbacks.sampleRateDidChange = sampleRateChanged;
- asioCallbacks.asioMessage = asioMessages;
- asioCallbacks.bufferSwitchTimeInfo = bufferSwitchTimeInfo;
- create_asio_buffers(&asioDriverInfo);
- startAsio();
- return true;
- }
- }
- return false;
-}
-
-void PlayerAsio::startAsio()
-{
- if (ASIOStart() == ASE_OK)
- {
- driverIsLoaded = true;
- qDebug() << "Asio streaming started";
- }
-}
-
-void PlayerAsio::close()
-{
- if(ASIOStop() == ASE_OK)
- {
- driverIsLoaded = false;
- qDebug() << "Asio streaming stopped";
- }
-
- if(ASIOExit() == ASE_OK)
- {
- qDebug() << "Asio exited";
- }
-}
-
-void PlayerAsio::setDefaults()
-{
- // Get list of interfaces
- QStringList interfaces = getInterfaces();
-
- // Set first interfaces to master left
- QStringList::iterator it = interfaces.begin();
- if (it!=interfaces.end())
- {
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue((*it)));
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue((*it)));
- }
- else
- {
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
- }
-
- // Set head left and right to none
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
-
-}
-
-/*******
- *
- * Asio and mixxx Callbacks
- *
- ********/
-
-//----------------------------------------------------------------------------------
-void bufferSwitch(long index, ASIOBool processNow)
-{ // the actual processing callback.
-
- ASIOTime timeInfo;
- memset (&timeInfo, 0, sizeof (timeInfo));
-
-
- bufferSwitchTimeInfo (&timeInfo, index, processNow);
-
-}
-
-
-//----------------------------------------------------------------------------------
-void sampleRateChanged(ASIOSampleRate sRate)
-{
- // do whatever you need to do if the sample rate changed
- // usually this only happens during external sync.
- // Audio processing is not stopped by the driver, actual sample rate
- // might not have even changed, maybe only the sample rate status of an
- // AES/EBU or S/PDIF digital input at the audio device.
- // You might have to update time/sample related conversion routines, etc.
-}
-
-//----------------------------------------------------------------------------------
-long asioMessages(long selector, long value, void * message, double * opt)
-{
- // currently the parameters "value", "message" and "opt" are not used.
- long ret = 0;
- switch(selector)
- {
- case kAsioSelectorSupported:
- if(value == kAsioResetRequest
- || value == kAsioEngineVersion
- || value == kAsioResyncRequest
- || value == kAsioLatenciesChanged
- // the following three were added for ASIO 2.0, you don't necessarily have to support them
- || value == kAsioSupportsTimeInfo
- || value == kAsioSupportsTimeCode
- || value == kAsioSupportsInputMonitor)
- ret = 1L;
- break;
- case kAsioResetRequest:
- // defer the task and perform the reset of the driver during the next "safe" situation
- // You cannot reset the driver right now, as this code is called from the driver.
- // Reset the driver is done by completely destruct is. I.e. ASIOStop(), ASIODisposeBuffers(), Destruction
- // Afterwards you initialize the driver again.
- //asioDriverInfo.stopped; // In this sample the processing will just stop
- ret = 1L;
- break;
- case kAsioResyncRequest:
- // This informs the application, that the driver encountered some non fatal data loss.
- // It is used for synchronization purposes of different media.
- // Added mainly to work around the Win16Mutex problems in Windows 95/98 with the
- // Windows Multimedia system, which could loose data because the Mutex was hold too long
- // by another thread.
- // However a driver can issue it in other situations, too.
- ret = 1L;
- break;
- case kAsioLatenciesChanged:
- // This will inform the host application that the drivers were latencies changed.
- // Beware, it this does not mean that the buffer sizes have changed!
- // You might need to update internal delay data.
- ret = 1L;
- break;
- case kAsioEngineVersion:
- // return the supported ASIO version of the host application
- // If a host applications does not implement this selector, ASIO 1.0 is assumed
- // by the driver
- ret = 2L;
- break;
- case kAsioSupportsTimeInfo:
- // informs the driver wether the asioCallbacks.bufferSwitchTimeInfo() callback
- // is supported.
- // For compatibility with ASIO 1.0 drivers the host application should always support
- // the "old" bufferSwitch method, too.
- ret = 1;
- break;
- case kAsioSupportsTimeCode:
- // informs the driver wether application is interested in time code info.
- // If an application does not need to know about time code, the driver has less work
- // to do.
- ret = 0;
- break;
- }
- return ret;
-}
-
-void PlayerAsio::processCallback(long bufferIndex) {
-
- float * inputBuffer = prepareBuffer(bufferLength);
- // perform the processing
- for (int i = 0; i < asioDriverInfo.inputBuffers + asioDriverInfo.outputBuffers; i++)
- {
- if (asioDriverInfo.bufferInfos[i].isInput == false)
- {
- ASIOBufferInfo * bufferInfo = &asioDriverInfo.bufferInfos[i];
-
- m_reenter++;
- if (m_reenter > 1) {
- qDebug() << "ASIO : reentered callback ???!!!";
- return;
- }
-
- if (!driverIsLoaded) {
- qDebug() << "ASIO : callback and not started ???!!!";
- }
-
-
- bool swap = true;
-
-
- void * outputBuffer = bufferInfo->buffers[bufferIndex];
- ASIOSampleType bufferType = asioDriverInfo.channelInfos[i].type;
- switch (bufferType) {
- case ASIOSTInt16LSB:
- Output_Float32_Int16(i, inputBuffer, static_cast(outputBuffer), !swap);
- break;
- case ASIOSTInt16MSB:
- Output_Float32_Int16(i, inputBuffer, static_cast(outputBuffer), swap);
- break;
- case ASIOSTInt32LSB:
- Output_Float32_Int32(i, inputBuffer, static_cast(outputBuffer), !swap);
- break;
- case ASIOSTInt32MSB:
- Output_Float32_Int32(i, inputBuffer, static_cast(outputBuffer), swap);
- break;
- case ASIOSTFloat32LSB:
- //Output_Float32_Float32(i, inputBuffer, static_cast(outputBuffer), swap);
- break;
- case ASIOSTFloat32MSB:
- //Output_Float32_Float32(i, inputBuffer, static_cast(outputBuffer), !swap);
- memset(static_cast(outputBuffer),0,bufferLength*4);
- break;
- case ASIOSTInt24LSB: // used for 20 bits as well
- Output_Float32_Int24(i, inputBuffer,static_cast(outputBuffer), !swap);
- //memset(static_cast(outputBuffer),0,bufferLength*4);
- break;
- case ASIOSTInt24MSB: // used for 20 bits as well
- case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
- case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
-
- // these are used for 32 bit data buffer, with different alignment of the data inside
- // 32 bit PCI bus systems can more easily used with these
-
- case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment
- case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment
- case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment
- case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment
-
-
- case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment
- case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment
- case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment
- case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment
- // not implemented !!
-
- break;
-
-
- }
-
- m_reenter--;
- }
- }
- if (asioDriverInfo.postOutput)
- ASIOOutputReady();
-}
-
-ASIOTime * bufferSwitchTimeInfo(ASIOTime * timeInfo, long index, ASIOBool processNow)
-{
- ((PlayerAsio *)(PlayerProxy::getPlayer()))->processCallback(index);
-
- return 0L;
-}
diff -Nru mixxx-1.6.0/src/playerasio.h mixxx-1.6.1/src/playerasio.h
--- mixxx-1.6.0/src/playerasio.h 2007-02-03 03:06:06.000000000 -0600
+++ mixxx-1.6.1/src/playerasio.h 1969-12-31 18:00:00.000000000 -0600
@@ -1,133 +0,0 @@
-// PlayerAsio.h: interface for the PlayerAsio class.
-//
-//////////////////////////////////////////////////////////////////////
-
-#include
-#include
-#include
-#include
-#include
-#include "player.h"
-#include "asiosys.h"
-#include "asio.h"
-#include "asiodrivers.h"
-
-
-#if !defined(PlayerAsio_H)
-#define PlayerAsio_H
-
-void __cdecl bufferSwitch(long index, ASIOBool processNow);
-long __cdecl asioMessages(long selector, long value, void* message, double* opt);
-void __cdecl sampleRateChanged(ASIOSampleRate sRate);
-ASIOTime* __cdecl bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow);
-
-enum {
- // number of input and outputs supported by the host application
- // you can change these to higher or lower values
- kMaxInputChannels = 0,
- kMaxOutputChannels = 4
-};
-
-
-// internal data storage
-typedef struct DriverInfo
-{
-
- ASIODriverInfo driverInfo;
-
-
- long inputChannels;
- long outputChannels;
-
-
- long minSize;
- long maxSize;
- long preferredSize;
- long granularity;
-
-
- ASIOSampleRate sampleRate;
-
-
- bool postOutput;
-
-
- long inputLatency;
- long outputLatency;
-
-
- long inputBuffers; // becomes number of actual created input buffers
- long outputBuffers; // becomes number of actual created output buffers
- ASIOBufferInfo bufferInfos[kMaxInputChannels + kMaxOutputChannels]; // buffer info's
-
- // ASIOGetChannelInfo()
- ASIOChannelInfo channelInfos[kMaxInputChannels + kMaxOutputChannels]; // channel info's
-
-
- double nanoSeconds;
- double samples;
- double tcSamples; // time code samples
-
-
- ASIOTime tInfo; // time info state
- unsigned long sysRefTime; // system reference time, when bufferSwitch() was called
-
-
-} DriverInfo;
-
-
-class PlayerAsio : public Player
-{
-
-public:
-
-
- PlayerAsio(ConfigObject *config);
- virtual ~PlayerAsio();
-
- bool initialize();
- bool open();
- void close();
- void startAsio();
-
- int getBufferSize(void);
- int getSampleRate(void);
- int getChannelCount(void);
-
- QStringList getInterfaces();
- QStringList getSampleRates();
-
- void setDefaults();
-
- static QString getSoundApi() { return "ASIO"; }
- QString getSoundApiName() { return getSoundApi(); };
-
- void process(const CSAMPLE *, const CSAMPLE *, const int) { };
- void processCallback(long bufferIndex);
-
-
-private:
- bool initDriver(void);
-
- void Output_Float32_Int16(int channelNumber, float* inputBuffer, short* outputBuffer, bool swap);
- void Output_Float32_Int32(int channelNumber, float* inputBuffer, float* outputBuffer, bool swap);
- void Output_Float32_Int24(int channelNumber, float* inputBuffer, float* outputBuffer, bool swap);
- void float32toInt24inPlace(float* buffer, long frames, bool swap);
- void float32toInt32inPlace(float* buffer, long frames, bool swap);
- void SwapBuffer(short* buffer);
-
- ASIOError create_asio_buffers (DriverInfo *asioDriverInfo);
- long init_asio_static_data (DriverInfo *asioDriverInfo);
-
- AsioDrivers* driver;
- int m_reenter;
- bool driverIsLoaded;
- int drvNum;
- int bufferLength;
- char* driverList[32];
- /** Used in sample convertion */
- float *m_pTempBuffer;
-
-};
-
-#endif
diff -Nru mixxx-1.6.0/src/player.cpp mixxx-1.6.1/src/player.cpp
--- mixxx-1.6.0/src/player.cpp 2008-03-27 00:04:43.000000000 -0500
+++ mixxx-1.6.1/src/player.cpp 1969-12-31 18:00:00.000000000 -0600
@@ -1,151 +0,0 @@
-/***************************************************************************
- player.cpp - description
- -------------------
- begin : Wed Feb 20 2002
- copyright : (C) 2002 by Tue and Ken Haste Andersen
- email :
-***************************************************************************/
-
-/***************************************************************************
-* *
-* 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. *
-* *
-***************************************************************************/
-
-#include "player.h"
-#include "enginemaster.h"
-#include "controlobject.h"
-
-#ifdef RECORD_OUTPUT
-// HACK TO RECORD OUTPUT. WRITTEN TO FILE AT PROGRAM EXIT
- #include
- #include
-typedef struct {
- short int * pBuffer;
- int size;
-} recordObject;
-Q3PtrList m_qRecordList;
-#endif
-
-//Static variable memory allocation
-short int Player::m_iBufferSize = 0;
-short int Player::m_iChannels[MAX_AUDIODEVICES];
-EngineMaster * Player::m_pMaster = 0;
-
-
-
-/* -------- ------------------------------------------------------
- Purpose: Initializes the audio hardware.
- Input: Size of the output buffer in samples
- Output: Pointer to internal synthesis data structure.
- -------- ------------------------------------------------------ */
-Player::Player(ConfigObject * pConfig)
-{
- m_pConfig = pConfig;
- m_pBuffer = new CSAMPLE[MAX_BUFFER_LEN];
- m_pControlObjectSampleRate = ControlObject::getControl(ConfigKey("[Master]","samplerate"));
- m_pControlObjectLatency = new ControlObject(ConfigKey("[Master]","latency"));;
-
- for (int i = 0; i < MAX_AUDIODEVICES; i++)
- {
- m_iChannels[i] = 0;
- }
-}
-
-/* -------- ------------------------------------------------------
- Purpose: Terminate and deallocate the synthesis system
- Input: -
- Output: -
- -------- ------------------------------------------------------ */
-Player::~Player()
-{
- delete [] m_pBuffer;
-
-#ifdef RECORD_OUTPUT
- //
- // HACK: Write recorded sound
- //
-
- qDebug() << "Writing output to file... please wait!";
-
- // Setup file format
- AFfilesetup outputSetup = afNewFileSetup();
- afInitFileFormat(outputSetup, AF_FILE_WAVE);
- afInitRate(outputSetup, AF_DEFAULT_TRACK, m_pControlObjectSampleRate->get());
- afInitChannels(outputSetup, AF_DEFAULT_TRACK, 2);
- afInitSampleFormat (outputSetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
- //afInitByteOrder (outputSetup, AF_DEFAULT_TRACK, AF_BYTEORDER_BIGENDIAN);
-
- // Open file handle
- AFfilehandle fh = afOpenFile("output.wav","w",outputSetup);
- if (!fh)
- qCritical("Could not write wave output file");
- recordObject * r;
- for (r = m_qRecordList.first(); r; r=m_qRecordList.next())
- {
- afWriteFrames(fh,AF_DEFAULT_TRACK,r->pBuffer,r->size/2);
- }
- afCloseFile(fh);
-#endif
-}
-
-/*
- short int Player::getBufferSize()
- {
- // if (m_iChannels>0)
- // return m_iBufferSize/m_iChannels;
- // else
- return m_iBufferSize;
- }
- */
-
-void Player::setMaster(EngineMaster * pMaster)
-{
- m_pMaster = pMaster;
-}
-
-bool Player::open()
-{
- if (m_pConfig->getValueString(ConfigKey("[Soundcard]","PitchIndpTimeStretch")).toInt())
- qDebug() << "pitch true";
-
- // Set sound scale method
- if (m_pMaster)
- m_pMaster->setPitchIndpTimeStretch(m_pConfig->getValueString(ConfigKey("[Soundcard]","PitchIndpTimeStretch")).toInt());
-
- return true;
-}
-
-/* -------- ------------------------------------------------------
- Purpose: Internal callback function used for preparing samples
- for playback. This is where the synthesis is done.
- Input: Number of samples for each channel (4 channels in all)
- Output: pointer to resulting buffer of samples
- -------- ------------------------------------------------------ */
-CSAMPLE * Player::prepareBuffer(int iBufferSize)
-{
- // First, sync control parameters with changes from GUI thread
- ControlObject::sync();
-
- // Process a block of samples for output. iBufferSize is the
- // number of samples for one channel, but the EngineObject
- // architecture expects number of samples for two channels
- // as input so...
- m_pMaster->process(0, m_pBuffer, iBufferSize*2);
-
-#ifdef RECORD_OUTPUT
- // HACK: RECORD SOUND
- recordObject * r = new recordObject;
- m_qRecordList.append(r);
- r->size = iBufferSize*2;
- r->pBuffer = new short int[r->size];
- for (int j=0; jsize; ++j)
- r->pBuffer[j] = (short int)(m_pBuffer[j]);
-#endif
-
- return m_pBuffer;
-}
-
diff -Nru mixxx-1.6.0/src/player.h mixxx-1.6.1/src/player.h
--- mixxx-1.6.0/src/player.h 2007-08-21 23:16:40.000000000 -0500
+++ mixxx-1.6.1/src/player.h 1969-12-31 18:00:00.000000000 -0600
@@ -1,79 +0,0 @@
-/***************************************************************************
- player.h - description
- -------------------
- begin : Wed Feb 20 2002
- copyright : (C) 2002 by Tue and Ken Haste Andersen
- email :
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. *
- * *
- ***************************************************************************/
-
-#ifndef PLAYER_H
-#define PLAYER_H
-
-#include "configobject.h"
-#include
-#include "engineobject.h"
-#include
-
-#define MAX_AUDIODEVICES 2
-
-class EngineMaster;
-class ControlObject;
-
-class Player : public EngineObject
-{
-public:
- Player(ConfigObject *pConfig);
- virtual ~Player();
- /** Initialize the API. Returns true on success. No other methods in a Player
- * class can be called before this method returns true. Called by the proxy
- * class. */
- virtual bool initialize() = 0;
- /** Returns the current buffer size (total latency) used by the playback system */
- //static short int getBufferSize();
- /** Set EngineMaster object */
- static void setMaster(EngineMaster *pMaster);
- /** Open devices according to config database, and start audio stream.
- * Returns true on success. */
- virtual bool open();
- /** Close devices, and stop audio stream */
- virtual void close() = 0;
- /** Store default configuration in config database */
- virtual void setDefaults() = 0;
- /** Return list of interfaces */
- virtual QStringList getInterfaces() = 0;
- /** Return list of input interfaces */
- virtual QStringList getInputInterfaces() = 0;
- /** Return list of sample rates */
- virtual QStringList getSampleRates() = 0;
- /** Return name of sound api */
- virtual QString getSoundApiName() = 0;
-
-protected:
- /** Prepares one buffer of sound by calling the engine */
- CSAMPLE *prepareBuffer(int iBufferSize);
-
- /** Pointer to config database */
- ConfigObject *m_pConfig;
- /** Pointer to EngineMaster object */
- static EngineMaster *m_pMaster;
- CSAMPLE *m_pBuffer;
- /** Current buffer size in use. */
- static short int m_iBufferSize;
- /** Current number of channels in use */
- static short int m_iChannels[MAX_AUDIODEVICES];
- /** Pointer to object holding sample rate */
- ControlObject *m_pControlObjectSampleRate;
- /** Pointer to object holding latency */
- ControlObject *m_pControlObjectLatency;
-};
-
-#endif
diff -Nru mixxx-1.6.0/src/playerjack.cpp mixxx-1.6.1/src/playerjack.cpp
--- mixxx-1.6.0/src/playerjack.cpp 2008-03-27 00:04:43.000000000 -0500
+++ mixxx-1.6.1/src/playerjack.cpp 1969-12-31 18:00:00.000000000 -0600
@@ -1,370 +0,0 @@
-/***************************************************************************
- playerjack.cpp - description
- -------------------
- begin : Sat Nov 15 2003
- copyright : (C) 2003 by Tue Haste Andersen
- email :
-***************************************************************************/
-
-/***************************************************************************
-* *
-* 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. *
-* *
-***************************************************************************/
-
-#include "playerjack.h"
-#include "controlobject.h"
-#include
-#include
-#include
-#include "controlobject.h"
-
-PlayerJack::PlayerJack(ConfigObject * config) : Player(config) //, mLibJack("libjack.so")
-{
- ports = 0;
- m_bOpen = false;
-
-/*
- //mLibJack = new QLibrary("jack");
- if (!mLibJack.load())
- qDebug() << "JACK lib path" << mLibJack.library();
-
- //if (mLibJack.isLoaded())
- {
- jack_set_error_function = (jack_set_error_function_t) mLibJack.resolve("jack_set_error_function");
- jack_port_unregister = (jack_port_unregister_t) mLibJack.resolve("jack_port_unregister");
- jack_client_close = (jack_client_close_t) mLibJack.resolve("jack_client_close");
- jack_client_new = (jack_client_new_t) mLibJack.resolve("jack_client_new");
- jack_set_process_callback = (jack_set_process_callback_t) mLibJack.resolve("jack_set_process_callback");
- jack_set_sample_rate_callback = (jack_set_sample_rate_callback_t) mLibJack.resolve("jack_set_sample_rate_callback");
- jack_on_shutdown =(jack_on_shutdown_t) mLibJack.resolve("jack_on_shutdown");
- jack_port_register =(jack_port_register_t) mLibJack.resolve("jack_port_register");
- jack_activate =(jack_activate_t) mLibJack.resolve("jack_activate");
- jack_connect =(jack_connect_t) mLibJack.resolve("jack_connect");
- jack_port_name =(jack_port_name_t) mLibJack.resolve("jack_port_name");
- jack_deactivate =(jack_deactivate_t) mLibJack.resolve("jack_deactivate");
- jack_get_ports =(jack_get_ports_t) mLibJack.resolve("jack_get_ports");
- jack_get_sample_rate =(jack_get_sample_rate_t) mLibJack.resolve("jack_get_sample_rate");
- jack_port_get_buffer =(jack_port_get_buffer_t) mLibJack.resolve("jack_port_get_buffer");
- }
- */
-}
-
-PlayerJack::~PlayerJack()
-{
-// if (!mLibJack.isLoaded())
-// return;
-
- close();
-
- if (client)
- {
- jack_port_unregister(client, output_master_left);
- jack_port_unregister(client, output_master_right);
- jack_port_unregister(client, output_head_left);
- jack_port_unregister(client, output_head_right);
-
- jack_client_close(client);
- }
-
- if (ports)
- free(ports);
-}
-
-bool PlayerJack::initialize()
-{
- // Verify that library is loaded, and all function pointers has been retreived
- /*
- if (!mLibJack.isLoaded())
- {
- qDebug() << "lib not loaded";
- return false;
- }
- else
- if (!jack_set_error_function |
- !jack_port_unregister |
- !jack_client_close |
- !jack_client_new |
- !jack_set_process_callback |
- !jack_set_sample_rate_callback |
- !jack_on_shutdown |
- !jack_port_register |
- !jack_activate |
- !jack_connect |
- !jack_port_name |
- !jack_deactivate |
- !jack_get_ports |
- !jack_get_sample_rate |
- !jack_port_get_buffer)
- {
- qDebug() << "API function pointer error";
- return false;
- }
- */
-
- jack_set_error_function(jackError);
-
- if ((client = jack_client_new("Mixxx")) == 0)
- return false;
-
- jack_set_process_callback(client, jackProcess, this);
- jack_set_sample_rate_callback(client, jackSrate, this);
- jack_on_shutdown(client, jackShutdown, this);
-
- output_master_left = jack_port_register(client, "Master left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
- output_master_right = jack_port_register(client, "Master right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
- output_head_left = jack_port_register(client, "Head left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
- output_head_right = jack_port_register(client, "Head right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
-
- return true;
-}
-
-bool PlayerJack::open()
-{
- Player::open();
-
- /* tell the JACK server that we are ready to roll */
- if (jack_activate(client))
- {
- qDebug() << "Jack: Cannot activate client";
- return false;
- }
-
- // Connect to the ports
- QString name;
- m_iChannels = 0;
-
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterLeft"));
- if (name != "None")
- {
- qDebug() << "connecting" << name << "to master left";
- if (jack_connect(client, jack_port_name(output_master_left), name.latin1()))
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
- else
- {
- m_iBufferSize = jack_port_get_total_latency(client, output_master_left);
- m_iChannels++;
- }
- }
-
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterRight"));
- if (name != "None")
- {
- qDebug() << "connecting" << name << "to master right";
- if (jack_connect(client, jack_port_name(output_master_right), name.latin1()))
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
- else
- {
- m_iBufferSize = jack_port_get_total_latency(client, output_master_right);
- m_iChannels++;
- }
- }
-
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceHeadLeft"));
- if (name != "None")
- {
- qDebug() << "connecting" << name << "to head left";
- if (jack_connect(client, jack_port_name(output_head_left), name.latin1()))
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
- else
- {
- m_iBufferSize = jack_port_get_total_latency(client, output_head_left);
- m_iChannels++;
- }
- }
-
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceHeadRight"));
- if (name != "None")
- {
- qDebug() << "connecting" << name << "to head right";
- if (jack_connect(client, jack_port_name(output_head_right), name.latin1()))
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
- else
- {
- m_iBufferSize = jack_port_get_total_latency(client, output_head_right);
- m_iChannels++;
- }
- }
-
- qDebug() << "channels " << m_iChannels << ", latency " << m_iBufferSize;
-
-
- // Update the config database with the used sample rate
- QStringList srates = getSampleRates();
- QStringList::iterator it = srates.begin();
- if (*it)
- {
- m_pConfig->set(ConfigKey("[Soundcard]","Samplerate"),ConfigValue((*it)));
-
- // Set currently used latency in config database
- int msec = (int)(1000.*(float)m_iBufferSize/((float)(*it).toInt()));
- m_pConfig->set(ConfigKey("[Soundcard]","Latency"), ConfigValue(msec));
-
- // Update SRATE and Latency ControlObjects
- m_pControlObjectSampleRate->queueFromThread((double)((*it).toInt()));
- m_pControlObjectLatency->queueFromThread((double)msec);
-
- }
-
- m_bOpen = true;
- return true;
-}
-
-void PlayerJack::close()
-{
- // Deactivate jack and disconnect all ports
- if (m_bOpen && client)
- jack_deactivate(client);
- m_bOpen = false;
-}
-
-void PlayerJack::setDefaults()
-{
- // Get list of interfaces
- QStringList interfaces = getInterfaces();
-
- // Set first interfaces to master left
- QStringList::iterator it = interfaces.begin();
- if (*it)
- {
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue((*it)));
- }
- else
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
-
- // Set second interface to master right
- if (*it) ++it;
- if (*it)
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue((*it)));
- else
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
-
- // Set head left and right to none
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
-
- // Set default sample rate
- QStringList srates = getSampleRates();
- it = srates.begin();
- if (*it)
- {
- m_pConfig->set(ConfigKey("[Soundcard]","Samplerate"),ConfigValue((*it)));
-
- // Set currently used latency in config database
- int msec = 1000*m_iBufferSize/(4*(*it).toInt());
- m_pConfig->set(ConfigKey("[Soundcard]","Latency"), ConfigValue(msec));
- }
-}
-
-QStringList PlayerJack::getInterfaces()
-{
- QStringList result;
-
- if (!client && !initialize())
- {
- qDebug() << "Jack: Failed to reinitialize the connection to Jack";
- return result;
- }
-
- if ((ports = jack_get_ports (client, 0, 0, JackPortIsPhysical|JackPortIsInput)) == 0)
- qDebug() << "Jack: Cannot find any physical playback ports";
- else
- {
- int i=0;
- while (ports[i]!=0)
- {
- result.append(ports[i]);
- ++i;
- }
- }
-
- return result;
-}
-
-QStringList PlayerJack::getSampleRates()
-{
- QStringList result;
-
- if (client)
- result.append(QString("%1").arg((int)jack_get_sample_rate(client)));
-
- return result;
-}
-
-QString PlayerJack::getSoundApi()
-{
- return QString("Jack");
-}
-
-int PlayerJack::callbackProcess(int iBufferSize)
-{
-// qDebug() << "buffer size " << iBufferSize;
- jack_default_audio_sample_t * out_ml = (jack_default_audio_sample_t *)jack_port_get_buffer(output_master_left, iBufferSize);
- jack_default_audio_sample_t * out_mr = (jack_default_audio_sample_t *)jack_port_get_buffer(output_master_right, iBufferSize);
- jack_default_audio_sample_t * out_hl = (jack_default_audio_sample_t *)jack_port_get_buffer(output_head_left, iBufferSize);
- jack_default_audio_sample_t * out_hr = (jack_default_audio_sample_t *)jack_port_get_buffer(output_head_right, iBufferSize);
-
- if (m_bOpen)
- {
- CSAMPLE * buffer = prepareBuffer(iBufferSize);
-
- for (int i=0; iqueueFromThread((double)srate);
-}
-
-void PlayerJack::callbackSetBufferSize(int iBufferSize)
-{
- m_iBufferSize = iBufferSize;
-}
-
-void PlayerJack::callbackShutdown()
-{
- m_pConfig->set(ConfigKey("[Soundcard]","SoundApi"), ConfigValue("None"));
-
- qWarning("Jack connection was killed.\n\nThis could be due to a high CPU load. Try increasing the latency\nwhen starting the Jack sound server.");
-}
-
-void jackError(const char * desc)
-{
- qDebug() << "Jack experienced an error:" << desc;
-}
-
-int jackProcess(jack_nframes_t nframes, void * arg)
-{
- ((PlayerJack *)arg)->callbackProcess(nframes);
- return 0;
-}
-
-int jackSrate(jack_nframes_t nframes, void * arg)
-{
- // Update SRATE in EngineObject
- ((PlayerJack *)arg)->callbackSetSrate(nframes);
- return 0;
-}
-
-void jackShutdown(void * arg)
-{
- ((PlayerJack *)arg)->callbackShutdown();
-}
-
-void jackBufferSize(jack_nframes_t nframes, void * arg)
-{
- ((PlayerJack *)arg)->callbackSetBufferSize(nframes);
-}
diff -Nru mixxx-1.6.0/src/playerjack.h mixxx-1.6.1/src/playerjack.h
--- mixxx-1.6.0/src/playerjack.h 2005-03-18 17:01:48.000000000 -0600
+++ mixxx-1.6.1/src/playerjack.h 1969-12-31 18:00:00.000000000 -0600
@@ -1,120 +0,0 @@
-/***************************************************************************
- playerjack.h - description
- -------------------
- begin : Sat Nov 15 2003
- copyright : (C) 2003 by Tue Haste Andersen
- email :
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. *
- * *
- ***************************************************************************/
-
-#ifndef PLAYERJACK_H
-#define PLAYERJACK_H
-
-#include "player.h"
-#include
-#include
-
-/**
- *@author Tue and Ken Haste Andersen
- */
-
-class PlayerJack : public Player
-{
-public:
- PlayerJack(ConfigObject *config);
- ~PlayerJack();
- bool initialize();
- bool open();
- void close();
- void setDefaults();
- QStringList getInterfaces();
- QStringList getSampleRates();
- static QString getSoundApi();
- QString getSoundApiName() { return getSoundApi(); };
- /** Satisfy virtual declaration in EngineObject */
- void process(const CSAMPLE *, const CSAMPLE *, const int) {};
- /** Process samples. Called from jack callback */
- int callbackProcess(int iBufferSize);
- /** Used to set sample rate from Jack callback */
- void callbackSetSrate(int iSrate);
- /** Used to set current buffer size */
- void callbackSetBufferSize(int iBufferSize);
- /** Used to reinitialize when shut down by Jack server */
- void callbackShutdown();
-
-protected:
- /** Pointer to QLibrary object */
- //QLibrary mLibJack;
- /** Pointer to client info */
- jack_client_t *client;
- /** Null terminated array of port names */
- const char **ports;
- /** Playback ports */
- jack_port_t *output_master_left, *output_master_right, *output_head_left, *output_head_right;
- /** True if devices are open */
- bool m_bOpen;
-
-/*
- typedef void (*jack_set_error_function_t)(void (*func)(const char *));
- jack_set_error_function_t jack_set_error_function;
-
- typedef int (*jack_port_unregister_t)(jack_client_t *, jack_port_t *);
- jack_port_unregister_t jack_port_unregister;
-
- typedef int (*jack_client_close_t)(jack_client_t *client);
- jack_client_close_t jack_client_close;
-
- typedef jack_client_t* (*jack_client_new_t)(const char *client_name);
- jack_client_new_t jack_client_new;
-
- typedef int (*jack_set_process_callback_t)(jack_client_t *client,JackProcessCallback process_callback,void *arg);
- jack_set_process_callback_t jack_set_process_callback;
-
- typedef int (*jack_set_sample_rate_callback_t)(jack_client_t *client,JackSampleRateCallback srate_callback,void *arg);
- jack_set_sample_rate_callback_t jack_set_sample_rate_callback;
-
- typedef void (*jack_on_shutdown_t)(jack_client_t *client, void (*function)(void *arg), void *arg);
- jack_on_shutdown_t jack_on_shutdown;
-
- typedef jack_port_t* (*jack_port_register_t)(jack_client_t *,const char *port_name,const char *port_type,unsigned long flags,unsigned long buffer_size);
- jack_port_register_t jack_port_register;
-
- typedef int (*jack_activate_t)(jack_client_t *client);
- jack_activate_t jack_activate;
-
- typedef int (*jack_connect_t)(jack_client_t *,const char *source_port,const char *destination_port);
- jack_connect_t jack_connect;
-
- typedef const char* (*jack_port_name_t)(const jack_port_t *port);
- jack_port_name_t jack_port_name;
-
- typedef int (*jack_deactivate_t)(jack_client_t *client);
- jack_deactivate_t jack_deactivate;
-
- typedef const char** (*jack_get_ports_t)(jack_client_t *,const char *port_name_pattern,const char *type_name_pattern,unsigned long flags);
- jack_get_ports_t jack_get_ports;
-
- typedef jack_nframes_t (*jack_get_sample_rate_t)(jack_client_t *);
- jack_get_sample_rate_t jack_get_sample_rate;
-
- typedef void* (*jack_port_get_buffer_t)(jack_port_t *, jack_nframes_t);
- jack_port_get_buffer_t jack_port_get_buffer;
-*/
-};
-
-// Jack callbacks:
-void jackError(const char *desc);
-int jackProcess(jack_nframes_t nframes, void *arg);
-int jackSrate(jack_nframes_t nframes, void *arg);
-void jackShutdown(void *arg);
-void jackBufferSize(jack_nframes_t nframes, void *arg);
-
-#endif
diff -Nru mixxx-1.6.0/src/playerportaudio.cpp mixxx-1.6.1/src/playerportaudio.cpp
--- mixxx-1.6.0/src/playerportaudio.cpp 2008-03-27 00:04:43.000000000 -0500
+++ mixxx-1.6.1/src/playerportaudio.cpp 1969-12-31 18:00:00.000000000 -0600
@@ -1,938 +0,0 @@
-/***************************************************************************
- playerportaudiov19.cpp - description
- -------------------
- begin : Wed Feb 20 2002
- copyright : (C) 2002 by Tue and Ken Haste Andersen
- (C) 2006/2007 by Albert Santoni
- (C) 2006 by Adam Davison
- email :
-***************************************************************************/
-
-/***************************************************************************
-* *
-* 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. *
-* *
-***************************************************************************/
-
-#include "playerportaudio.h"
-#include "controlobject.h"
-
-// Mathstuff required for Win32
-#include "mathstuff.h"
-//Added by qt3to4:
-#include
-#include
-#include
-
-bool PlayerPortAudio::m_painited = false;
-
-PlayerPortAudio::PlayerPortAudio(ConfigObject * config, QString api_name) : Player(config)
-{
- for (int i = 0; i < MAX_AUDIODEVICES; i++)
- {
- m_devId[i] = -1;
- m_inputDevId[i] = -1;
- m_pStream[i] = 0;
- m_iChannels[i] = -1;
- }
-
- m_iNumberOfBuffers = 2;
- m_iMasterLeftCh = -1;
- m_iMasterRigthCh = -1;
- m_iHeadLeftCh = -1;
- m_iHeadRightCh = -1;
- m_iNumActiveDevices = 0;
- m_iPreviousDevIndex = -1;
-#ifdef __VINYLCONTROL__
- m_VinylControl[0] = NULL;
- m_VinylControl[1] = NULL;
-#endif
-
- m_HostAPI = api_name;
- m_bInit = false;
-}
-
-PlayerPortAudio::~PlayerPortAudio()
-{
- //Close all the audio devices.
- close();
-
- if (m_bInit) {
- Pa_Terminate();
- m_painited = false;
- }
-}
-
-bool PlayerPortAudio::initialize()
-{
- PaError err = Pa_Initialize();
- if (err!=paNoError)
- {
- qDebug() << "PortAudio error: " << Pa_GetErrorText(err);
- m_bInit = false;
- }
- else
- m_bInit = true;
-
- return m_bInit;
-}
-
-bool PlayerPortAudio::open()
-{
- Player::open();
-
-#ifdef __VINYLCONTROL__
- //Create a new VinylControl object so that it updates it's settings.
- //TODO: FIX THIS SAMPLERATE HACKAGE
- int iTempSrate = m_pConfig->getValueString(ConfigKey("[Soundcard]","Samplerate")).toInt();
- if (iTempSrate <= 0)
- iTempSrate = 44100;
- m_VinylControl[0] = new VinylControlProxy(m_pConfig, "[Channel1]", iTempSrate);
- m_VinylControl[1] = new VinylControlProxy(m_pConfig, "[Channel2]", 44100);
-#endif
-
- // Find out which device to open. Select the first one listed as either Master Left,
- // Master Right, Head Left, Head Right. If other devices are requested for opening
- // than the one selected here, set them to "None" in the config database
-
- // For the record, with MAX_AUDIODEVICES currently set to 2, we're referring to
- // Master Left/Right as device 1 and Headphones as device 2 (unless Master and
- // Headphones are on the same device, then we only use device 1.)
- PaDeviceIndex id[MAX_AUDIODEVICES];
- PaDeviceIndex id_input[MAX_AUDIODEVICES];
- int iChannelMax[MAX_AUDIODEVICES]; /** Maximum number of channels needed */
- PaDeviceIndex temp_id = -1;
- QString name;
-
- for (int i = 0; i < MAX_AUDIODEVICES; i++)
- {
- iChannelMax[i] = -1;
- id[i] = -1;
- id_input[i] = -1;
- }
-
- m_iMasterLeftCh = -1;
- m_iMasterRigthCh = -1;
- m_iHeadLeftCh = -1;
- m_iHeadRightCh = -1;
-
- waitForNextOutput.wakeAll();
-
- // Master left
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterLeft"));
- temp_id = getDeviceID(name);
- if (temp_id >= 0)
- {
- if (getChannelNo(name)>=0)
- {
- id[0] = temp_id;
- iChannelMax[0] = getChannelNo(name);
- m_iMasterLeftCh = getChannelNo(name)-1;
- }
- }
-
- // Master right
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterRight"));
- temp_id = getDeviceID(name);
- if (getChannelNo(name)>=0 //Make sure we got a valid number of channels
- && ((id[0]==-1 && temp_id>=0) //Make sure the left channel and this (right) channel IDs are valid
- || (temp_id!=-1 && id[0]==temp_id))) //No idea...
- {
- id[0] = math_max(temp_id, id[0]);
- iChannelMax[0] = math_max(iChannelMax[0], getChannelNo(name));
- m_iMasterRigthCh = getChannelNo(name)-1;
- }
-
- // Head left
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceHeadLeft"));
- temp_id = getDeviceID(name);
- if (getChannelNo(name)>=0 && ((id[1]==-1 && temp_id>=0) || (temp_id!=-1 && id[1]==temp_id)))
- {
- id[1] = temp_id;
- iChannelMax[1] = math_max(iChannelMax[1], getChannelNo(name));
- m_iHeadLeftCh = getChannelNo(name)-1;
- }
-
- // Head right
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceHeadRight"));
- temp_id = getDeviceID(name);
- if (getChannelNo(name)>=0 && ((id[1]==-1 && temp_id>=0) || (temp_id!=-1 && id[1]==temp_id)))
- {
- id[1] = temp_id;
- iChannelMax[1] = math_max(iChannelMax[1], getChannelNo(name));
- m_iHeadRightCh = getChannelNo(name)-1;
- }
-
- // Inputs
- name = m_pConfig->getValueString(ConfigKey("[VinylControl]","DeviceInputDeck1"));
- temp_id = getInputDeviceID(name);
- if (temp_id != -1)
- id_input[0] = temp_id;
-
- name = m_pConfig->getValueString(ConfigKey("[VinylControl]","DeviceInputDeck2"));
- temp_id = getInputDeviceID(name);
- if (temp_id != -1)
- id_input[1] = temp_id;
-
- // Check if any of the devices in the config database needs to be set to "None"
- if (m_iMasterLeftCh<0)
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
- if (m_iMasterRigthCh<0)
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
- if (m_iHeadLeftCh<0)
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
- if (m_iHeadRightCh<0)
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
-
- // Number of channels to open
- int iChannels[MAX_AUDIODEVICES];
- if (id[0] == id[1]) //Check if we're supposed to use the same soundcard for both Master and Headphone output
- {
- iChannels[0] = math_max(iChannelMax[0], iChannelMax[1]);
- iChannels[1] = -1;
- }
- else
- {
- iChannels[0] = iChannelMax[0];
- iChannels[1] = iChannelMax[1];
- }
-
- // Sample rate
- int iSrate = m_pConfig->getValueString(ConfigKey("[Soundcard]","Samplerate")).toInt();
- if (iSrate <= 0)
- iSrate = 44100;
-
- // Get latency in msec
- int iLatencyMSec = m_pConfig->getValueString(ConfigKey("[Soundcard]","Latency")).toInt();
-
- if (iLatencyMSec <= 0) //Make sure we don't get a crazy latency value.
- iLatencyMSec = 100;
-
- // Latency in samples
- //int iLatencySamples = (int)((float)(iSrate*iChannels)/1000.f*(float)iLatencyMSec); //Pre-multisoundcard output
- int iLatencySamples = (int)((float)(iSrate*math_max(iChannels[0], iChannels[1]))/1000.f*(float)iLatencyMSec);
-
- // Round to the nearest multiple of 4.
- iLatencySamples -= (iLatencySamples % 4);
- iLatencySamples += 4;
-
- qDebug() << "iLatencySamples: " << iLatencySamples;
-
- // Apply simple rule to determine number of buffers
- if (iLatencySamples/kiMaxFrameSize<2)
- m_iNumberOfBuffers = 2;
- else
- m_iNumberOfBuffers = iLatencySamples/kiMaxFrameSize;
-
- // Frame size...
- int iFramesPerBuffer = iLatencySamples/m_iNumberOfBuffers;
-
- // Ensure the chosen configuration is valid
- //TODO: Fix this in our PortAudio-v19 implementation. PA19 ditches the Pa_GetMinNumBuffers() function, as it's
- // not needed anymore.
- /*
- if (m_iNumberOfBuffersset(ConfigKey("[Soundcard]","Latency"), ConfigValue(iLatencyMSec));
- }
- */
-
- // Callback function to use
- PaStreamCallback * callback = paV19Callback;
- qDebug() << "PortAudio: kiMaxFrameSize: " << kiMaxFrameSize << ", iLatencyMSec: " << iLatencyMSec;
- qDebug() << "PortAudio: id[0] " << id[0] << ", sr " << iSrate << ", ch[0] " << iChannels[0] << ", bufsize " << iFramesPerBuffer << ", bufno " << m_iNumberOfBuffers << ", req. latency " << iLatencyMSec << " msec";
- qDebug() << "PortAudio: id[1] " << id[1] << ", sr " << iSrate << ", ch[1] " << iChannels[1] << ", bufsize " << iFramesPerBuffer << ", bufno " << m_iNumberOfBuffers << ", req. latency " << iLatencyMSec << " msec";
-
- qDebug() << "Device 1 indices (id[0]: " << id[0] << ", id_input[0]: " << id_input[0] << ")";
- qDebug() << "Device 2 indices (id[1]: " << id[1] << ", id_input[1]: " << id_input[1] << ")";
-
-
- //If all devices are set to "None", then just return.
- if ((id[0] < 0) && (id[1] < 0))
- return false;
-
- PaStreamParameters outputParams[MAX_AUDIODEVICES];
- PaStreamParameters inputParams[MAX_AUDIODEVICES];
- bool bDeviceAlreadyOpened = false;
-
- //Set up and open each soundcard that we need!
- for (int i = 0; i < MAX_AUDIODEVICES; i++)
- {
- bDeviceAlreadyOpened = false;
-
- for (int j = 0; j < i; j++) //Check to see if we've already opened this device (eg. Maybe we're already using it for Master output)
- {
- if (j != i)
- {
- if (id[j] == id[i] && id[j] != -1) {
- bDeviceAlreadyOpened = true;
- }
- }
- }
- if (((id[i] != -1) && !bDeviceAlreadyOpened) || (id_input[i] != -1)) //Make sure we're supposed to open this device...
- {
- qDebug() << "PortAudio: Trying to open device id " << id[i] << ", with channels " << iChannels[i] << " at samplerate " << iSrate;
- PaStreamParameters * p_outputParams;
- outputParams[i].device = id[i];
- outputParams[i].channelCount = iChannels[i];
- outputParams[i].sampleFormat = paFloat32;
- outputParams[i].suggestedLatency = ((float)iLatencyMSec) / 1000.0f; //Latency in seconds.
- outputParams[i].hostApiSpecificStreamInfo = NULL;
-
- PaStreamParameters * p_inputParams; //TODO: Does this need to be made an array like inputParams?
- inputParams[i].device = id_input[i]; //TODO: Isn't the "input" device always the same as the output device? (if there is an output device?)
- // Maybe that should be restricted in the preferences GUI...
- // NO, it's not always the same as the output device! Consider using 4 outputs on your
- // master soundcard, and a different soundcard for input. The master's id is the same as the first
- // for the second stream, but the input id for the second stream is something different.
- inputParams[i].channelCount = 2;
- inputParams[i].sampleFormat = paInt16; //As needed by scratchlib
- inputParams[i].suggestedLatency = ((float)iLatencyMSec) / 1000.0f; //Latency in seconds.
- inputParams[i].hostApiSpecificStreamInfo = NULL;
-
- if (id[i] < 0 || (i > 0 && (id[1] == id[0]))) //TODO: comment this the same as the below input one.... kinda
- p_outputParams = NULL;
- else
- p_outputParams = &(outputParams[i]);
-
- if (id_input[i] < 0) //If we're not supposed to open an input device, set the pointer to be null.
- p_inputParams = NULL; //NULL input params in Pa_OpenStream means don't open the device for input.
- else
- p_inputParams = &(inputParams[i]);
-
- PaError err = paNoError;
-
- // Set up a struct containing all the data we want to pass back to the callback
- callbackStuff[i].player = this;
- callbackStuff[i].devIndex = i; //The audio device's index (NOT THE PORTAUDIO ID!!!)
-
- // Try open device using iChannelMax
- err = Pa_OpenStream(&m_pStream[i],
- p_inputParams, // Input parameters
- p_outputParams, // Output parameters
- iSrate, // Sample rate
- iFramesPerBuffer, // Frames per buffer
- paClipOff, // Stream flags
- callback, // Stream callback
- &(callbackStuff[i])); // Pointer passed to the callback function
-
- if (err == paNoError)
- m_iChannels[i] = iChannels[i];
- else
- {
- // Try open device using maximum supported channels by soundcard
- iChannels[i] = Pa_GetDeviceInfo(id[i])->maxOutputChannels;
- outputParams[i].channelCount = iChannels[i];
- err = Pa_OpenStream(&m_pStream[i],
- p_inputParams, // Input parameters
- p_outputParams, // Output parameters
- iSrate, // Sample rate
- iFramesPerBuffer, // Frames per buffer
- paClipOff, // Stream flags
- callback, // Stream callback
- &(callbackStuff[i])); // Pointer passed to the callback function
- if (err==paNoError)
- m_iChannels[i] = iChannels[i];
- }
-
- if( err != paNoError ) //*** TODO/WARNING: I don't think this block makes any sense whatsoever... - Albert April 21/07
- {
- // Try open device using only two channels
- outputParams[i].channelCount = 2;
- err = Pa_OpenStream(&m_pStream[i],
- p_inputParams, // Input parameters
- p_outputParams, // Output parameters
- iSrate, // Sample rate
- iFramesPerBuffer, // Frames per buffer
- paClipOff, // Stream flags
- callback, // Stream callback
- &(callbackStuff[i])); // Pointer passed to the callback function
- if (err==paNoError)
- {
- m_iChannels[i] = 2;
-
- // Update channel variables and config database
- if (m_iMasterLeftCh>1)
- {
- m_iMasterLeftCh = -1;
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
- }
- if (m_iMasterRigthCh>1)
- {
- m_iMasterRigthCh = -1;
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
- }
- if (m_iHeadLeftCh>1)
- {
- m_iHeadLeftCh = -1;
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
- }
- if (m_iHeadRightCh>1)
- {
- m_iHeadRightCh = -1;
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
- }
- }
- }
-
- if( err != paNoError ) //Make sure we opened the soundcard successfully.
- {
- qDebug() << "PortAudio: Open stream error: " << Pa_GetErrorText(err);
- qDebug() << "PortAudio: More error info: " << Pa_GetLastHostErrorInfo()->errorText;
-
- m_devId[i] = -1;
- m_inputDevId[i] = -1;
- m_iChannels[i] = -1;
-
- return false;
- }
-
- m_devId[i] = id[i];
- m_inputDevId[i] = id_input[i];
-
- // Update SRATE and Latency ControlObjects
- m_pControlObjectSampleRate->queueFromThread((double)iSrate);
- m_pControlObjectLatency->queueFromThread((double)iLatencyMSec);
-
- // Start stream
- err = Pa_StartStream(m_pStream[i]);
- if (err != paNoError)
- {
- qDebug() << "PortAudio: Start stream " << i << " error: " << Pa_GetErrorText(err);
- m_pStream[i] = 0;
- }
- else
- qDebug() << "PortAudio: Started stream " << i << " successfully";
-
- //If the Master and Headphone devices are the same, or the Headphone device is set to "None",
- //then we can just break out of this loop:
- /*if ((id[0] == id[1]) || (id[1] == -1))
- {
- calculateNumActiveDevices();
- return true;
- }*/
- }
- }
-
- /*
- //Print out all the information about the soundcards and their channels.
- qDebug() << "PortAudio: ==Soundcard Summary==";
- qDebug() << "Device 1 index: " << m_devId[0];
- qDebug() << "Device 2 index: " << m_devId[1];
- qDebug() << "Channels for device 1: " << m_iChannels[0];
- qDebug() << "Channels for device 2: " << m_iChannels[1];
- qDebug() << "m_iMasterLeftCh: " << m_iMasterLeftCh;
- qDebug() << "m_iMasterRightCh: " << m_iMasterRigthCh;
- qDebug() << "m_iHeadLeftCh: " << m_iHeadLeftCh;
- qDebug() << "m_iHeadRightCh: " << m_iHeadRightCh;
- */
-
- calculateNumActiveDevices();
- return true;
-}
-
-//Find out how many active/open soundcards there are.
-void PlayerPortAudio::calculateNumActiveDevices()
-{
- int count = 0;
-
- for (int i = 0; i < MAX_AUDIODEVICES; i++)
- {
- if (m_devId[i] != -1)
- count++;
- }
- m_iNumActiveDevices = count;
-}
-
-void PlayerPortAudio::close()
-{
- //waitForNextOutput.wakeAll();
-
- for (int i = 0; i < MAX_AUDIODEVICES; i++)
- {
- m_devId[i] = -1;
- m_iChannels[i] = 0;
-
- // Stop streams
- if (m_pStream[i])
- {
- PaError err = Pa_StopStream(m_pStream[i]);
- if( err != paNoError )
- qDebug() << "PortAudio: Stop stream " << i << " error: " << Pa_GetErrorText(err) << ",";
-
- // Close streams
- err = Pa_CloseStream(m_pStream[i]);
- if( err != paNoError )
- qDebug() << "PortAudio: Close stream " << i << " error: " << Pa_GetErrorText(err);
- }
-
- m_pStream[i] = 0;
- waitForNextOutput.wakeAll();
- calculateNumActiveDevices();
- }
-
- //waitForNextOutput.wakeAll();
-
- m_iMasterLeftCh = -1;
- m_iMasterRigthCh = -1;
- m_iHeadLeftCh = -1;
- m_iHeadRightCh = -1;
-}
-
-void PlayerPortAudio::setDefaults()
-{
- // Get list of interfaces
- QStringList interfaces = getInterfaces();
-
- // Set first interfaces to master left
- QStringListIterator it(interfaces);
-
- if (it.hasNext())
- {
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue((it.next())));
- }
- else
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
-
- // Set second interface to master right
- if (it.hasNext())
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue((it.next())));
- else
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
-
- // Set head left and right to none
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
-
- // Set default sample rate
- QStringList srates = getSampleRates();
- QStringListIterator itSRates(srates);
- while (it.hasNext())
- {
- QString s;
- s = itSRates.next();
- m_pConfig->set(ConfigKey("[Soundcard]","Samplerate"),ConfigValue(s));
- if ((s).toInt()>=44100)
- break;
- }
-
- // Set currently used latency in config database
- //int msec = (int)(1000.*(2.*1024.)/(2.*(float)(*it).toInt()));
- int msec = 100; // More conservative defaults
-
- m_pConfig->set(ConfigKey("[Soundcard]","Latency"), ConfigValue(msec));
-}
-
-QStringList PlayerPortAudio::getInterfaces()
-{
- //qDebug() << "PortAudio: getInterfaces()";
-
- QStringList result;
- const PaHostApiInfo * apiInfo = NULL;
- const PaDeviceInfo * devInfo = NULL;
- QString api;
-
- if (m_HostAPI == "None")
- return result;
-
- PaDeviceIndex numDevices = Pa_GetDeviceCount();
-
- for (int i = 0; i < numDevices; i++)
- {
- devInfo = Pa_GetDeviceInfo(i);
-
- // Add the device if it is an output device:
- //if (devInfo != NULL && devInfo->maxOutputChannels > 0)
- if (devInfo != NULL)
- {
- apiInfo = Pa_GetHostApiInfo(devInfo->hostApi);
- //api = apiInfo->name;
- //qDebug() << "Api name: " << apiInfo->name;
- qDebug() << devInfo->name;
- //qDebug() << "m_HostAPI: " << m_HostAPI << "devInfo->hostApi: " << new QString(devInfo->hostApi);
-
- //... and make sure the interface matches the API we've selected.
- if (m_HostAPI == apiInfo->name)
- {
- //qDebug() << "name " << devInfo->name << ", API " << devInfo->hostApi << ", maxOutputChannels: " << devInfo->maxOutputChannels;
-
- for (int j=1; j <= devInfo->maxOutputChannels; ++j)
- result.append(QString("%1 (channel %2)").arg(devInfo->name).arg(j));
- }
- }
- }
- //qDebug() << "PortAudio: getInterfaces() end";
- return result;
-}
-
-/**
- * Get the audio input/capture interfaces from PortAudio
- */
-QStringList PlayerPortAudio::getInputInterfaces()
-{
- qDebug() << "PortAudio: getInputInterfaces()";
-
- QStringList result;
- const PaHostApiInfo * apiInfo = NULL;
- const PaDeviceInfo * devInfo = NULL;
- QString api;
-
- if (m_HostAPI == "None")
- return result;
-
- PaDeviceIndex numDevices = Pa_GetDeviceCount();
-
- for (int i = 0; i < numDevices; i++)
- {
- devInfo = Pa_GetDeviceInfo(i);
-
- // Add the device if it is an input device:
- //if (devInfo != NULL && devInfo->maxOutputChannels > 0)
- if (devInfo != NULL && (devInfo->maxInputChannels > 0))
- {
- apiInfo = Pa_GetHostApiInfo(devInfo->hostApi);
- //api = apiInfo->name;
- qDebug() << "Api name: " << apiInfo->name;
- qDebug(devInfo->name);
- //qDebug() << "m_HostAPI: " << m_HostAPI << "devInfo->hostApi: " << new QString(devInfo->hostApi);
-
- //... and make sure the interface matches the API we've selected.
- if (m_HostAPI == apiInfo->name )
- {
- qDebug() << "name " << devInfo->name << ", API " << devInfo->hostApi << ", maxInputChannels: " << devInfo->maxInputChannels;
-
- result.append(QString("%1").arg(devInfo->name));
-
- //for (int j=1; j <= devInfo->maxInputChannels; ++j)
- // result.append(QString("%1 (channel %2)").arg(devInfo->name).arg(j));
- }
- }
- }
- qDebug() << "PortAudio: getInputInterfaces() end";
- return result;
-}
-
-
-QStringList PlayerPortAudio::getSampleRates()
-{
- // Returns a sorted list of supported sample rates of the currently opened device.
- // If no device is open, return the list of sample rates supported by the
- // default device
- qDebug() << "PortAudio: getSampleRates()";
-
- PaError err;
- PaDeviceIndex id = m_devId[0]; //TODO: This is a hack to pick the samplerates from the first soundcard....
- //Figure out something smarter...
- //Something smarter = poll the samplerates from both soundcards, and
- //only display the samlerates that are supported by both. - Albert April 30, 2007
- //The problem with doing this right now is that Pa_IsFormatSupported when using
- //ALSA takes ages for some reason, and polling both soundcards here would
- //double this 5 second freeze that Mixxx experiences because of Pa_IsFormatSupported
- //(buggily) blocking.
- //qDebug() << "m_devId[0]: " << m_devId[0];
- if (id<0)
- id = Pa_GetDefaultOutputDevice();
-
- //const PaDeviceInfo *devInfo = Pa_GetDeviceInfo(id);
-
- PaStreamParameters outputParams;
- outputParams.device = id;
- outputParams.channelCount = 2;
- outputParams.sampleFormat = paFloat32;
- outputParams.suggestedLatency = .150; //Latency in seconds.
- outputParams.hostApiSpecificStreamInfo = NULL;
-
- Q3ValueList desiredSampleRates; //A list of all the sample rates we're going to suggest.
- Q3ValueList validSampleRates; //A list containing all the supported sample rates.
-
- //Here's all the sample rates we're going to suggest to PortAudio. We check which ones
- //are actually supported below.
- desiredSampleRates.append(11025.0);
- desiredSampleRates.append(22050.0);
- desiredSampleRates.append(44100.0);
- desiredSampleRates.append(48000.0);
- desiredSampleRates.append(96000.0);
-
- // Sample rates
- //if (devInfo)
- {
- for (unsigned int j=0; j < desiredSampleRates.count(); j++)
- {
- //Check if each sample rate is supported, if so, add them to the list of supported sample rates.
- qDebug() << "PortAudio: checking if sample rate is supported...";
- err = Pa_IsFormatSupported(NULL, &outputParams, desiredSampleRates[j]);
- if (err == paFormatIsSupported) //The format IS supported.
- {
- validSampleRates.append(desiredSampleRates[j]);
- qDebug() << "Supported...";
- }
- else
- {
- qDebug() << "PortAudio error: " << Pa_GetErrorText(err) << ", id was: " << id;
- }
- }
- }
-
- //If for some reason our enumeration of the sample rates failed, throw
- //in some default values. (PortAudio might be being sketchy...)
- if (validSampleRates.count() == 0)
- {
- validSampleRates.append(44100.0);
- validSampleRates.append(48000.0);
- validSampleRates.append(96000.0);
- }
-
- // Sort list
-#ifndef QT3_SUPPORT
- qSort(validSampleRates);
-#endif
-
- // Convert srlist to stringlist
- QStringList result;
- for (unsigned int i = 0; i < validSampleRates.count(); ++i)
- result.append(QString("%1").arg((*validSampleRates.at(i))));
-
- qDebug() << "PortAudio: getSampleRates() end";
-
- return result;
-}
-
-QStringList PlayerPortAudio::getSoundApiList()
-{
- //Note: Need to put the active API at the top of the list.
- QStringList apiList;
- const PaHostApiInfo * apiInfo = NULL;
-
- //We need to initialize PortAudio before we find out what APIs are present.
- //Even if this gets called while PortAudio is already initialized, the docs
- //say this is OK (I think...).
-
- PaError err = paNoError;
-
- // So this little hackfest saves buggy drivers from being really buggy - AD
- if (!m_painited) {
- err = Pa_Initialize();
- m_painited = true;
- }
-
- if (err == paNoError)
- {
- for (int i = 0; i < Pa_GetHostApiCount(); i++)
- {
- apiInfo = Pa_GetHostApiInfo(i);
- //qDebug() << "Api name: " << apiInfo->name;
- apiList.append(apiInfo->name);
- }
-// Pa_Terminate();
- }
- else
- qDebug() << "PortAudio error: " << Pa_GetErrorText(err);
-
- return apiList;
-
- /*
- #ifdef __LINUX__
- return QStringList("OSS (PA)");
- #endif
- #ifdef __MACX__
- return QStringList("CoreAudio (PA)");
- #endif
- #ifdef __WIN__
- return QStringList("WMME (PA)");
- #endif
- */
-
-}
-
-
-PaDeviceIndex PlayerPortAudio::getDeviceID(QString name)
-{
- //qDebug() << "PortAudio: getDeviceID(" + name + ")";
- PaDeviceIndex no = Pa_GetDeviceCount();
- for (int i=0; imaxOutputChannels > 0)
- {
- for (int j = 1; j <= devInfo->maxOutputChannels; ++j)
- if (QString("%1 (channel %2)").arg(devInfo->name).arg(j) == name)
- {
- //qDebug() << "PortAudio: getDeviceID(" + name + "), returning device id " << i;
- return i;
- }
- }
- }
- return -1;
-}
-
-
-PaDeviceIndex PlayerPortAudio::getInputDeviceID(QString name)
-{
- qDebug() << "PortAudio: getInputDeviceID(" + name + ")";
- PaDeviceIndex no = Pa_GetDeviceCount();
- for (int i=0; imaxOutputChannels > 0)
- {
- for (int j = 1; j <= devInfo->maxInputChannels; ++j)
- {
- //qDebug() << "Comparing: " << QString("%1").arg(devInfo->name);
- //qDebug() << "and: " << name;
- if (QString("%1").arg(devInfo->name) == name)
- {
- qDebug() << "PortAudio: getInputDeviceID(" + name + "), returning device id " << i;
- return i;
- }
- }
- }
- }
- qDebug() << "PortAudio: getInputDeviceID(" + name + "), returning device id -1";
- return -1;
-}
-
-PaDeviceIndex PlayerPortAudio::getChannelNo(QString name)
-{
- PaDeviceIndex no = Pa_GetDeviceCount();
- for (int i=0; imaxOutputChannels > 0)
- {
- for (int j=1; j<=devInfo->maxOutputChannels; ++j)
- if (QString("%1 (channel %2)").arg(devInfo->name).arg(j) == name)
- return j;
- }
- }
- return -1;
-}
-
-/** -------- ------------------------------------------------------
- Purpose: This callback function gets called everytime a soundcard runs out of samples to play.
- This is where the soundcard/PortAudio ask Mixxx for more samples, and get them in
- an orderly fashion (*thread safety). This is also where the "routing" of audio samples
- take place.
- -------- ------------------------------------------------------
- */
-int PlayerPortAudio::callbackProcess(unsigned long framesPerBuffer, float * out, short * in, int devIndex)
-{
- //if (m_iBufferSize==0)
- // m_iBufferSize = iBufferSize*m_iNumberOfBuffers;
-
- static float * tmp; //Leave this as static - it's shared between two threads.
- float * output = out;
- int i;
-
- /*
- if (!out)
- {
- qDebug() << "output is NULL!";
- prevDevice.lock();
- m_iPreviousDevIndex = devIndex; //Save this devIndex as the previous one
- prevDevice.unlock();
- waitForNextOutput.wakeAll(); //Allow the other thread to give at 'er
- return 0;
- }*/
-
- prevDevice.lock();
- int iPreviousDevIndex = m_iPreviousDevIndex;
- prevDevice.unlock();
-
- if (iPreviousDevIndex == devIndex && m_iNumActiveDevices > 1)
- {
- lockSamples.lock();
- waitForNextOutput.wait(&lockSamples);
- lockSamples.unlock();
- }
-
- //Only fill the buffer with sound data from Mixxx once.
- lockSamples.lock();
- if (devIndex == 0)
- {
- tmp = prepareBuffer(iBufferSize);
- }
- lockSamples.unlock();
-
- // Reset sample for each open channel
- for (i=0; i=0 && m_iChannels[devIndex]>=1) { output[m_iMasterLeftCh] += tmp[(i*4) ]/32768.;}
- if (m_iMasterRigthCh>=0 && m_iChannels[devIndex]>=2) output[m_iMasterRigthCh] += tmp[(i*4)+1]/32768.;
- if (m_iHeadLeftCh>=0 && m_iChannels[devIndex]>=3) output[m_iHeadLeftCh] += tmp[(i*4)+2]/32768.;
- if (m_iHeadRightCh>=0 && m_iChannels[devIndex]>=4) output[m_iHeadRightCh] += tmp[(i*4)+3]/32768.;
- }
- else if (devIndex == 1) //If there's a second sound device, route the headphones to it.
- {
- //if (m_iMasterLeftCh>=0 && m_iChannels[devIndex]>=1) { output[m_iMasterLeftCh] += tmp[(i*4) ]/32768.;}
- //if (m_iMasterRigthCh>=0 && m_iChannels[devIndex]>=2) output[m_iMasterRigthCh] += tmp[(i*4)+1]/32768.;
- //qDebug() << "m_iHeadLeftCh:" << m_iHeadLeftCh << "devIndex: " << devIndex << "tmp[blah]" << tmp[(i*4)+2]/32768.;
- if (m_iHeadLeftCh>=0 && m_iChannels[devIndex]>=1) output[m_iHeadLeftCh] += tmp[(i*4)+2]/32768.;
- if (m_iHeadRightCh>=0 && m_iChannels[devIndex]>=2) output[m_iHeadRightCh] += tmp[(i*4)+3]/32768.;
- //qDebug() << "headphones!";
- }
- for (int j=0; j < m_iChannels[devIndex]; ++j)
- *output++;
- }
-
- if (in)
- {
-#ifdef __VINYLCONTROL__
- m_VinylControl[devIndex]->AnalyseSamples(in, iBufferSize);
-#endif
- }
-
- prevDevice.lock();
- m_iPreviousDevIndex = devIndex; //Save this devIndex as the previous one
- prevDevice.unlock();
- waitForNextOutput.wakeAll(); //Allow the other thread to give at 'er
-
- return 0;
-}
-
-
-/* -------- ------------------------------------------------------
- Purpose: Wrapper function to call processing loop function,
- implemented as a method in a class. Used in PortAudio,
- which knows nothing about C++.
- Input: .
- Output: -
- -------- ------------------------------------------------------ */
-int paV19Callback(const void * inputBuffer, void * outputBuffer,
- unsigned long framesPerBuffer,
- const PaStreamCallbackTimeInfo * timeInfo,
- PaStreamCallbackFlags statusFlags,
- void * _callbackStuff)
-{
- /*
- //Variables that are used in the human-readable form of function call from hell (below).
- static PlayerPortAudio* _player;
- static int devIndex;
- _player = ((PAPlayerCallbackStuff*)_callbackStuff)->player;
- devIndex = ((PAPlayerCallbackStuff*)_callbackStuff)->devIndex;
- */
-
- //Human-readable form of the function call from hell:
- //return _player->callbackProcess(framesPerBuffer, (float *)outputBuffer, devIndex);
-
- //Function call from hell (might provide a little bit of cheapo thread safety to do it this way):
- return ((PAPlayerCallbackStuff *)_callbackStuff)->player->callbackProcess(framesPerBuffer, (float *)outputBuffer, (short *)inputBuffer, ((PAPlayerCallbackStuff *)_callbackStuff)->devIndex);
-}
-
diff -Nru mixxx-1.6.0/src/playerportaudio.h mixxx-1.6.1/src/playerportaudio.h
--- mixxx-1.6.0/src/playerportaudio.h 2007-08-21 23:16:40.000000000 -0500
+++ mixxx-1.6.1/src/playerportaudio.h 1969-12-31 18:00:00.000000000 -0600
@@ -1,109 +0,0 @@
-/***************************************************************************
- playerportaudiov19.h - description
- -------------------
- begin : Wed Feb 20 2002
- copyright : (C) 2002 by Tue and Ken Haste Andersen
- email :
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. *
- * *
- ***************************************************************************/
-
-#ifndef PLAYERPORTAUDIO_H
-#define PLAYERPORTAUDIO_H
-
-#include
-#include
-#include
-#include
-#include "player.h"
-#include "portaudio.h"
-#ifdef __VINYLCONTROL__
-#include "vinylcontrolproxy.h"
-#endif
-
-/**
- *@author Tue and Ken Haste Andersen
- */
-
-/** Maximum frame size used with PortAudio. Used to determine no of buffers
- * when setting latency */
-const int kiMaxFrameSize = 1024;
-
-class PlayerPortAudio; //Forward declaration
-
-/** A struct to some stuff we need to pass along to the callback through PortAudio **/
-struct PAPlayerCallbackStuff
-{
- PlayerPortAudio* player;
- int devIndex;
-};
-
-class PlayerPortAudio : public Player {
-public:
- PlayerPortAudio(ConfigObject *config, QString api_name);
- ~PlayerPortAudio();
- bool initialize();
- bool open();
- void close();
- void setDefaults();
- QStringList getInterfaces();
- QStringList getInputInterfaces();
- QStringList getSampleRates();
- static QStringList getSoundApiList();
- QString getSoundApiName() { return getSoundApiList().front(); };
- void calculateNumActiveDevices();
- /** Satisfy virtual declaration in EngineObject */
- void process(const CSAMPLE *, const CSAMPLE *, const int) {};
- /** Process samples. Called from PortAudio callback */
- int callbackProcess(int iBufferSize, float *out, short *in, int devIndex);
-
- static bool m_painited;
-protected:
- /** Get id of device with a given name. Returns -1 if device is not found */
- PaDeviceIndex getDeviceID(QString name);
- PaDeviceIndex getInputDeviceID(QString name);
- /** Get channel number of device with a given name. Returns -1 if device is not found */
- int getChannelNo(QString name);
-
- /** PortAudio stream */
- PaStream *m_pStream[MAX_AUDIODEVICES];
- /** Id of currently open device. -1 if no device is open */
- PaDeviceIndex m_devId[MAX_AUDIODEVICES];
- PaDeviceIndex m_inputDevId[MAX_AUDIODEVICES]; //For input devices
- /** Channels used for each output from Mixxx. Set to -1 when not in use */
- int m_iMasterLeftCh, m_iMasterRigthCh, m_iHeadLeftCh, m_iHeadRightCh;
- /** True if PortAudio was sucessfully initialized */
- bool m_bInit;
- /** A struct to hold some information/pointers we need to pass to our callback function */
- PAPlayerCallbackStuff callbackStuff[MAX_AUDIODEVICES];
- /** Number of buffers */
- int m_iNumberOfBuffers;
- /** Number of active/open soundcards **/
- int m_iNumActiveDevices;
- /** Name of the current audio API inside PortAudio **/
- QString m_HostAPI;
- /** Mutex so that two threads don't try to prepare a new buffer full of samples from Mixxx at the same time */
- QMutex lockSamples;
- /** Wait condition that forces multiple PortAudio callbacks in separate threads to play nicely */
- QWaitCondition waitForNextOutput;
- QMutex waitMutex;
- int m_iPreviousDevIndex;
- QMutex prevDevice;
-#ifdef __VINYLCONTROL__
- VinylControlProxy *m_VinylControl[2];
-#endif
-};
-
-int paV19Callback(const void *inputBuffer, void *outputBuffer,
- unsigned long framesPerBuffer,
- const PaStreamCallbackTimeInfo* timeInfo,
- PaStreamCallbackFlags statusFlags,
- void *_player);
-#endif
diff -Nru mixxx-1.6.0/src/playerproxy.cpp mixxx-1.6.1/src/playerproxy.cpp
--- mixxx-1.6.0/src/playerproxy.cpp 2007-09-09 17:52:24.000000000 -0500
+++ mixxx-1.6.1/src/playerproxy.cpp 1969-12-31 18:00:00.000000000 -0600
@@ -1,189 +0,0 @@
-/***************************************************************************
- playerproxy.cpp - description
- -------------------
- begin : Fri Nov 21 2003
- copyright : (C) 2003 by Tue and Ken Haste Andersen
- email :
-***************************************************************************/
-
-/***************************************************************************
-* *
-* 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. *
-* *
-***************************************************************************/
-
-#include "playerproxy.h"
-
-#ifdef __PORTAUDIO__
- #include "playerportaudio.h"
-#endif
-#ifdef __JACK__
- #include "playerjack.h"
-#endif
-#ifdef __RTAUDIO__
- #include "playerrtaudio.h"
-#endif
-#ifdef __ASIO__
- #include "playerasio.h"
-#endif
-#ifdef __ALSA__
- #include "playeralsa.h"
-#endif
-
-Player * PlayerProxy::m_pPlayer = 0;
-
-PlayerProxy::PlayerProxy(ConfigObject * pConfig) : Player(pConfig)
-{
- // Set API based on info stored in config database
- setSoundApi(m_pConfig->getValueString(ConfigKey("[Soundcard]","SoundApi")));
-
- if (!m_pPlayer)
- {
- // No valid API is stored in the database, so select the default
- QStringList api = getSoundApiList();
- QStringList::iterator it = api.begin();
- while (!m_pPlayer && it!=api.end())
- {
- if (setSoundApi((*it)))
- {
- m_pConfig->set(ConfigKey("[Soundcard]","SoundApi"), ConfigValue((*it)));
- m_pPlayer->setDefaults();
- }
- *it++;
- }
- }
-}
-
-PlayerProxy::~PlayerProxy()
-{
- if (m_pPlayer)
- delete m_pPlayer;
-}
-
-bool PlayerProxy::open()
-{
- if (m_pPlayer)
- return m_pPlayer->open();
- else
- return false;
-}
-
-void PlayerProxy::close()
-{
- if (m_pPlayer)
- m_pPlayer->close();
-}
-
-void PlayerProxy::setDefaults()
-{
- if (m_pPlayer)
- m_pPlayer->setDefaults();
-}
-
-QStringList PlayerProxy::getInterfaces()
-{
- if (m_pPlayer)
- return m_pPlayer->getInterfaces();
- else
- return QStringList();
-}
-
-QStringList PlayerProxy::getInputInterfaces()
-{
- if (m_pPlayer)
- return m_pPlayer->getInputInterfaces();
- else
- return QStringList();
-}
-
-QStringList PlayerProxy::getSampleRates()
-{
- if (m_pPlayer)
- return m_pPlayer->getSampleRates();
- else
- return QStringList();
-}
-
-QString PlayerProxy::getSoundApiName()
-{
- if (m_pPlayer)
- return m_pPlayer->getSoundApiName();
- else
- return QString();
-}
-
-
-QStringList PlayerProxy::getSoundApiList()
-{
- QStringList result;
-#ifdef __PORTAUDIO__
- result += PlayerPortAudio::getSoundApiList();
-#endif
-#ifdef __JACK__
- result.append(PlayerJack::getSoundApi());
-#endif
-#ifdef __RTAUDIO__
- result.append(PlayerRtAudio::getSoundApi());
-#endif
-#ifdef __ASIO__
- result.append(PlayerAsio::getSoundApi());
-#endif
-#ifdef __ALSA__
- result.append(PlayerALSA::getSoundApi());
-#endif
-
- return result;
-}
-
-bool PlayerProxy::setSoundApi(QString name)
-{
- if (m_pPlayer)
- delete m_pPlayer;
- m_pPlayer = 0;
-
-#ifdef __PORTAUDIO__
- if (PlayerPortAudio::getSoundApiList().contains(name))
- m_pPlayer = new PlayerPortAudio(m_pConfig, name);
-#endif
-
-#ifdef __JACK__
- if (name == PlayerJack::getSoundApi())
- m_pPlayer = new PlayerJack(m_pConfig);
-#endif
-
-#ifdef __RTAUDIO__
- if (name == PlayerRtAudio::getSoundApi())
- m_pPlayer = new PlayerRtAudio(m_pConfig);
-#endif
-
-#ifdef __ASIO__
- if (name == PlayerAsio::getSoundApi())
- m_pPlayer = new PlayerAsio(m_pConfig);
-#endif
-
-#ifdef __ALSA__
- if (name == PlayerALSA::getSoundApi())
- m_pPlayer = new PlayerALSA(m_pConfig);
-#endif
-
- // Try initializing the selected API
- bool init = false;
- if (m_pPlayer)
- init = m_pPlayer->initialize();
-
- if (!init)
- {
- if (m_pPlayer)
- delete m_pPlayer;
- m_pPlayer = 0;
- }
-
- if (m_pPlayer)
- return true;
- else
- return false;
-}
-
diff -Nru mixxx-1.6.0/src/playerproxy.h mixxx-1.6.1/src/playerproxy.h
--- mixxx-1.6.0/src/playerproxy.h 2007-08-21 23:16:40.000000000 -0500
+++ mixxx-1.6.1/src/playerproxy.h 1969-12-31 18:00:00.000000000 -0600
@@ -1,54 +0,0 @@
-/***************************************************************************
- playerproxy.h - description
- -------------------
- begin : Fri Nov 21 2003
- copyright : (C) 2003 by Tue Haste Andersen
- email :
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. *
- * *
- ***************************************************************************/
-
-#ifndef PLAYERPROXY_H
-#define PLAYERPROXY_H
-
-#include "player.h"
-
-class PlayerProxy : public Player
-{
-public:
- PlayerProxy(ConfigObject *pConfig);
- ~PlayerProxy();
- bool initialize() { return false; };
- bool open();
- void close();
- void setDefaults();
- QStringList getInterfaces();
- QStringList getInputInterfaces();
- QStringList getSampleRates();
- QString getSoundApiName();
- /** Return list of supported sound api's */
- static QStringList getSoundApiList();
- /** Select active sound api */
- bool setSoundApi(QString name);
- /** Satisfy virtual declaration in EngineObject */
- void process(const CSAMPLE *, const CSAMPLE *, const int) {};
- /** Static function to return active player class. Needed for ASIO implementation */
- static Player *getPlayer() { return m_pPlayer; }
-
-protected:
- /** Pointer to active Player class */
- static Player *m_pPlayer;
-};
-
-#endif
-
-
-
-
diff -Nru mixxx-1.6.0/src/playerrtaudio.cpp mixxx-1.6.1/src/playerrtaudio.cpp
--- mixxx-1.6.0/src/playerrtaudio.cpp 2008-03-27 00:04:43.000000000 -0500
+++ mixxx-1.6.1/src/playerrtaudio.cpp 1969-12-31 18:00:00.000000000 -0600
@@ -1,442 +0,0 @@
-/***************************************************************************
- playerrtaudio.cpp - description
- -------------------
- begin : Thu May 20 2004
- copyright : (C) 2002 by Tue and Ken Haste Andersen
- email :
-***************************************************************************/
-
-/***************************************************************************
-* *
-* 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. *
-* *
-***************************************************************************/
-
-#include "playerrtaudio.h"
-#include "controlobject.h"
-
-/** Maximum frame size used with RtAudio. Used to determine no of buffers
- * when setting latency */
-const int kiMaxFrameSize = 64;
-
-
-PlayerRtAudio::PlayerRtAudio(ConfigObject * config) : Player(config)
-{
- m_pRtAudio = 0;
- m_bInit = false;
-
- m_devId = -1;
- m_iNumberOfBuffers = 2;
- m_iChannels = -1;
- m_iMasterLeftCh = -1;
- m_iMasterRigthCh = -1;
- m_iHeadLeftCh = -1;
- m_iHeadRightCh = -1;
-}
-
-PlayerRtAudio::~PlayerRtAudio()
-{
- if (m_devId>=1)
- {
- try {
- m_pRtAudio->stopStream();
- m_pRtAudio->closeStream();
- }
- catch (RtError &error)
- {
- error.printMessage();
- }
- }
-
- if (m_bInit)
- delete m_pRtAudio;
-}
-
-bool PlayerRtAudio::initialize()
-{
- try {
- m_pRtAudio = new RtAudio();
- }
- catch (RtError &error)
- {
- error.printMessage();
- m_pRtAudio = 0;
- m_bInit = false;
- }
- m_bInit = true;
-
- return m_bInit;
-}
-
-bool PlayerRtAudio::open()
-{
- Player::open();
-
- // Find out which device to open. Select the first one listed as either Master Left,
- // Master Right, Head Left, Head Right. If other devices are requested for opening
- // than the one selected here, set them to "None" in the config database
- int id = -1;
- int temp = -1;
- QString name;
- /** Maximum number of channels needed */
- int iChannelMax = -1;
-
- m_iMasterLeftCh = -1;
- m_iMasterRigthCh = -1;
- m_iHeadLeftCh = -1;
- m_iHeadRightCh = -1;
-
- // Master left
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterLeft"));
- temp = getDeviceID(name);
- if (temp>=0)
- {
- if (getChannelNo(name)>=0)
- {
- id = temp;
- iChannelMax = getChannelNo(name);
- m_iMasterLeftCh = getChannelNo(name)-1;
- }
- }
-
- // Master right
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceMasterRight"));
- temp = getDeviceID(name);
- if (getChannelNo(name)>=0 && ((id==-1 && temp>=0) || (temp!=-1 && id==temp)))
- {
- id = temp;
- iChannelMax = math_max(iChannelMax, getChannelNo(name));
- m_iMasterRigthCh = getChannelNo(name)-1;
- }
-
- // Head left
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceHeadLeft"));
- temp = getDeviceID(name);
- if (getChannelNo(name)>=0 && ((id==-1 && temp>=0) || (temp!=-1 && id==temp)))
- {
- id = temp;
- iChannelMax = math_max(iChannelMax, getChannelNo(name));
- m_iHeadLeftCh = getChannelNo(name)-1;
- }
-
- // Head right
- name = m_pConfig->getValueString(ConfigKey("[Soundcard]","DeviceHeadRight"));
- temp = getDeviceID(name);
- if (getChannelNo(name)>=0 && ((id==-1 && temp>=0) || (temp!=-1 && id==temp)))
- {
- id = temp;
- iChannelMax = math_max(iChannelMax, getChannelNo(name));
- m_iHeadRightCh = getChannelNo(name)-1;
- }
-
- // Check if any of the devices in the config database needs to be set to "None"
- if (m_iMasterLeftCh<0)
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
- if (m_iMasterRigthCh<0)
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
- if (m_iHeadLeftCh<0)
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
- if (m_iHeadRightCh<0)
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
-
- // Number of channels to open
- int iChannels = iChannelMax;
-
- // Sample rate
- int iSrate = m_pConfig->getValueString(ConfigKey("[Soundcard]","Samplerate")).toInt();
-
- // Get latency in msec
- int iLatencyMSec = m_pConfig->getValueString(ConfigKey("[Soundcard]","Latency")).toInt();
-
- // Latency in samples
- int iLatencySamples = (int)((float)(iSrate*iChannels)/1000.f*(float)iLatencyMSec);
-
- // Apply simple rule to determine number of buffers
- if (iLatencySamples/kiMaxFrameSize<2)
- m_iNumberOfBuffers = 2;
- else
- m_iNumberOfBuffers = iLatencySamples/kiMaxFrameSize;
-
- // Frame size...
- int iFramesPerBuffer = iLatencySamples/m_iNumberOfBuffers;
-
- qDebug() << "RtAudio: id " << id << ", sr " << iSrate << ", ch " << iChannels << ", bufsize " << iFramesPerBuffer << ", bufno " << m_iNumberOfBuffers;
-
- if (id<1)
- {
- m_devId = -1;
- return false;
- }
-
- // Start playback
- try
- {
- // Update SRATE and Latency ControlObjects
- m_pControlObjectSampleRate->queueFromThread((double)iSrate);
- m_pControlObjectLatency->queueFromThread((double)iLatencyMSec);
-
- // Open stream
- m_pRtAudio->openStream(id, iChannels, 0, 0, RTAUDIO_FLOAT32, iSrate, &iFramesPerBuffer, m_iNumberOfBuffers);
-
- // Set callback function
- m_pRtAudio->setStreamCallback(&rtCallback, (void *)this);
-
- m_iChannels = iChannels;
- m_devId = id;
-
- // Start playback
- m_pRtAudio->startStream();
- }
- catch (RtError &error)
- {
- error.printMessage();
-
- m_devId = -1;
- m_iChannels = -1;
-
- return false;
- }
-
- return true;
-}
-
-void PlayerRtAudio::close()
-{
- m_iChannels = 0;
- m_iMasterLeftCh = -1;
- m_iMasterRigthCh = -1;
- m_iHeadLeftCh = -1;
- m_iHeadRightCh = -1;
-
- if (m_devId>0)
- {
- qDebug() << "close";
- try
- {
- m_pRtAudio->stopStream();
- m_pRtAudio->closeStream();
- }
- catch (RtError &error)
- {
- error.printMessage();
- }
- }
- m_devId = -1;
-}
-
-void PlayerRtAudio::setDefaults()
-{
- // Get list of interfaces
- QStringList interfaces = getInterfaces();
-
- // Set first interfaces to master left
- QStringList::iterator it = interfaces.begin();
- if (it!=interfaces.end())
- {
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue((*it)));
- }
- else
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterLeft"),ConfigValue("None"));
-
- // Set second interface to master right
- ++it;
- if (it!=interfaces.end())
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue((*it)));
- else
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceMasterRight"),ConfigValue("None"));
-
- // Set head left and right to none
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadLeft"),ConfigValue("None"));
- m_pConfig->set(ConfigKey("[Soundcard]","DeviceHeadRight"),ConfigValue("None"));
-
- // Set default sample rate
- QStringList srates = getSampleRates();
- it = srates.begin();
- while (it!=srates.end())
- {
- m_pConfig->set(ConfigKey("[Soundcard]","Samplerate"),ConfigValue((*it)));
-
- if ((*it).toInt()>=44100)
- break;
-
- ++it;
- }
-
- // Set currently used latency in config database
- int msec = (int)(1000.*(2.*1024.)/(2.*(float)(*it).toInt()));
- m_pConfig->set(ConfigKey("[Soundcard]","Latency"), ConfigValue(msec));
-}
-
-QStringList PlayerRtAudio::getInterfaces()
-{
- QStringList result;
-
- int no = m_pRtAudio->getDeviceCount();
- RtAudioDeviceInfo info;
- for (int i=1; i<=no; i++)
- {
- bool bGotInfo = false;
- try {
- info = m_pRtAudio->getDeviceInfo(i);
- bGotInfo = true;
- }
- catch (RtError &error)
- {
- error.printMessage();
- }
-
- // Add the device if it is an output device:
- if (bGotInfo && info.outputChannels > 0)
- {
- qDebug() << "name " << info.name.c_str();
- for (int j=1; j<=info.outputChannels; ++j)
- result.append(QString("%1 (channel %2)").arg(info.name.c_str()).arg(j));
- }
- }
-
- return result;
-}
-
-QStringList PlayerRtAudio::getSampleRates()
-{
- // Returns the list of supported sample rates of the currently opened device.
- // If no device is open, return the list of sample rates supported by the
- // default device
- int id = m_devId;
- if (id<1)
- id = 1;
-
- RtAudioDeviceInfo info;
- try {
- info = m_pRtAudio->getDeviceInfo(id);
- }
- catch (RtError &error)
- {
- error.printMessage();
- return QStringList();
- }
-
- // Sample rates
- QValueList srlist;
-
- if (info.sampleRates.size() > 0)
- {
- for (unsigned int j=0; jgetDeviceCount();
- for (int i=1; i<=no; i++)
- {
- RtAudioDeviceInfo info;
- try {
- info = m_pRtAudio->getDeviceInfo(i);
- }
- catch (RtError &error)
- {
- error.printMessage();
- return -1;
- }
-
- // Add the device if it is an output device:
- if (info.outputChannels > 0)
- {
- for (int j=1; j<=info.outputChannels; ++j)
- if (QString("%1 (channel %2)").arg(info.name.c_str()).arg(j) == name)
- return i;
- }
- }
- return -1;
-}
-
-int PlayerRtAudio::getChannelNo(QString name)
-{
- int no = m_pRtAudio->getDeviceCount();
- for (int i=1; i<=no; i++)
- {
- RtAudioDeviceInfo info;
- try {
- info = m_pRtAudio->getDeviceInfo(i);
- }
- catch (RtError &error)
- {
- error.printMessage();
- return -1;
- }
-
- // Add the device if it is an output device:
- if (info.outputChannels > 0)
- {
- for (int j=1; j<=info.outputChannels; ++j)
- if (QString("%1 (channel %2)").arg(info.name.c_str()).arg(j) == name)
- return j;
- }
- }
- return -1;
-}
-
-int PlayerRtAudio::callbackProcess(int iBufferSize, float * out)
-{
- //m_iBufferSize = iBufferSize*m_iNumberOfBuffers;
-
- float * tmp = prepareBuffer(iBufferSize);
- float * output = out;
- int i;
-
- // Reset sample for each open channel
- for (i=0; i=0) output[m_iMasterLeftCh] += tmp[(i*4) ]/32768.;
- if (m_iMasterRigthCh>=0) output[m_iMasterRigthCh] += tmp[(i*4)+1]/32768.;
- if (m_iHeadLeftCh>=0) output[m_iHeadLeftCh] += tmp[(i*4)+2]/32768.;
- if (m_iHeadRightCh>=0) output[m_iHeadRightCh] += tmp[(i*4)+3]/32768.;
-
- for (int j=0; jcallbackProcess(framesPerBuffer, (float *)outputBuffer);
-}
diff -Nru mixxx-1.6.0/src/playerrtaudio.h mixxx-1.6.1/src/playerrtaudio.h
--- mixxx-1.6.0/src/playerrtaudio.h 2005-03-03 06:01:40.000000000 -0600
+++ mixxx-1.6.1/src/playerrtaudio.h 1969-12-31 18:00:00.000000000 -0600
@@ -1,65 +0,0 @@
-/***************************************************************************
- playerrtaudio.h - description
- -------------------
- begin : Thu May 20 2004
- copyright : (C) 2002 by Tue and Ken Haste Andersen
- email :
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. *
- * *
- ***************************************************************************/
-
-#ifndef PLAYERRTAUDIO_H
-#define PLAYERRTAUDIO_H
-
-#include "player.h"
-#include
-
-/**
- *@author Tue and Ken Haste Andersen
- */
-
-
-class PlayerRtAudio : public Player {
-public:
- PlayerRtAudio(ConfigObject *config);
- ~PlayerRtAudio();
- bool initialize();
- bool open();
- void close();
- void setDefaults();
- QStringList getInterfaces();
- QStringList getSampleRates();
- static QString getSoundApi();
- QString getSoundApiName() { return getSoundApi(); };
- /** Satisfy virtual declaration in EngineObject */
- void process(const CSAMPLE *, const CSAMPLE *, const int) {};
- /** Process samples. Called from RtAudio callback */
- int callbackProcess(int iBufferSize, float *out);
-
-protected:
- /** Pointer to RtAudio object */
- RtAudio *m_pRtAudio;
- /** Get id of device with a given name. Returns -1 if device is not found */
- int getDeviceID(QString name);
- /** Get channel number of device with a given name. Returns -1 if device is no found */
- int getChannelNo(QString name);
- /** Id of currently open device. -1 if no device is open */
- int m_devId;
- /** Channels used for each output from Mixxx. Set to -1 when not in use */
- int m_iMasterLeftCh, m_iMasterRigthCh, m_iHeadLeftCh, m_iHeadRightCh;
- /** True if RtAudio was sucessfully initialized */
- bool m_bInit;
- /** Number of buffers */
- int m_iNumberOfBuffers;
-};
-
-int rtCallback(char *outputBuffer, int framesPerBuffer, void *_player);
-
-#endif
diff -Nru mixxx-1.6.0/src/SConscript mixxx-1.6.1/src/SConscript
--- mixxx-1.6.0/src/SConscript 2008-07-29 10:43:09.000000000 -0500
+++ mixxx-1.6.1/src/SConscript 2008-09-23 01:51:13.000000000 -0500
@@ -325,12 +325,19 @@
if not env.GetOption('clean') and not SCons.Util.containsAny(os.sys.argv, ['-h', '--help']):
conf = Configure(env, custom_tests = { 'CheckForPKGConfig' : CheckForPKGConfig, 'CheckForPKG' : CheckForPKG })
-
+
+# if platform == 'linux' and conf.CheckCHeader('mp4.h'):
+# print "Enabling M4A support!"
+# env.Append(CXXFLAGS = '-D__M4A__')
+# sources += Split("""soundsourcem4a.cpp """); # MP4/M4A Support
+# env.Append(LIBS = 'libmp4v2')
+# env.Append(LIBS = 'libfaad')
+
#TODO: Add all of the other configure checks as custom_tests properly.
# On Posix default SCons.LIBPREFIX = 'lib', on Windows default SCons.LIBPREFIX = ''
- if not conf.CheckLibWithHeader('portaudio', 'portaudio.h', 'C'):
+ if not conf.CheckLibWithHeader('portaudio', 'portaudio.h', 'C') and not (platform == 'win32' and conf.CheckLib(['portaudio'])):
print 'Did not find libportaudio.a, portaudio.lib, or the PortAudio-v19 development header files - exiting!'
Exit(1)
@@ -630,10 +637,23 @@
flags_ipod = getFlags(env, 'ipod', 0)
if int(flags_ipod):
env.Append(CXXFLAGS = '-D__IPOD__')
- # env.Append(LIBS = 'libgpod-1.0')
- # env.Append(LIBS = 'glib-2.0')
- env.ParseConfig('pkg-config libgpod-1.0 --silence-errors --cflags --libs')
- env.ParseConfig('pkg-config glib-2.0 --silence-errors --cflags --libs')
+
+ if platform == 'win32':
+ env.Append(LIBS = 'gpod');
+ # You must check v-this-v directory out from http://publicsvn.songbirdnest.com/vendor-binaries/trunk/windows-i686-msvc8/libgpod/
+ env.Append(LIBPATH='../../../windows-i686-msvc8/libgpod/release/lib')
+ # Following building the following must be added to the dist folder in order for mixxx to run with ipod support on Win32
+ # \windows-i686-msvc8\libgpod\release\lib\libgpod.dll
+ # \windows-i686-msvc8\glib\release\bin\libgobject-2.0-0.dll
+ # \windows-i686-msvc8\glib\release\bin\libglib-2.0-0.dll
+ # \windows-i686-msvc8\libiconv\release\bin\iconv.dll
+ # \windows-i686-msvc8\gettext\release\binintl.dll
+ if platform == 'linux' or platform == 'osx':
+ # env.Append(LIBS = 'libgpod-1.0')
+ # env.Append(LIBS = 'glib-2.0')
+ env.ParseConfig('pkg-config libgpod-1.0 --silence-errors --cflags --libs')
+ env.ParseConfig('pkg-config glib-2.0 --silence-errors --cflags --libs')
+
sources += Split("""wipodtracksmodel.cpp """) #IPOD
print "iPod support... enabled"
build_flags += 'ipod '
@@ -681,14 +701,17 @@
else:
print "Vinyl Control... disabled"
-flags_msvcdebug = getFlags(env, 'msvcdebug', 1)
-if int(flags_msvcdebug) and platform == 'win32':
- env.Append(LINKFLAGS = '/DEBUG')
- env.Append(CXXFLAGS = '/ZI')
- print "MSVC Debugging... enabled"
- build_flags += 'msvcdebug '
-else:
- print "MSVC Debugging... disabled"
+flags_msvcdebug = getFlags(env, 'msvcdebug', 0)
+if platform == 'win32':
+ if int(flags_msvcdebug):
+ env.Append(CCFLAGS = '/MDd') # required for sndfile w/ flac support on windows
+ env.Append(LINKFLAGS = '/DEBUG')
+ env.Append(CXXFLAGS = '/ZI')
+ print "MSVC Debugging... enabled"
+ build_flags += 'msvcdebug '
+ else:
+ env.Append(CCFLAGS = '/MD') # required for sndfile w/ flac support on windows
+ print "MSVC Debugging... disabled"
flags_script = getFlags(env, 'script', 0)
if int(flags_script):
@@ -1010,8 +1033,14 @@
#env.Alias('mixxx', icon)
env.Alias('mixxx', binary)
-
-
+ def cleanSVNDirsFromDist():
+ if os.path.exists("dist"):
+ print "Cleaning .svn directories from dist... ",
+ os.system('cmd.exe /c @FOR /F "tokens=*" %D IN (\'dir /b /ad /s dist\*.svn*\') do @(rd /s /q "%D") 2> NUL')
+ print "Done."
+ import atexit
+ atexit.register(cleanSVNDirsFromDist)
+
def BuildRelease(target, source, env):
print
print "==== Mixxx Post-Build Checks ===="
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/back-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/back-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/back-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/back-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/back-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/back-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/back-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/back-on-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/crosshandle-on-.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/crosshandle-on-.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/crossslider-off-.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/crossslider-off-.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/cue-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/cue-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/cue-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/cue-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/cue-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/cue-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/cue-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/cue-on-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/endoftrack-loop-ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/endoftrack-loop-ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/endoftrack-loop-ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/endoftrack-loop-ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/endoftrack-next-ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/endoftrack-next-ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/endoftrack-next-ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/endoftrack-next-ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/endoftrack-stop-ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/endoftrack-stop-ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/endoftrack-stop-ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/endoftrack-stop-ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/flanger-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/flanger-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/flanger-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/flanger-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/flanger-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/flanger-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/flanger-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/flanger-on-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/fwd-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/fwd-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/fwd-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/fwd-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/fwd-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/fwd-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/fwd-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/fwd-on-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/head-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/head-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/head-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/head-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/head-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/head-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/head-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/head-on-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg0.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg0.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg10.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg10.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg11.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg11.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg12.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg12.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg13.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg13.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg14.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg14.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg15.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg15.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg16.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg16.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg17.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg17.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg18.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg18.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg19.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg19.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg20.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg20.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg21.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg21.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg22.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg22.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg23.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg23.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg24.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg24.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg25.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg25.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg26.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg26.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg27.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg27.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg28.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg28.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg29.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg29.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg30.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg30.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg31.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg31.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg32.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg32.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg33.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg33.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg34.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg34.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg35.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg35.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg36.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg36.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg37.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg37.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg38.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg38.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg39.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg39.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg3.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg3.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg40.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg40.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg41.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg41.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg42.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg42.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg43.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg43.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg44.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg44.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg4.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg4.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg5.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg5.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg6.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg6.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg7.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg7.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg8.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg8.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobg9.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobg9.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm0.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm0.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm10.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm10.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm11.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm11.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm12.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm12.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm13.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm13.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm14.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm14.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm15.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm15.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm16.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm16.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm17.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm17.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm18.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm18.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm19.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm19.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm20.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm20.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm21.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm21.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm22.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm22.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm23.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm23.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm24.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm24.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm25.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm25.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm26.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm26.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm27.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm27.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm28.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm28.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm29.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm29.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm30.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm30.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm31.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm31.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm32.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm32.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm33.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm33.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm34.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm34.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm35.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm35.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm36.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm36.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm37.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm37.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm38.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm38.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm39.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm39.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm3.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm3.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm40.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm40.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm41.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm41.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm42.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm42.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm43.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm43.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm44.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm44.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm4.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm4.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm5.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm5.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm6.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm6.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm7.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm7.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm8.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm8.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/knobm9.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/knobm9.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/master_vol_meter_off.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/master_vol_meter_off.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/master_vol_meter_on.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/master_vol_meter_on.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/play-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/play-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/play-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/play-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/play-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/play-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/play-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/play-on-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/playpos-marker1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/playpos-marker1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/playpos-marker2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/playpos-marker2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/playpos-slider.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/playpos-slider.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/ratedown-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/ratedown-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/ratedown-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/ratedown-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/ratedown-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/ratedown-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/ratedown-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/ratedown-on-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/ratehandle-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/ratehandle-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/ratehandle-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/ratehandle-on-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/rateslider-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/rateslider-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/rateslider-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/rateslider-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/rateup-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/rateup-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/rateup-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/rateup-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/rateup-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/rateup-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/rateup-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/rateup-on-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/rev-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/rev-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/rev-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/rev-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/rev-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/rev-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/rev-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/rev-on-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/scene.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/scene.png differ
diff -Nru mixxx-1.6.0/src/skins/Natt/skin.xml mixxx-1.6.1/src/skins/Natt/skin.xml
--- mixxx-1.6.0/src/skins/Natt/skin.xml 2008-07-11 02:25:36.000000000 -0500
+++ mixxx-1.6.1/src/skins/Natt/skin.xml 1969-12-31 18:00:00.000000000 -0600
@@ -1,1087 +0,0 @@
-
-
-
-
- scene.png
-
-
-
- Crossfader
- crosshandle-on-.png
- crossslider-off-.png
- 310,237
- true
-
- [Master],crossfader
- false
-
-
-
-
- Playback rate
- ratehandle-on-Ch1.png
- rateslider-off-Ch1.png
- 10,170
- false
-
- [Channel1],rate
- false
-
-
-
-
- Playback rate
- ratehandle-on-Ch2.png
- rateslider-off-Ch2.png
- 706,170
- false
-
- [Channel2],rate
- false
-
-
-
-
- Tempo syncronization
- 1
-
- 0
- sync-on-Ch1.png
- sync-off-Ch1.png
-
- 45,170
-
- [Channel1],beatsync
- true
- LeftButton
-
-
-
-
- Tempo syncronization
- 1
-
- 0
- sync-on-Ch2.png
- sync-off-Ch2.png
-
- 741,170
-
- [Channel2],beatsync
- true
- LeftButton
-
-
-
-
- Change playback rate (left/right click: large/small effect)
- 1
-
- 0
- rateup-on-Ch1.png
- rateup-off-Ch1.png
-
- 45,326
-
- [Channel1],rate_perm_up
- true
- LeftButton
-
-
- [Channel1],rate_perm_up_small
- true
- RightButton
-
-
-
-
- Change playback rate (left/right click: large/small effect)
- 1
-
- 0
- rateup-on-Ch2.png
- rateup-off-Ch2.png
-
- 741,326
-
- [Channel2],rate_perm_up
- true
- LeftButton
-
-
- [Channel2],rate_perm_up_small
- true
- RightButton
-
-
-
-
- Change playback rate (left/right click: large/small effect)
- 1
-
- 0
- ratedown-on-Ch1.png
- ratedown-off-Ch1.png
-
- 45,306
-
- [Channel1],rate_perm_down
- true
- LeftButton
-
-
- [Channel1],rate_perm_down_small
- true
- RightButton
-
-
-
-
- Change playback rate (left/right click: large/small effect)
- 1
-
- 0
- ratedown-on-Ch2.png
- ratedown-off-Ch2.png
-
- 741,306
-
- [Channel2],rate_perm_down
- true
- LeftButton
-
-
- [Channel2],rate_perm_down_small
- true
- RightButton
-
-
-
-
- Temporary change playback rate (left/right click: large/small effect)
- 1
-
- 0
- rateup-on-Ch1.png
- rateup-off-Ch1.png
-
- 72,326
-
- [Channel1],rate_temp_up
- true
- LeftButton
-
-
- [Channel1],rate_temp_up
- false
- LeftButton
-
-
- [Channel1],rate_temp_up_small
- true
- RightButton
-
-
- [Channel1],rate_temp_up_small
- false
- RightButton
-
-
-
-
- Temporary change playback rate (left/right click: large/small effect)
- 1
-
- 0
- ratedown-on-Ch1.png
- ratedown-off-Ch1.png
-
- 72,306
-
- [Channel1],rate_temp_down
- true
- LeftButton
-
-
- [Channel1],rate_temp_down
- false
- LeftButton
-
-
- [Channel1],rate_temp_down_small
- true
- RightButton
-
-
- [Channel1],rate_temp_down_small
- false
- RightButton
-
-
-
-
- Temporary change playback rate (left/right click: large/small effect)
- 1
-
- 0
- rateup-on-Ch2.png
- rateup-off-Ch2.png
-
- 768,326
-
- [Channel2],rate_temp_up
- true
- LeftButton
-
-
- [Channel2],rate_temp_up
- false
- LeftButton
-
-
- [Channel2],rate_temp_up_small
- true
- RightButton
-
-
- [Channel2],rate_temp_up_small
- false
- RightButton
-
-
-
-
- Temporary change playback rate (left/right click: large/small effect)
- 1
-
- 0
- ratedown-on-Ch2.png
- ratedown-off-Ch2.png
-
- 768,306
-
- [Channel2],rate_temp_down
- true
- LeftButton
-
-
- [Channel2],rate_temp_down
- false
- LeftButton
-
-
- [Channel2],rate_temp_down_small
- true
- RightButton
-
-
- [Channel2],rate_temp_down_small
- false
- RightButton
-
-
-
-
- Channel volume
- volhandle-on-Ch1.png
- volslider-off-Ch1.png
- 8,413
- false
-
- [Channel1],volume
- false
-
-
-
-
- Channel volume
- volhandle-on-Ch2.png
- volslider-off-Ch2.png
- 703,413
- false
-
- [Channel2],volume
- false
-
-
-
-
- Master VuMeter
- master_vol_meter_on.png
- master_vol_meter_off.png
- 388,170
- 5
- 400
- false
-
- [Master],VuMeter
-
-
-
-
- Channel VuMeter
- vumeter-on-Ch1.png
- vumeter-off-Ch1.png
- 82,413
- 5
- 400
-
- [Channel1],VuMeter
-
-
-
-
- Channel VuMeter
- vumeter-on-Ch2.png
- vumeter-off-Ch2.png
- 777,413
- 5
- 400
-
- [Channel2],VuMeter
-
-
-
-
- End of track mode
- 3
-
- 0
- endoftrack-stop-ch1.png
- endoftrack-stop-ch1.png
-
-
- 1
- endoftrack-next-ch1.png
- endoftrack-next-ch1.png
-
-
- 2
- endoftrack-loop-ch1.png
- endoftrack-loop-ch1.png
-
- 334,170
-
- [Channel1],TrackEndMode
-
-
-
-
- End of track mode
- 3
-
- 0
- endoftrack-stop-ch2.png
- endoftrack-stop-ch2.png
-
-
- 1
- endoftrack-next-ch2.png
- endoftrack-next-ch2.png
-
-
- 2
- endoftrack-loop-ch2.png
- endoftrack-loop-ch2.png
-
- 417,170
-
- [Channel2],TrackEndMode
-
-
-
-
- Left click: Pause/play, Right click: Set cue point
- 2
-
- 0
- play-off-Ch1.png
- play-off-Ch1.png
-
-
- 1
- play-on-Ch1.png
- play-on-Ch1.png
-
- 10,60
-
- [Channel1],play
- true
- LeftButton
-
-
- [Channel1],cue_set
- true
- RightButton
-
-
-
-
- Left click: Pause/play, Right click: Set cue point
- 2
-
- 0
- play-off-Ch2.png
- play-off-Ch2.png
-
-
- 1
- play-on-Ch2.png
- play-on-Ch2.png
-
- 706,60
-
- [Channel2],play
- true
- LeftButton
-
-
- [Channel2],cue_set
- true
- RightButton
-
-
-
-
- Go to and play (while playing), Set cue point (while stopped), Go to and stop (right-click)
- 1
-
- 0
- cue-on-Ch1.png
- cue-off-Ch1.png
-
- 54,126
-
- [Channel1],cue_default
- true
- LeftButton
-
-
- [Channel1],cue_gotoandstop
- true
- RightButton
-
-
-
-
- Go to and play (while playing), Set cue point (while stopped), Go to and stop (right-click)
- 1
-
- 0
- cue-on-Ch2.png
- cue-off-Ch2.png
-
- 750,126
-
- [Channel2],cue_default
- true
- LeftButton
-
-
- [Channel2],cue_gotoandstop
- true
- RightButton
-
-
-
-
- Reverse playback
- 1
-
- 0
- rev-on-Ch1.png
- rev-off-Ch1.png
-
- 10,126
-
- [Channel1],reverse
- true
- LeftButton
-
-
- [Channel1],reverse
- false
- LeftButton
-
-
-
-
- Reverse playback
- 1
-
- 0
- rev-on-Ch2.png
- rev-off-Ch2.png
-
- 706,126
-
- [Channel2],reverse
- true
- LeftButton
-
-
- [Channel2],reverse
- false
- LeftButton
-
-
-
-
- Left click: Fast forward, Right click: End of track
- 1
-
- 0
- fwd-on-Ch1.png
- fwd-off-Ch1.png
-
- 54,97
-
- [Channel1],fwd
- true
- LeftButton
-
-
- [Channel1],fwd
- false
- LeftButton
-
-
- [Channel1],end
- true
- RightButton
-
-
-
-
- Left click: Fast backward, Right click: Start of track
- 1
-
- 0
- back-on-Ch1.png
- back-off-Ch1.png
-
- 10,97
-
- [Channel1],back
- true
- LeftButton
-
-
- [Channel1],back
- false
- LeftButton
-
-
- [Channel1],start
- true
- RightButton
-
-
-
-
- Left click: Fast forward, Right click: End of track
- 1
-
- 0
- fwd-on-Ch2.png
- fwd-off-Ch2.png
-
- 750,97
-
- [Channel2],fwd
- true
- LeftButton
-
-
- [Channel2],fwd
- false
- LeftButton
-
-
- [Channel2],end
- true
- RightButton
-
-
-
-
- Left click: Fast backward, Right click: Start of track
- 1
-
- 0
- back-on-Ch2.png
- back-off-Ch2.png
-
- 706,97
-
- [Channel2],back
- true
- LeftButton
-
-
- [Channel2],back
- false
- LeftButton
-
-
- [Channel2],start
- true
- RightButton
-
-
-
-
- Flanger on/off
- 2
-
- 0
- flanger-off-Ch1.png
- flanger-off-Ch1.png
-
-
- 1
- flanger-on-Ch1.png
- flanger-on-Ch1.png
-
- 46,364
-
- [Channel1],flanger
-
-
-
-
- Flanger on/off
- 2
-
- 0
- flanger-off-Ch2.png
- flanger-off-Ch2.png
-
-
- 1
- flanger-on-Ch2.png
- flanger-on-Ch2.png
-
- 742,364
-
- [Channel2],flanger
-
-
-
-
- Headphone cue
- 2
-
- 0
- head-off-Ch1.png
- head-off-Ch1.png
-
-
- 1
- head-on-Ch1.png
- head-on-Ch1.png
-
- 2,364
-
- [Channel1],pfl
-
-
-
-
- Headphone cue
- 2
-
- 0
- head-off-Ch2.png
- head-off-Ch2.png
-
-
- 1
- head-on-Ch2.png
- head-on-Ch2.png
-
- 698,364
-
- [Channel2],pfl
-
-
-
-
- Master volume
- 41
- knobm%1.png
- 547,243
-
- [Master],volume
-
-
-
-
- Master balance
- 41
- knobm%1.png
- 600,243
-
- [Master],balance
-
-
-
-
- Headphone volume
- 41
- knobm%1.png
- 504,243
-
- [Master],headVolume
-
-
-
-
- Mix between headphone and main
- 41
- knobm%1.png
- 128,243
-
- [Master],headMix
-
-
-
-
- Flanger depth
- 41
- knobm%1.png
- 224,243
-
- [Flanger],lfoDepth
-
-
-
-
- Flanger delay
- 41
- knobm%1.png
- 267,243
-
- [Flanger],lfoDelay
-
-
-
-
- Flanger LFO period
- 41
- knobm%1.png
- 171,243
-
- [Flanger],lfoPeriod
-
-
-
-
- Channel pre gain
- 41
- knobm%1.png
- 46,424
-
- [Channel1],pregain
-
-
-
-
- Channel highpass filter
- 41
- knobm%1.png
- knobg%1.png
- 46,470
-
- [Channel1],filterHigh
-
-
- [Channel1],filterHighKill
- true
-
-
-
-
- Channel bandpass filter
- 41
- knobm%1.png
- knobg%1.png
- 46,517
-
- [Channel1],filterMid
-
-
- [Channel1],filterMidKill
- true
-
-
-
-
- Channel lowpass filter
- 41
- knobm%1.png
- knobg%1.png
- 46,565
-
- [Channel1],filterLow
-
-
- [Channel1],filterLowKill
- true
-
-
-
-
- Channel pre gain
- 41
- knobm%1.png
- 741,424
-
- [Channel2],pregain
-
-
-
-
- Channel highpass filter
- 41
- knobm%1.png
- knobg%1.png
- 741,470
-
- [Channel2],filterHigh
-
-
- [Channel2],filterHighKill
- true
-
-
-
-
- Channel bandpass filter
- 41
- knobm%1.png
- knobg%1.png
- 741,517
-
- [Channel2],filterMid
-
-
- [Channel2],filterMidKill
- true
-
-
-
-
- Channel lowpass filter
- 41
- knobm%1.png
- knobg%1.png
- 741,565
-
- [Channel2],filterLow
-
-
- [Channel2],filterLowKill
- true
-
-
-
-
- Drag with mouse to control sound playback. Drop tracks from external file manager here
- 1
- 116,47
- 570,48
- #161D2E
- #49BADA
- #D8E1EA
- #30C0E9
- #ffffff
- true
-
-
-
- Drag with mouse to control sound playback. Drop tracks from external file manager here
- 2
- 116,102
- 570,48
- #161D2E
- #E08F47
- #D8E1EA
- #30C0E9
- #ffffff
- true
-
-
-
- 1
- 136,6
- 250,25
- #ffffff
- #0E1526
-
-
-
- 2
- 418,6
- 250,25
- #ffffff
- #0E1526
-
-
-
- Tempo display (Beat Per Minute)
- 1
- 118,170
- 78,16
- 6
- #0E1526
- #ffffff
-
- [Channel1],bpm
-
-
-
-
- Tempo display (Beat Per Minute)
- 2
- 484,170
- 78,16
- 6
- #0E1526
- #ffffff
-
- [Channel2],bpm
-
-
-
-
- Play position/remaining time
- 1
- 220,170
- 94,16
- right
- 6
- #0E1526
- #ffffff
-
- [Channel1],playposition
-
-
-
-
- Play position/remaining time
- 2
- 591,170
- 94,16
- right
- 6
- #0E1526
- #ffffff
-
- [Channel2],playposition
-
-
-
-
- Playback rate factor
- 1
- 45,250
- 47,16
- 3
- #0E1526
- #ffffff
-
- [Channel1],rate
-
-
-
-
- Playback rate factor
- 2
- 740,250
- 47,16
- 3
- #0E1526
- #ffffff
-
- [Channel2],rate
-
-
-
-
- Play position - Use mouse to seek
- playpos-marker1.png
- playpos-slider.png
- 112,177
- true
- no
-
- [Channel1],playposition
- false
-
-
-
-
- Play position - Use mouse to seek
- playpos-marker2.png
- playpos-slider.png
- 487,177
- true
- no
-
- [Channel2],playposition
- false
-
-
-
-
- Overview display of waveform
- 1
- 118,193
- 264,36
- #161D2E
- #5D9BA8
- #ffffff
-
- [Channel1],playposition
- false
-
-
-
-
- Overview display of waveform
- 2
- 420,193
- 264,36
- #161D2E
- #5D9BA8
- #ffffff
-
- [Channel2],playposition
- false
-
-
-
-
- 109,284
- 164,25
- #161D2E
-
-
-
- 285,284
- 325,25
- #161D2E
-
-
-
- 109,309
- 582,275
- #9C9F5D
- #161D2E
- #161D2E
- #161D2E
- #161D2E
- #161D2E
-
-
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/sync-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/sync-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/sync-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/sync-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/sync-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/sync-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/sync-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/sync-on-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/volhandle-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/volhandle-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/volhandle-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/volhandle-on-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/volslider-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/volslider-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/volslider-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/volslider-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/vumeter-off-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/vumeter-off-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/vumeter-off-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/vumeter-off-Ch2.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/vumeter-on-Ch1.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/vumeter-on-Ch1.png differ
Binary files /tmp/OngMa6ps8D/mixxx-1.6.0/src/skins/Natt/vumeter-on-Ch2.png and /tmp/MHYQbGTmm3/mixxx-1.6.1/src/skins/Natt/vumeter-on-Ch2.png differ
diff -Nru mixxx-1.6.0/src/soundsourcem4a.cpp mixxx-1.6.1/src/soundsourcem4a.cpp
--- mixxx-1.6.0/src/soundsourcem4a.cpp 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/soundsourcem4a.cpp 2008-08-24 01:38:08.000000000 -0500
@@ -0,0 +1,138 @@
+/***************************************************************************
+ soundsourcem4a.cpp - mp4/m4a decoder
+ -------------------
+ copyright : (C) 2008 by Garth Dahlstrom
+ email : ironstorm@users.sf.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. *
+ * *
+ ***************************************************************************/
+
+#include "trackinfoobject.h"
+#include "soundsourcem4a.h"
+#include
+
+#ifdef __WIN__
+#include
+#include
+#endif
+
+SoundSourceM4A::SoundSourceM4A(QString qFileName) : SoundSource(qFileName)
+{
+ QString mp4FileName;
+ mp4FileName = qFileName;
+ trackId = MP4_INVALID_TRACK_ID;
+ sampleId = 0;
+ mp4file = MP4Read(mp4FileName);
+ if (mp4file == MP4_INVALID_FILE_HANDLE) {
+ qDebug() << "mp4: " << mp4FileName << "could not be opened using the MP4 decoder.";
+ filelength = 0;
+ return;
+ }
+ trackId = MP4FindTrackId(mp4file, 0); // We are only interested in first track for the initial dev iteration
+ if (trackId == MP4_INVALID_TRACK_ID) {
+ qDebug() << "trackId is invalid.";
+ return;
+ }
+ channels = 2; //FIXME: hard coded M4A to 2 channels
+
+ filelength = MP4GetTrackNumberOfSamples(mp4file, trackId);
+ SRATE = (filelength * 1024 * 1000) / MP4ConvertFromTrackDuration(mp4file, trackId, MP4GetTrackDuration(mp4file, trackId), MP4_MSECS_TIME_SCALE);
+ SRATE = 44100; // FIXME: Hard-coded SRATE, above formula for SRATE overflows an unsigned long... :(
+ qDebug() << "SRATE:"<< SRATE;
+ qDebug() << "filelength:" << filelength;
+}
+
+SoundSourceM4A::~SoundSourceM4A(){
+ if (mp4file != MP4_INVALID_FILE_HANDLE) {
+ MP4Close(mp4file);
+ }
+}
+
+long SoundSourceM4A::seek(long filepos){
+ Q_ASSERT(filepos % 2 == 0);
+ sampleId = 1 + (2 * filepos / READCHUNKSIZE); // sampleId is 1 indexed
+ qDebug() << "seek sampleId:"<< sampleId << "filepos:"<< filepos;
+}
+
+unsigned SoundSourceM4A::read(volatile unsigned long size, const SAMPLE* destination){
+ Q_ASSERT(size % 2 == 0);
+
+ MP4Timestamp sampleTime;
+ MP4Duration sampleDuration, sampleRenderingOffset;
+ bool isSyncSample;
+
+// uint32_t sample_size = MP4GetTrackMaxSampleSize(mp4file, trackId);
+// uint8_t *sample = (uint8_t *)malloc(sample_size);
+ unsigned int this_size = MP4GetTrackMaxSampleSize(mp4file, trackId); // size;
+
+ uint8_t *sample = (uint8_t*) destination;
+
+ bool ret = MP4ReadSample(mp4file,
+ trackId,
+ sampleId,
+ &sample,
+ &this_size,
+ &sampleTime,
+ &sampleDuration,
+ &sampleRenderingOffset,
+ &isSyncSample);
+ qDebug() << "read Track:"<< trackId << "Sample:" << sampleId << "Length:" << this_size << "success:"<getLocation();
+
+ char *value;
+ MP4FileHandle mp4file = MP4Read(mp4FileName);
+ if (mp4file == MP4_INVALID_FILE_HANDLE) {
+ qDebug() << "mp4: " << mp4FileName << "could not be opened using the MP4 decoder.";
+ return ERR;
+ }
+
+ if (MP4GetMetadataName(mp4file, &value) && value != NULL) {
+ Track->setTitle(value);
+ free(value);
+ }
+ if (MP4GetMetadataArtist(mp4file, &value) && value != NULL) {
+ Track->setArtist(value);
+ free(value);
+ }
+ if (MP4GetMetadataComment(mp4file, &value) && value != NULL) {
+ Track->setComment(value);
+ free(value);
+ }
+ u_int16_t bpm = 0;
+ if (MP4GetMetadataTempo(mp4file, &bpm)) {
+ if(bpm > 0) {
+ Track->setBpm(bpm);
+ Track->setBpmConfirm(true);
+ }
+ }
+ Track->setHeaderParsed(true);
+ Track->setType("m4a");
+
+ int trackId = MP4FindTrackId(mp4file, 0); // We are only interested in first track for the initial dev iteration
+ Track->setDuration(MP4ConvertFromTrackDuration(mp4file, trackId, MP4GetTrackDuration(mp4file, trackId), MP4_SECS_TIME_SCALE));
+ Track->setBitrate(MP4GetTrackBitRate(mp4file, trackId)/1000);
+
+ Track->setChannels(2); // FIXME: hard-coded to 2 channels
+
+ MP4Close(mp4file);
+ return OK;
+}
diff -Nru mixxx-1.6.0/src/soundsourcem4a.h mixxx-1.6.1/src/soundsourcem4a.h
--- mixxx-1.6.0/src/soundsourcem4a.h 1969-12-31 18:00:00.000000000 -0600
+++ mixxx-1.6.1/src/soundsourcem4a.h 2008-08-24 01:38:08.000000000 -0500
@@ -0,0 +1,43 @@
+/***************************************************************************
+ soundsourcemp4.h - mp4/m4a decoder
+ -------------------
+ copyright : (C) 2008 by Garth Dahlstrom
+ email : ironstorm@users.sf.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. *
+ * *
+ ***************************************************************************/
+
+#ifndef SOUNDSOURCEM4A_H
+#define SOUNDSOURCEM4A_H
+
+#include
+#include "soundsource.h"
+#include "mp4.h"
+
+class TrackInfoObject;
+
+
+class SoundSourceM4A : public SoundSource {
+ public:
+ SoundSourceM4A(QString qFileName);
+ ~SoundSourceM4A();
+ long seek(long);
+ unsigned read(unsigned long size, const SAMPLE*);
+ inline long unsigned length();
+ static int ParseHeader( TrackInfoObject * );
+ private:
+ int channels;
+ int trackId;
+ long sampleId;
+ unsigned long filelength;
+ MP4FileHandle mp4file;
+};
+
+#endif
diff -Nru mixxx-1.6.0/src/soundsourcemp3.cpp mixxx-1.6.1/src/soundsourcemp3.cpp
--- mixxx-1.6.0/src/soundsourcemp3.cpp 2008-08-05 09:35:21.000000000 -0500
+++ mixxx-1.6.1/src/soundsourcemp3.cpp 2008-08-19 17:47:01.000000000 -0500
@@ -95,12 +95,12 @@
m_iAvgFrameSize = 0;
mad_header_finish (&Header); // This is a macro for nothing.
-
+
if (currentframe==0)
bitrate = 0;
else
bitrate = bitrate/currentframe;
-
+
framecount = currentframe;
currentframe = 0;
/*
@@ -393,14 +393,14 @@
*(destination++) = madScale(Synth.pcm.samples[0][i]);
// This is safe because we have Q_ASSERTed that samples_wanted is even.
- Total_samples_decoded += 2;
+ Total_samples_decoded += 2;
}
if(Total_samples_decoded >= samples_wanted) {
if(i < Synth.pcm.length)
rest = i;
- else
+ else
rest = -1;
return Total_samples_decoded;
}
@@ -506,12 +506,10 @@
// http://www.id3.org/id3v2.4.0-frames.txt
QString s;
getField(tag,"TIT2",&s); // TIT2 : Title
- if (s.length()>2)
- Track->setTitle(s);
+ Track->setTitle(s);
s="";
getField(tag,"TPE1",&s); // TPE1 : Artist
- if (s.length()>2)
- Track->setArtist(s);
+ Track->setArtist(s);
s="";
getField(tag,"TBPM",&s); // TBPM: the bpm
float bpm = 0;
@@ -533,7 +531,7 @@
// this closes 'tag' for us
id3_file_close(fh);
}
-
+
// Get file length. This has to be done by one of these options:
// 1) looking for the tag named TLEN (above),
// -- too buggy to rely on
@@ -547,13 +545,13 @@
// -- We do not do this, 7/2008
// Open file, initialize MAD and read beginnning of file
-
+
QFile file(location);
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "SSMP3::ParseHeader Open failed:" << location;
return ERR;
}
-
+
mad_stream Stream;
mad_header Header;
@@ -567,7 +565,7 @@
unsigned long bytesperframe = 0;
bool constantbitrate = true;
int frames = 0;
-
+
// Number of bytes to read at a time to determine duration
const unsigned int READLENGTH = 5000;
char *inputbuf = new char[READLENGTH];
@@ -592,7 +590,7 @@
// This preserves skiplen, so if we had a buffer error earlier
// the skip will occur when we give it more data.
mad_stream_buffer(&Stream, (unsigned char *) inputbuf, readbytes);
-
+
while((Stream.bufend - Stream.this_frame) > 0) {
if(mad_header_decode(&Header,&Stream) == -1) {
if(!MAD_RECOVERABLE(Stream.error)) {
diff -Nru mixxx-1.6.0/src/soundsourceproxy.cpp mixxx-1.6.1/src/soundsourceproxy.cpp
--- mixxx-1.6.0/src/soundsourceproxy.cpp 2008-05-11 10:27:38.000000000 -0500
+++ mixxx-1.6.1/src/soundsourceproxy.cpp 2008-08-24 01:38:08.000000000 -0500
@@ -19,6 +19,9 @@
#include "trackinfoobject.h"
#include "soundsourceproxy.h"
#include "soundsourcemp3.h"
+#ifdef __M4A__
+ #include "soundsourcem4a.h"
+#endif
#include "soundsourceoggvorbis.h"
#ifdef __SNDFILE__
#include "soundsourcesndfile.h"
@@ -42,6 +45,10 @@
#endif
if (qFilename.toLower().endsWith(".mp3"))
m_pSoundSource = new SoundSourceMp3(qFilename);
+#ifdef __M4A__
+ else if (qFilename.toLower().endsWith(".m4a"))
+ m_pSoundSource = new SoundSourceM4A(qFilename);
+#endif
else if (qFilename.toLower().endsWith(".ogg"))
m_pSoundSource = new SoundSourceOggVorbis(qFilename);
else
@@ -64,6 +71,10 @@
if (qFilename.toLower().endsWith(".mp3"))
m_pSoundSource = new SoundSourceMp3(qFilename);
+#ifdef __M4A__
+ else if (qFilename.toLower().endsWith(".m4a"))
+ m_pSoundSource = new SoundSourceM4A(qFilename);
+#endif
else if (qFilename.toLower().endsWith(".ogg"))
m_pSoundSource = new SoundSourceOggVorbis(qFilename);
else
@@ -108,6 +119,10 @@
#endif
if (qFilename.toLower().endsWith(".mp3"))
return SoundSourceMp3::ParseHeader(p);
+#ifdef __M4A__
+ else if (qFilename.toLower().endsWith(".m4a"))
+ return SoundSourceM4A::ParseHeader(p);
+#endif
else if (qFilename.toLower().endsWith(".ogg"))
return SoundSourceOggVorbis::ParseHeader(p);
else if (qFilename.toLower().endsWith(".wav") || qFilename.toLower().endsWith(".aif") ||
diff -Nru mixxx-1.6.0/src/soundsourcesndfile.cpp mixxx-1.6.1/src/soundsourcesndfile.cpp
--- mixxx-1.6.0/src/soundsourcesndfile.cpp 2008-03-27 00:04:43.000000000 -0500
+++ mixxx-1.6.1/src/soundsourcesndfile.cpp 2008-08-15 22:09:05.000000000 -0500
@@ -132,6 +132,16 @@
Track->setSampleRate(info.samplerate);
Track->setChannels(info.channels);
+ const char *string;
+ string = sf_get_string(fh, SF_STR_ARTIST);
+// qDebug() << location << "SF_STR_ARTIST" << string;
+ if(string && strlen(string))
+ Track->setArtist(string);
+ string = sf_get_string(fh, SF_STR_TITLE);
+ if(string && strlen(string))
+ Track->setTitle(string);
+// qDebug() << location << "SF_STR_TITLE" << string;
+
sf_close( fh );
return OK;
}
diff -Nru mixxx-1.6.0/src/track.cpp mixxx-1.6.1/src/track.cpp
--- mixxx-1.6.0/src/track.cpp 2008-08-04 14:00:57.000000000 -0500
+++ mixxx-1.6.1/src/track.cpp 2008-08-18 00:08:49.000000000 -0500
@@ -10,6 +10,10 @@
//
//
+#ifdef __WIN__
+#include // for Sleep() on Windows
+#endif
+
#include "track.h"
#include "trackinfoobject.h"
#include "trackcollection.h"
@@ -1340,26 +1344,49 @@
/** Runs the BPM detection on every track in the TrackCollection that doesn't already have a BPM. */
void Track::slotBatchBPMDetection()
{
-/*
- //Unfinished/WIP - Albert Jan 31/08
- //General idea should work more or less, I suppose...
+ /* Possible use cases:
+ 1) BPM detect whole library
+ 2) BPM detect play queue or a specific play list
+ */
+
+ // TODO: Abort batch processing if either deck is playing and tell user...
+ int processed = 0;
+ for (int i =0; i < m_pTrackCollection->getSize(); i++) {
+ TrackInfoObject* cur_track = m_pTrackCollection->getTrack(i);
+
+ if (!cur_track->isValid()) continue; // Skip invalid track objects
+
+ // Batch Process Wave Summary
+ if (cur_track->getWaveSummary() == NULL || cur_track->getWaveSummary()->size() == 0) {
+ processed++;
+ // TODO: convert the qDebug statement to a status dialog box.
+ qDebug() << "Track #"<< i << "= Batch job #"<< processed << ":" << cur_track->getTitle() << "by" << cur_track->getArtist() << "has WaveSummary: false -- has BPM value:" << (cur_track->getBpm() > 0) << " ("<< m_pBpmDetector->queueCount() << "tracks in the BPM Detect Queue )";
+ // Open sound file
+ SoundSourceProxy * pSoundSource = new SoundSourceProxy(cur_track);
+ m_pWaveSummary->waveformSummaryGen(cur_track, pSoundSource, false);
+ delete pSoundSource;
+ pSoundSource = NULL;
+
+ // Batch Process BPM
+ if (cur_track->getBpm() == 0) {
+ cur_track->sendToBpmQueue();
+ }
+ }
- //Iterate over each TrackInfoObject stored in m_pTrackCollection
- TrackInfoObject* cur_track;
- QListIterator it(m_qPlaylists);
- TrackPlaylist* current;
- while (it.hasNext())
- {
- current = it.next();
- if (current->getListName()==qName)
- return current;
+ // FIXME: remove the song count limitation when BPM detect doesn't crash...
+ if (processed == 100) { qDebug() << "----- BPM detection/Waveform generation batch processing limit of " << processed << " songs has been reached. Rerun to detect more songs."; break; }
}
-
- //(TIO -> TrackInfoObject)
- //Check to see if the TIO already has a non-zero BPM
-
- //If not, run TIO->sendToBpmQueue().
-
-*/
+ // Block the UI thread until BPM detection queue is cleared.
+ while (m_pBpmDetector->queueCount()) {
+ // TODO: convert the qDebug statement to a status dialog box.
+ qDebug() << "---- waiting for BPM detection queue to empty... " << m_pBpmDetector->queueCount() << " to go.";
+#ifdef __WIN__
+ Sleep(3000);
+#else
+ sleep(3);
+#endif
+ }
+ // Save the track database to disk...
+ writeXML(m_pConfig->getValueString(ConfigKey("[Playlist]","Listfile")));
}
diff -Nru mixxx-1.6.0/src/track.h mixxx-1.6.1/src/track.h
--- mixxx-1.6.0/src/track.h 2008-07-13 22:21:19.000000000 -0500
+++ mixxx-1.6.1/src/track.h 2008-08-14 00:24:33.000000000 -0500
@@ -155,12 +155,12 @@
void slotSendToPlaylist(TrackPlaylist* playlist, TrackInfoObject* pTrackInfoObject);
/** Slot for sending a track to a playlist */
void slotSendToPlaylist(TrackPlaylist* playlist, QString filename);
-
+
/** Slot for showing a particular playlist in the track table view */
- void slotShowPlaylist(TrackPlaylist* playlist);
+ void slotShowPlaylist(TrackPlaylist* playlist);
/** Runs the BPM detection on every track in the TrackCollection */
void slotBatchBPMDetection();
-
+
signals:
/** A new track has been loaded in player 1 */
void newTrackPlayer1(TrackInfoObject *);
@@ -173,7 +173,7 @@
private:
/** Returns pointer to playlist by the given name */
TrackPlaylist *getPlaylist(QString qName);
-
+
/** Creates the promo tracks playlist dynamically */
void initPromoTracks();
/** Load the special promo track metadata from an XML file */
@@ -191,7 +191,7 @@
TrackPlaylist m_qPlayqueuePlaylist;
/** The promo tracks playlist */
TrackPlaylist m_qPromoPlaylist;
-
+
/** Data Model for Library */
WTrackTableModel *m_pLibraryModel;
/** Data Model for Playqueue*/
@@ -206,7 +206,7 @@
WTrackTableModel *m_pPlaylistModel;
/** Data Model containing the list of playlists */
WPlaylistListModel *m_pPlaylistListModel;
-
+
/** Pointer to playlist for which a popup menu is currently displayed */
TrackPlaylist *m_pActivePopupPlaylist;
/** Pointer to TrackInfoObject for which a popup menu is currently displayed */
@@ -249,8 +249,8 @@
unsigned int m_iPlayqueueIdx;
/** Provides access to the config keys */
ConfigObject *m_pConfig;
-
- int savedRowPosition;
+
+ int savedRowPosition;
};
#endif
diff -Nru mixxx-1.6.0/src/trackinfoobject.cpp mixxx-1.6.1/src/trackinfoobject.cpp
--- mixxx-1.6.0/src/trackinfoobject.cpp 2008-08-04 13:12:52.000000000 -0500
+++ mixxx-1.6.1/src/trackinfoobject.cpp 2008-08-19 17:47:01.000000000 -0500
@@ -342,33 +342,18 @@
if (m_sFilename.find('-') != -1)
{
- m_sArtist = m_sFilename.section('-',0,0); // Get the first part
+ m_sArtist = m_sFilename.section('-',0,0).trimmed(); // Get the first part
m_sTitle = m_sFilename.section('-',1,1); // Get the second part
- m_sTitle = m_sTitle.section('.',0,-2); // Remove the ending
- m_sType = m_sFilename.section('.',-1); // Get the ending
+ m_sTitle = m_sTitle.section('.',0,-2).trimmed(); // Remove the ending
}
else
{
- m_sTitle = m_sFilename.section('.',0,-2); // Remove the ending;
- m_sType = m_sFilename.section('.',-1); // Get the ending
+ m_sTitle = m_sFilename.section('.',0,-2).trimmed(); // Remove the ending;
+ m_sType = m_sFilename.section('.',-1).trimmed(); // Get the ending
}
- // Remove spaces from start and end of title and artist
- while (m_sArtist.startsWith(" "))
- m_sArtist = m_sArtist.right(m_sArtist.length()-1);
- while (m_sArtist.endsWith(" "))
- m_sArtist = m_sArtist.left(m_sArtist.length()-1);
- while (m_sTitle.startsWith(" "))
- m_sTitle = m_sTitle.right(m_sTitle.length()-1);
- while (m_sTitle.endsWith(" "))
- m_sTitle = m_sTitle.left(m_sTitle.length()-1);
-
-
- // Sort out obviously wrong parsings:
- if ((m_sArtist.length() < 3) || (m_sTitle.length() < 3))
- {
- m_sTitle = m_sFilename.section('.',0,-2);
- m_sArtist = "";
+ if (m_sTitle.length() == 0) {
+ m_sTitle = m_sFilename.section('.',0,-2).trimmed();
}
// Find the length:
@@ -378,7 +363,7 @@
m_sComment = QString("");
// Find the type
- m_sType = m_sFilename.section(".",-1).lower();
+ m_sType = m_sFilename.section(".",-1).lower().trimmed();
m_qMutex.unlock();
}
@@ -544,7 +529,7 @@
QString TrackInfoObject::getInfo() const
{
m_qMutex.lock();
- QString artist = m_sArtist == "" ? "" : m_sArtist + ", ";
+ QString artist = m_sArtist.trimmed() == "" ? "" : m_sArtist + ", ";
QString sInfo = artist + m_sTitle;
m_qMutex.unlock();
@@ -587,7 +572,7 @@
void TrackInfoObject::setTitle(QString s)
{
m_qMutex.lock();
- m_sTitle = s;
+ m_sTitle = s.trimmed();
m_qMutex.unlock();
/*
if (m_pTableItemTitle)
@@ -610,7 +595,7 @@
void TrackInfoObject::setArtist(QString s)
{
m_qMutex.lock();
- m_sArtist = s;
+ m_sArtist = s.trimmed();
m_qMutex.unlock();
/*
if (m_pTableItemArtist)
@@ -899,14 +884,14 @@
m_qMutex.unlock();
}
-void TrackInfoObject::setWaveSummary(Q3MemArray * pWave, Q3ValueList * pSegmentation)
+void TrackInfoObject::setWaveSummary(Q3MemArray * pWave, Q3ValueList * pSegmentation, bool updateUI)
{
m_qMutex.lock();
m_pWave = pWave;
m_pSegmentation = pSegmentation;
m_qMutex.unlock();
- setOverviewWidget(m_pOverviewWidget);
+ if (updateUI) setOverviewWidget(m_pOverviewWidget);
}
//TODO: Get rid of these crappy methods. getNext() and getPrev() are terrible for modularity
diff -Nru mixxx-1.6.0/src/trackinfoobject.h mixxx-1.6.1/src/trackinfoobject.h
--- mixxx-1.6.0/src/trackinfoobject.h 2008-07-13 22:21:19.000000000 -0500
+++ mixxx-1.6.1/src/trackinfoobject.h 2008-08-14 00:23:43.000000000 -0500
@@ -52,7 +52,7 @@
/** Creates a new track given information from the xml file. */
TrackInfoObject(const QDomNode &, BpmDetector *bpmDetector);
~TrackInfoObject();
- /** Returns true if the object contains valid information */
+ /** Returns true if the object contains valid information */
bool isValid() const;
int parse();
/** Checks if the file given in m_sFilename really exists on the disc, and
@@ -165,8 +165,9 @@
void setVisualResampleRate(double dVisualResampleRate);
double getVisualResampleRate();
- /** Set pointer to waveform summary */
- void setWaveSummary(Q3MemArray *pWave, Q3ValueList *pSegmentation);
+ /** Set pointer to waveform summary -- updates UI by default */
+ void setWaveSummary(Q3MemArray *pWave, Q3ValueList *pSegmentation, bool updateUI = true);
+
/** Returns a pointer to waveform summary */
Q3MemArray *getWaveSummary();
/** Returns a pointer to segmentation summary */
diff -Nru mixxx-1.6.0/src/waveform/waveformrenderbeat.cpp mixxx-1.6.1/src/waveform/waveformrenderbeat.cpp
--- mixxx-1.6.0/src/waveform/waveformrenderbeat.cpp 2008-07-21 23:19:17.000000000 -0500
+++ mixxx-1.6.1/src/waveform/waveformrenderbeat.cpp 2008-09-16 21:12:45.000000000 -0500
@@ -93,7 +93,7 @@
}
-void WaveformRenderBeat::draw(QPainter *pPainter, QPaintEvent *event, QVector *buffer, double dPlayPos) {
+void WaveformRenderBeat::draw(QPainter *pPainter, QPaintEvent *event, QVector *buffer, double dPlayPos, double rateAdjust) {
if(m_dBpm == -1 || m_dBpm == 0)
return;
@@ -125,13 +125,14 @@
m_dBeatLength = 60.0 * m_iSampleRate / m_dBpm;
}
- const int oversample = m_pParent->getSubpixelsPerPixel();
+ double subpixelsPerPixel = m_pParent->getSubpixelsPerPixel()*(1.0+rateAdjust);
+ const int oversample = (int)subpixelsPerPixel;
pPainter->save();
- pPainter->scale(1.0/oversample,1.0);
+ pPainter->scale(1.0/subpixelsPerPixel,1.0);
pPainter->setPen(colorMarks);
- double subpixelWidth = m_iWidth * oversample;
+ double subpixelWidth = m_iWidth * subpixelsPerPixel;
double subpixelHalfWidth = subpixelWidth / 2.0;
double halfw = m_iWidth/2;
double halfh = m_iHeight/2;
@@ -140,8 +141,8 @@
iCurPos = iCurPos >> 1;
// basePos and endPos are in samples
- double basePos = iCurPos - m_dSamplesPerPixel*halfw;
- double endPos = basePos + m_iWidth*m_dSamplesPerPixel;
+ double basePos = iCurPos - m_dSamplesPerPixel*halfw*(1.0+rateAdjust);
+ double endPos = basePos + m_iWidth*m_dSamplesPerPixel*(1.0+rateAdjust);
// snap to the first beat
double curPos = ceilf(basePos/m_dBeatLength)*m_dBeatLength;
diff -Nru mixxx-1.6.0/src/waveform/waveformrenderbeat.h mixxx-1.6.1/src/waveform/waveformrenderbeat.h
--- mixxx-1.6.0/src/waveform/waveformrenderbeat.h 2008-07-21 23:19:17.000000000 -0500
+++ mixxx-1.6.1/src/waveform/waveformrenderbeat.h 2008-09-16 21:12:45.000000000 -0500
@@ -22,7 +22,7 @@
void resize(int w, int h);
void setup(QDomNode node);
WaveformRenderBeat(const char *group, WaveformRenderer *parent);
- void draw(QPainter *pPainter, QPaintEvent *event, QVector *buffer, double playPos);
+ void draw(QPainter *pPainter, QPaintEvent *event, QVector *buffer, double playPos, double rateAdjust);
void newTrack(TrackInfoObject *pTrack);
public slots:
diff -Nru mixxx-1.6.0/src/waveform/waveformrenderer.cpp mixxx-1.6.1/src/waveform/waveformrenderer.cpp
--- mixxx-1.6.0/src/waveform/waveformrenderer.cpp 2008-07-21 23:19:17.000000000 -0500
+++ mixxx-1.6.1/src/waveform/waveformrenderer.cpp 2008-09-16 21:12:45.000000000 -0500
@@ -54,6 +54,17 @@
m_pRenderCue = new WaveformRenderMark(group, ConfigKey(group, "cue_point"), this);
m_pCOVisualResample = new ControlObject(ConfigKey(group, "VisualResample"));
+
+ m_pRate = new ControlObjectThreadMain(ControlObject::getControl(ConfigKey(group, "rate")));
+ if(m_pRate != NULL) {
+ connect(m_pRate, SIGNAL(valueChanged(double)), this, SLOT(slotUpdateRate(double)));
+ }
+
+ m_pRateRange = new ControlObjectThreadMain(ControlObject::getControl(ConfigKey(group, "rateRange")));
+ if(m_pRateRange != NULL) {
+ connect(m_pRateRange, SIGNAL(valueChanged(double)), this, SLOT(slotUpdateRateRange(double)));
+ }
+
}
@@ -62,6 +73,14 @@
delete m_pCOVisualResample;
m_pCOVisualResample = NULL;
+ if(m_pRate)
+ delete m_pRate;
+ m_pRate = NULL;
+
+ if(m_pRateRange)
+ delete m_pRateRange;
+ m_pRateRange = NULL;
+
if(m_pPlayPos)
delete m_pPlayPos;
m_pPlayPos = NULL;
@@ -83,6 +102,15 @@
m_iPlayPosTime = clock();
}
+void WaveformRenderer::slotUpdateRate(double v) {
+ m_dRate = v;
+}
+
+void WaveformRenderer::slotUpdateRateRange(double v) {
+ m_dRateRange = v;
+}
+
+
void WaveformRenderer::resize(int w, int h) {
m_iWidth = w;
m_iHeight = h;
@@ -271,7 +299,7 @@
-void WaveformRenderer::drawSignalLines(QPainter *pPainter,double playpos) {
+void WaveformRenderer::drawSignalLines(QPainter *pPainter,double playpos, double rateAdjust) {
if(m_pSampleBuffer == NULL) {
return;
@@ -287,9 +315,18 @@
pPainter->save();
- int subpixelWidth = m_iWidth * m_iSubpixelsPerPixel;
+ double subpixelsPerPixel = m_iSubpixelsPerPixel * (1.0 + rateAdjust);
+
+ int subpixelWidth = int(m_iWidth * subpixelsPerPixel);
+
+ pPainter->scale(1.0/subpixelsPerPixel,m_iHeight*0.40);
- pPainter->scale(1.0/float(m_iSubpixelsPerPixel),m_iHeight*0.40);
+ // If the array is not large enough, expand it.
+ // Amortize the cost of this by requesting a factor of 2 more.
+ if(m_lines.size() < subpixelWidth) {
+ m_lines.resize(2*subpixelWidth);
+ }
+
int halfw = subpixelWidth/2;
for(int i=0;idrawLines(m_lines);
+ // Only draw lines that we have provided
+ pPainter->drawLines(m_lines.data(), subpixelWidth);
pPainter->restore();
}
@@ -406,7 +444,7 @@
}
*/
- double playpos = m_dPlayPos + playposadjust;
+ double playpos = m_dPlayPos;
if(m_bRepaintBackground) {
generateBackgroundPixmap();
@@ -426,19 +464,23 @@
// Translate our coordinate frame from (0,0) at top left
// to (0,0) at left, center. All the subrenderers expect this.
-
pPainter->translate(0.0,m_iHeight/2.0);
+
// Now scale so that positive-y points up.
pPainter->scale(1.0,-1.0);
-
+
// Draw the center horizontal line under the signal.
pPainter->drawLine(QLine(0,0,m_iWidth,0));
+
+ // Limit our rate adjustment to < 99%, "Bad Things" might happen otherwise.
+ double rateAdjust = math_min(0.99, m_dRate * m_dRateRange);
- drawSignalLines(pPainter,playpos);
+ // Draw the signal
+ drawSignalLines(pPainter,playpos,rateAdjust);
// Draw various markers.
- m_pRenderBeat->draw(pPainter,pEvent, m_pSampleBuffer, playpos);
- m_pRenderCue->draw(pPainter,pEvent, m_pSampleBuffer, playpos);
+ m_pRenderBeat->draw(pPainter,pEvent, m_pSampleBuffer, playpos, rateAdjust);
+ m_pRenderCue->draw(pPainter,pEvent, m_pSampleBuffer, playpos, rateAdjust);
pPainter->setPen(colorMarker);
diff -Nru mixxx-1.6.0/src/waveform/waveformrenderer.h mixxx-1.6.1/src/waveform/waveformrenderer.h
--- mixxx-1.6.0/src/waveform/waveformrenderer.h 2008-07-21 23:19:17.000000000 -0500
+++ mixxx-1.6.1/src/waveform/waveformrenderer.h 2008-09-16 21:12:45.000000000 -0500
@@ -24,7 +24,7 @@
void resize(int w, int h);
void draw(QPainter* pPainter, QPaintEvent *pEvent);
- void drawSignalLines(QPainter*, double playpos);
+ void drawSignalLines(QPainter*, double playpos, double rateAdjust);
void drawSignalPixmap(QPainter* p);
void newTrack(TrackInfoObject *pTrack);
void setup(QDomNode node);
@@ -33,6 +33,8 @@
int getPixelsPerSecond();
public slots:
void slotUpdatePlayPos(double playpos);
+ void slotUpdateRate(double rate);
+ void slotUpdateRateRange(double rate);
private:
void generateBackgroundPixmap();
@@ -43,7 +45,7 @@
int m_iNumSamples;
int m_iPlayPosTime, m_iPlayPosTimeOld;
- double m_dPlayPos, m_dPlayPosOld;
+ double m_dPlayPos, m_dPlayPosOld, m_dRate, m_dRateRange;
QVector *m_pSampleBuffer;
QVector m_lines;
@@ -53,7 +55,9 @@
QImage m_pImage;
ControlObjectThreadMain *m_pPlayPos;
-
+ ControlObjectThreadMain *m_pRate;
+ ControlObjectThreadMain *m_pRateRange;
+
ControlObject *m_pCOVisualResample;
WaveformRenderBeat *m_pRenderBeat;
diff -Nru mixxx-1.6.0/src/waveform/waveformrendermark.cpp mixxx-1.6.1/src/waveform/waveformrendermark.cpp
--- mixxx-1.6.0/src/waveform/waveformrendermark.cpp 2008-07-21 23:19:17.000000000 -0500
+++ mixxx-1.6.1/src/waveform/waveformrendermark.cpp 2008-09-16 21:12:45.000000000 -0500
@@ -79,7 +79,7 @@
}
-void WaveformRenderMark::draw(QPainter *pPainter, QPaintEvent *event, QVector *buffer, double dPlayPos) {
+void WaveformRenderMark::draw(QPainter *pPainter, QPaintEvent *event, QVector *buffer, double dPlayPos, double rateAdjust) {
if(m_iSampleRate == -1 || m_iSampleRate == 0 || m_iNumSamples == 0)
return;
@@ -87,14 +87,14 @@
// necessary?
if(buffer == NULL)
return;
-
- const int oversample = m_pParent->getSubpixelsPerPixel();
+
+ double subpixelsPerPixel = m_pParent->getSubpixelsPerPixel()*(1.0+rateAdjust);
pPainter->save();
- pPainter->scale(1.0/oversample,1.0);
+ pPainter->scale(1.0/subpixelsPerPixel,1.0);
pPainter->setPen(markColor);
- double subpixelWidth = m_iWidth * oversample;
+ double subpixelWidth = m_iWidth * subpixelsPerPixel;
double subpixelHalfWidth = subpixelWidth / 2.0;
double halfh = m_iHeight/2;
diff -Nru mixxx-1.6.0/src/waveform/waveformrendermark.h mixxx-1.6.1/src/waveform/waveformrendermark.h
--- mixxx-1.6.0/src/waveform/waveformrendermark.h 2008-07-21 23:19:17.000000000 -0500
+++ mixxx-1.6.1/src/waveform/waveformrendermark.h 2008-09-16 21:12:45.000000000 -0500
@@ -24,7 +24,7 @@
void resize(int w, int h);
void setup(QDomNode node);
WaveformRenderMark(const char *group, ConfigKey key, WaveformRenderer *parent);
- void draw(QPainter *pPainter, QPaintEvent *event, QVector *buffer, double playPos);
+ void draw(QPainter *pPainter, QPaintEvent *event, QVector *buffer, double playPos, double rateAdjust);
void newTrack(TrackInfoObject *pTrack);
public slots:
diff -Nru mixxx-1.6.0/src/wavesummary.cpp mixxx-1.6.1/src/wavesummary.cpp
--- mixxx-1.6.0/src/wavesummary.cpp 2008-07-30 11:53:19.000000000 -0500
+++ mixxx-1.6.1/src/wavesummary.cpp 2008-09-07 04:36:04.000000000 -0500
@@ -87,7 +87,7 @@
// Check if preview has been generated
Q3MemArray *p = pTrackInfoObject->getWaveSummary();
if (!p || p->size()==0) {
- waveformSummaryGen(pTrackInfoObject, pSoundSource);
+ waveformSummaryGen(pTrackInfoObject, pSoundSource);
}
if(pTrackInfoObject->getVisualWaveform() == NULL) {
@@ -101,9 +101,8 @@
qDebug() << "WaveSummary::run() exiting";
}
+void WaveSummary::waveformSummaryGen(TrackInfoObject *pTrackInfoObject, SoundSourceProxy *pSoundSource, bool updateUI) {
-void WaveSummary::waveformSummaryGen(TrackInfoObject *pTrackInfoObject, SoundSourceProxy *pSoundSource) {
-
// Allocate temp buffer
SAMPLE * pBuffer = new SAMPLE[kiBlockSize*2];
@@ -157,10 +156,10 @@
liPos += pSoundSource->read(kiBlockSize, pBuffer);
}
- pTrackInfoObject->setWaveSummary(pData, 0);
+ pTrackInfoObject->setWaveSummary(pData, 0, updateUI);
delete [] pBuffer;
- pBuffer = NULL;
+ pBuffer = NULL;
qDebug() << "WaveSummary generation successful for " << pTrackInfoObject->getFilename();
@@ -177,18 +176,19 @@
// => N = F / (MZ)
int numSamples = pSoundSource->length();
+ if (numSamples <= 0) return;
int f = pSoundSource->getSrate();
double mz = pTrackInfoObject->getVisualResampleRate();
double n = double(f) / mz;
-
+
int samplesPerDownsample = n;
int numDownsamples = numSamples / samplesPerDownsample;
-
+
if(numDownsamples % 2 != 0)
numDownsamples++;
// Downsample from curSamples -> numDownsamples
-
+
QVector *downsample = new QVector(numDownsamples);
float *downsampleVector = downsample->data();
int i,j;
@@ -202,7 +202,7 @@
// Allow the visual waveform to display this before we've populated it so
// that it displays the wave as we work.
pTrackInfoObject->setVisualWaveform(downsample);
-
+
qDebug() << "WaveSummary: f " << f << " samplesPerDownsample: " << samplesPerDownsample << " downsamples " << numDownsamples << " from " << numSamples;
// readLen and bufRead need to be divisible by 2
@@ -249,8 +249,14 @@
samplesAvailable -= bufRead;
}
int samplesRead = pSoundSource->read(readLen, pBuffer);
- samplesAvailable += samplesRead;
- filePos += samplesRead;
+ if(samplesRead) {
+ samplesAvailable += samplesRead;
+ filePos += samplesRead;
+ } else {
+ /* early EOF return, break out of the loop. */
+ qDebug() << "Waveform thread: got early EOF.";
+ filePos = numSamples;
+ }
}
qDebug() << "WaveSummary :: Waveform downsampling finished.";
diff -Nru mixxx-1.6.0/src/wavesummary.h mixxx-1.6.1/src/wavesummary.h
--- mixxx-1.6.0/src/wavesummary.h 2008-07-30 09:41:17.000000000 -0500
+++ mixxx-1.6.1/src/wavesummary.h 2008-08-14 00:23:43.000000000 -0500
@@ -52,7 +52,10 @@
~WaveSummary();
/** Puts an TrackInfoObject into the queue of summary generation. Thread safe, blocking. */
void enqueue(TrackInfoObject *pTrackInfoObject);
- void extractBeat(TrackInfoObject *pTrackInfoObject);
+ void extractBeat(TrackInfoObject *pTrackInfoObject);
+
+ /** Generate a waveform summary data for the given track */
+ void waveformSummaryGen(TrackInfoObject *pTrackInfoObject, SoundSourceProxy *pSoundSource, bool updateUI = true);
private:
/** Main thread loop */
@@ -61,8 +64,7 @@
void stop();
/** Generate a visual waveform for the given track */
void visualWaveformGen(TrackInfoObject *pTrackInfoObject, SoundSourceProxy *pSoundSource);
- /** Generate a waveform summary for the given track */
- void waveformSummaryGen(TrackInfoObject *pTrackInfoObject, SoundSourceProxy *pSoundSource);
+
/** Queue holding files to generate a summary for */
Q3PtrQueue m_qQueue;
/** Mutex controlling access to m_qQueue */
@@ -71,7 +73,7 @@
QWaitCondition m_qWait;
/** Pointer to config object **/
ConfigObject *m_Config;
-
+
ControlObjectThread *m_pControlVisualResample;
bool m_bShouldExit;
diff -Nru mixxx-1.6.0/src/wvisualsimple.cpp mixxx-1.6.1/src/wvisualsimple.cpp
--- mixxx-1.6.0/src/wvisualsimple.cpp 2008-07-13 22:21:19.000000000 -0500
+++ mixxx-1.6.1/src/wvisualsimple.cpp 2008-09-15 13:58:32.000000000 -0500
@@ -52,7 +52,7 @@
if (event->mimeData()->hasUrls()) {
QList urls(event->mimeData()->urls());
QUrl url = urls.first();
- QString name = url.path();
+ QString name = url.toLocalFile();
event->accept();
emit(trackDropped(name));
@@ -96,7 +96,7 @@
colorMarker = WSkinColor::getCorrectColor(colorMarker);
}
-void WVisualSimple::slotNewTrack()
+void WVisualSimple::slotNewTrack(TrackInfoObject* track)
{
}
@@ -152,3 +152,6 @@
paint.drawLine(m_qMarkerPos2, p2);
}
}
+
+
+
diff -Nru mixxx-1.6.0/src/wvisualsimple.h mixxx-1.6.1/src/wvisualsimple.h
--- mixxx-1.6.0/src/wvisualsimple.h 2008-07-13 22:21:19.000000000 -0500
+++ mixxx-1.6.1/src/wvisualsimple.h 2008-09-15 13:58:32.000000000 -0500
@@ -32,6 +32,7 @@
*/
class WaveformRenderer;
+class TrackInfoObject;
class WVisualSimple : public WWidget
{
@@ -52,7 +53,7 @@
public slots:
void setValue(double) {};
- void slotNewTrack();
+ void slotNewTrack(TrackInfoObject* track);
protected:
int m_iStartPosX, m_iValue;