first commit
7
README.md
Normal file
@ -0,0 +1,7 @@
|
||||
This is a copy of VK5ABN, Berndt's cuSDR source
|
||||
derived from his post: http://www.ping.net.au/20140126_cuSDR64src.tar.gz
|
||||
|
||||
I added local sound and up'd the number of recievers to 8
|
||||
for librtlhpsdr.
|
||||
|
||||
I have only compiled and used this on linux.
|
||||
1080
Source/bin/settings.ini
Normal file
3
Source/bin/windowsSettings.ini
Normal file
@ -0,0 +1,3 @@
|
||||
[General]
|
||||
geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x1\0\0\0\0\x2\x82\0\0\0\x18\0\0\a\x11\0\0\x3\x1a\0\0\x2\x8c\0\0\0\x44\0\0\a\a\0\0\x3\x10\0\0\0\0\0\0)
|
||||
windowState=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\x1\0\0\0\x1\0\0\0\xf5\0\0\x2\x11\xfc\x2\0\0\0\x5\xfb\0\0\0\x12\0R\0\x61\0\x64\0i\0o\0\x43\0t\0r\0l\0\0\0\0\0\xff\xff\xff\xff\0\0\0\x30\0\xff\xff\xff\xfb\0\0\0\x14\0S\0\x65\0r\0v\0\x65\0r\0\x43\0t\0r\0l\0\0\0\0\xa5\0\0\x2\x11\0\0\x2\x11\0\xff\xff\xff\xfb\0\0\0\x12\0H\0P\0S\0\x44\0R\0\x43\0t\0r\0l\x1\0\0\0\xa5\0\0\x2\x11\0\0\x2\x11\0\xff\xff\xff\xfb\0\0\0\x12\0\x43\0h\0i\0r\0p\0\x43\0t\0r\0l\0\0\0\0\0\xff\xff\xff\xff\0\0\0\x30\0\xff\xff\xff\xfb\0\0\0\x16\0\x44\0i\0s\0p\0l\0\x61\0y\0\x43\0t\0r\0l\0\0\0\0\0\xff\xff\xff\xff\0\0\0\x30\0\xff\xff\xff\0\0\x3\x81\0\0\x2\x11\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\x2\0\0\0\x2\0\0\0\x1\0\0\0\x18\0\x44\0i\0s\0p\0l\0\x61\0y\0P\0\x61\0n\0\x65\0l\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\x2\0\0\0\x1\0\0\0\x16\0M\0\x61\0i\0n\0\x42\0u\0t\0t\0o\0n\0s\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0)
|
||||
145
Source/cudaSDR.pri
Normal file
@ -0,0 +1,145 @@
|
||||
HEADERS += \
|
||||
./src/Util/cusdr_buttons.h \
|
||||
./src/Util/cusdr_colorTriangle.h \
|
||||
./src/Util/cusdr_highResTimer.h \
|
||||
./src/Util/cusdr_image.h \
|
||||
./src/Util/cusdr_imageblur.h \
|
||||
./src/Util/cusdr_led.h \
|
||||
./src/Util/cusdr_painter.h \
|
||||
./src/Util/cusdr_queue.h \
|
||||
./src/Util/cusdr_splash.h \
|
||||
./src/Util/cusdr_styles.h \
|
||||
./src/Util/cusdr_cpuUsage.h \
|
||||
./src/Util/qcircularbuffer.h \
|
||||
./src/AudioEngine/cusdr_audio_engine.h \
|
||||
./src/AudioEngine/cusdr_audio_settingsdialog.h \
|
||||
./src/AudioEngine/cusdr_audio_spectrum.h \
|
||||
./src/AudioEngine/cusdr_audio_spectrumanalyser.h \
|
||||
./src/AudioEngine/cusdr_audio_utils.h \
|
||||
./src/AudioEngine/cusdr_audio_waveform.h \
|
||||
./src/AudioEngine/cusdr_audio_wavfile.h \
|
||||
./src/AudioEngine/cusdr_fspectrum.h \
|
||||
./src/DataEngine/cusdr_audioReceiver.h \
|
||||
./src/DataEngine/cusdr_chirpProcessor.h \
|
||||
./src/DataEngine/cusdr_dataEngine.h \
|
||||
./src/DataEngine/cusdr_dataIO.h \
|
||||
./src/DataEngine/cusdr_discoverer.h \
|
||||
./src/DataEngine/cusdr_receiver.h \
|
||||
./src/DataEngine/soundout.h \
|
||||
./src/DataEngine/fractresampler.h \
|
||||
./src/DataEngine/datatypes.h \
|
||||
./src/QtDSP/fftw3.h \
|
||||
./src/QtDSP/qtdsp_demodulation.h \
|
||||
./src/QtDSP/qtdsp_dspEngine.h \
|
||||
./src/QtDSP/qtdsp_dualModeAverager.h \
|
||||
./src/QtDSP/qtdsp_fft.h \
|
||||
./src/QtDSP/qtdsp_filter.h \
|
||||
./src/QtDSP/qtdsp_powerSpectrum.h \
|
||||
./src/QtDSP/qtdsp_invsinc_coeff.h \
|
||||
./src/QtDSP/qtdsp_qComplex.h \
|
||||
./src/QtDSP/qtdsp_signalMeter.h \
|
||||
./src/QtDSP/qtdsp_wpagc.h \
|
||||
./src/GL/cusdr_oglDisplayPanel.h \
|
||||
./src/GL/cusdr_oglDistancePanel.h \
|
||||
./src/GL/cusdr_oglInfo.h \
|
||||
./src/GL/cusdr_oglReceiverPanel.h \
|
||||
./src/GL/cusdr_oglText.h \
|
||||
./src/GL/cusdr_oglUtils.h \
|
||||
./src/GL/cusdr_oglWidebandPanel.h \
|
||||
./src/cusdr_alexAntennaWidget.h \
|
||||
./src/cusdr_alexFilterWidget.h \
|
||||
./src/cusdr_alexTabWidget.h \
|
||||
./src/cusdr_chirpWidget.h \
|
||||
./src/cusdr_displayWidget.h \
|
||||
./src/cusdr_colorsWidget.h \
|
||||
./src/cusdr_hamDatabase.h \
|
||||
./src/cusdr_hpsdrTabWidget.h \
|
||||
./src/cusdr_hpsdrWidget.h \
|
||||
./src/cusdr_networkWidget.h \
|
||||
./src/cusdr_mainWidget.h \
|
||||
./src/cusdr_extCtrlWidget.h \
|
||||
./src/cusdr_radioTabWidget.h \
|
||||
./src/cusdr_radioWidget.h \
|
||||
./src/cusdr_agcWidget.h \
|
||||
./src/cusdr_displayTabWidget.h \
|
||||
./src/cusdr_radioPopupWidget.h \
|
||||
./src/cusdr_receiverWidget.h \
|
||||
#./src/cusdr_server.h \
|
||||
./src/cusdr_serverWidget.h \
|
||||
./src/cusdr_settings.h \
|
||||
./src/cusdr_fonts.h \
|
||||
./src/cusdr_transmitTabWidget.h \
|
||||
./src/cusdr_transmitOptionsWidget.h \
|
||||
./src/cusdr_transmitPAWidget.h \
|
||||
./src/Util/cusdr_cpuUsage_unix.h
|
||||
|
||||
#win32:HEADERS += ./src/Util/cusdr_cpuUsage.h \
|
||||
|
||||
SOURCES += \
|
||||
./src/Util/cusdr_buttons.cpp \
|
||||
./src/Util/cusdr_colorTriangle.cpp \
|
||||
./src/Util/cusdr_highResTimer.cpp \
|
||||
./src/Util/cusdr_image.cpp \
|
||||
./src/Util/cusdr_imageblur.cpp \
|
||||
./src/Util/cusdr_led.cpp \
|
||||
./src/Util/cusdr_painter.cpp \
|
||||
./src/Util/cusdr_splash.cpp \
|
||||
./src/Util/cusdr_cpuUsage.cpp \
|
||||
./src/AudioEngine/cusdr_audio_engine.cpp \
|
||||
./src/AudioEngine/cusdr_audio_settingsdialog.cpp \
|
||||
./src/AudioEngine/cusdr_audio_spectrumanalyser.cpp \
|
||||
./src/AudioEngine/cusdr_audio_utils.cpp \
|
||||
./src/AudioEngine/cusdr_audio_waveform.cpp \
|
||||
./src/AudioEngine/cusdr_audio_wavfile.cpp \
|
||||
./src/AudioEngine/cusdr_fspectrum.cpp \
|
||||
./src/DataEngine/cusdr_audioReceiver.cpp \
|
||||
./src/DataEngine/cusdr_chirpProcessor.cpp \
|
||||
./src/DataEngine/cusdr_dataEngine.cpp \
|
||||
./src/DataEngine/cusdr_dataIO.cpp \
|
||||
./src/DataEngine/cusdr_discoverer.cpp \
|
||||
./src/DataEngine/cusdr_receiver.cpp \
|
||||
./src/DataEngine/soundout.cpp \
|
||||
./src/DataEngine/fractresampler.cpp \
|
||||
./src/QtDSP/qtdsp_demodulation.cpp \
|
||||
./src/QtDSP/qtdsp_dspEngine.cpp \
|
||||
./src/QtDSP/qtdsp_dualModeAverager.cpp \
|
||||
./src/QtDSP/qtdsp_fft.cpp \
|
||||
./src/QtDSP/qtdsp_filter.cpp \
|
||||
./src/QtDSP/qtdsp_powerSpectrum.cpp \
|
||||
./src/QtDSP/qtdsp_signalMeter.cpp \
|
||||
./src/QtDSP/qtdsp_wpagc.cpp \
|
||||
./src/GL/cusdr_oglDisplayPanel.cpp \
|
||||
./src/GL/cusdr_oglDistancePanel.cpp \
|
||||
./src/GL/cusdr_oglInfo.cpp \
|
||||
./src/GL/cusdr_oglReceiverPanel.cpp \
|
||||
./src/GL/cusdr_oglText.cpp \
|
||||
./src/GL/cusdr_oglWidebandPanel.cpp \
|
||||
./src/cusdr_alexAntennaWidget.cpp \
|
||||
./src/cusdr_alexFilterWidget.cpp \
|
||||
./src/cusdr_alexTabWidget.cpp \
|
||||
./src/cusdr_chirpWidget.cpp \
|
||||
./src/cusdr_displayWidget.cpp \
|
||||
./src/cusdr_colorsWidget.cpp \
|
||||
./src/cusdr_hamDatabase.cpp \
|
||||
./src/cusdr_hpsdrTabWidget.cpp \
|
||||
./src/cusdr_hpsdrWidget.cpp \
|
||||
./src/cusdr_networkWidget.cpp \
|
||||
./src/cusdr_mainWidget.cpp \
|
||||
./src/cusdr_extCtrlWidget.cpp \
|
||||
./src/cusdr_radioTabWidget.cpp \
|
||||
./src/cusdr_radioWidget.cpp \
|
||||
./src/cusdr_agcWidget.cpp \
|
||||
./src/cusdr_displayTabWidget.cpp \
|
||||
./src/cusdr_radioPopupWidget.cpp \
|
||||
./src/cusdr_receiverWidget.cpp \
|
||||
#./src/cusdr_server.cpp \
|
||||
./src/cusdr_serverWidget.cpp \
|
||||
./src/cusdr_settings.cpp \
|
||||
./src/cusdr_fonts.cpp \
|
||||
./src/cusdr_transmitTabWidget.cpp \
|
||||
./src/cusdr_transmitOptionsWidget.cpp \
|
||||
./src/cusdr_transmitPAWidget.cpp \
|
||||
./src/main.cpp \
|
||||
./src/Util/cusdr_cpuUsage_unix.cpp
|
||||
|
||||
#win32:SOURCES += ./src/Util/cusdr_cpuUsage.cpp \
|
||||
88
Source/cudaSDR.pro
Normal file
@ -0,0 +1,88 @@
|
||||
QT += core gui network multimedia opengl
|
||||
|
||||
TARGET = cudaSDR
|
||||
TEMPLATE = app
|
||||
|
||||
CONFIG += qt warn_on
|
||||
CONFIG += console
|
||||
CONFIG += mobility
|
||||
CONFIG += $$QMAKE_HOST.arch
|
||||
message(CONFIG: $$QMAKE_HOST.arch)
|
||||
|
||||
MOBILITY += multimedia
|
||||
|
||||
include(cudaSDR.pri)
|
||||
|
||||
RESOURCES += res/cusdr.qrc
|
||||
|
||||
#DEFINES += AUDIO_ENGINE_DEBUG
|
||||
#DEFINES += _WINDOWS
|
||||
#DEFINES += _CRT_SECURE_NO_WARNINGS
|
||||
#DEFINES += QT_LARGEFILE_SUPPORT
|
||||
#DEFINES += QT_DLL
|
||||
#DEFINES += QT_MULTIMEDIA_LIB
|
||||
#DEFINES += QT_OPENGL_LIB
|
||||
#DEFINES += QT_NETWORK_LIB
|
||||
#DEFINES += QT_HAVE_MMX
|
||||
#DEFINES += QT_HAVE_3DNOW
|
||||
#DEFINES += QT_HAVE_SSE
|
||||
#DEFINES += QT_HAVE_MMXEXT
|
||||
#DEFINES += QT_HAVE_SSE2
|
||||
|
||||
unix {
|
||||
# CUDA_DIR = $$system(which nvcc | sed 's,/bin/nvcc$,,')
|
||||
|
||||
x86_64 { HOST_ARCH = x86_64-linux }
|
||||
arm7 { HOST_ARCH = armv7-linux-gnueabihf }
|
||||
|
||||
INCLUDEPATH += \
|
||||
./ \
|
||||
src/ \
|
||||
src/AudioEngine \
|
||||
src/CL \
|
||||
src/DataEngine \
|
||||
src/GL \
|
||||
src/QtDSP \
|
||||
src/Util
|
||||
|
||||
LIBS += \
|
||||
-lfftw3f -lpulse-simple -lpulse -lasound
|
||||
}
|
||||
|
||||
# ********************************************************
|
||||
# The WIN32 configuration needs to be checked and updated
|
||||
# ********************************************************
|
||||
win32 {
|
||||
RC_FILE += res/cusdr.rc
|
||||
|
||||
INCLUDEPATH += \
|
||||
./ \
|
||||
src/ \
|
||||
src/AudioEngine \
|
||||
src/CL \
|
||||
src/Cuda \
|
||||
src/DataEngine \
|
||||
src/GL \
|
||||
src/QtDSP \
|
||||
src/Util \
|
||||
$(CUDA_PATH_V6_5)/include
|
||||
|
||||
LIBS += \
|
||||
-L"$$(CUDA_PATH_V6_5)/lib/x64" \
|
||||
-L"./lib" \
|
||||
-lwsock32 \
|
||||
-lVersion \
|
||||
-lPsapi \
|
||||
-lQtOpenCL \
|
||||
-lopengl32 \
|
||||
-llibfftw3f-3 \
|
||||
-lgdi32 \
|
||||
-luser32 \
|
||||
-lKernel32
|
||||
}
|
||||
|
||||
OBJECTS_DIR = ./bld/o
|
||||
MOC_DIR = ./bld/moc
|
||||
#UI_DIR = ./bld/ui
|
||||
RCC_DIR = ./bld/rcc
|
||||
DESTDIR = ./bin
|
||||
208
Source/cudaSDR.pro.user
Normal file
@ -0,0 +1,208 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 3.2.1, 2015-02-18T18:13:10. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
<value type="QByteArray">{974be962-b6da-4db1-b656-2716ea8841ad}</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||
<value type="int">0</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||
<value type="QString" key="language">Cpp</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||
<value type="QString" key="language">QmlJS</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||
<valuemap type="QVariantMap"/>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 5.3.2 (qt5)</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Qt 5.3.2 (qt5)</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{c28b2f69-26d0-4219-96bf-795edbc3bba5}</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory"></value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">false</value>
|
||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
||||
<value type="QString">-w</value>
|
||||
<value type="QString">-r</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
||||
<value type="QString">-w</value>
|
||||
<value type="QString">-r</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||
<value type="int">0</value>
|
||||
<value type="int">1</value>
|
||||
<value type="int">2</value>
|
||||
<value type="int">3</value>
|
||||
<value type="int">4</value>
|
||||
<value type="int">5</value>
|
||||
<value type="int">6</value>
|
||||
<value type="int">7</value>
|
||||
<value type="int">8</value>
|
||||
<value type="int">9</value>
|
||||
<value type="int">10</value>
|
||||
<value type="int">11</value>
|
||||
<value type="int">12</value>
|
||||
<value type="int">13</value>
|
||||
<value type="int">14</value>
|
||||
</valuelist>
|
||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">cudaSDR</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/mh/RTL/LATEST_RTL/BETTERCODES_SVN/cusdrk/Source/cudaSDR.pro</value>
|
||||
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
|
||||
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">cudaSDR.pro</value>
|
||||
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
|
||||
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value>
|
||||
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
|
||||
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||
<value type="int">1</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||
<value type="int">16</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>Version</variable>
|
||||
<value type="int">16</value>
|
||||
</data>
|
||||
</qtcreator>
|
||||
36
Source/res/cusdr.qrc
Normal file
@ -0,0 +1,36 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>img/close.png</file>
|
||||
<file>img/close_high.png</file>
|
||||
<file>img/hide.png</file>
|
||||
<file>img/hide_high.png</file>
|
||||
<file>img/minimize.png</file>
|
||||
<file>img/minimize_high.png</file>
|
||||
<file>img/maximize.png</file>
|
||||
<file>img/maximize_high.png</file>
|
||||
<file>img/leftTop.png</file>
|
||||
<file>img/leftMiddle.png</file>
|
||||
<file>img/leftBottom.png</file>
|
||||
<file>img/left.png</file>
|
||||
<file>img/rightTop.png</file>
|
||||
<file>img/rightMiddle.png</file>
|
||||
<file>img/rightBottom.png</file>
|
||||
<file>img/right.png</file>
|
||||
<file>img/topBorder.png</file>
|
||||
<file>img/bottomBorder.png</file>
|
||||
<file>img/drawer.png</file>
|
||||
<file>img/left_arrow.png</file>
|
||||
<file>img/right_arrow.png</file>
|
||||
<file>img/up_arrow.png</file>
|
||||
<file>img/down_arrow.png</file>
|
||||
<file>img/up_arrow_off.png</file>
|
||||
<file>img/down_arrow_off.png</file>
|
||||
<file>img/cusdrLogo.png</file>
|
||||
<file>img/cuSDR_32.ico</file>
|
||||
<file>img/cuSDR_64.ico</file>
|
||||
<file>img/cusdrLogo2.png</file>
|
||||
<file>img/cudaSDRLogo.png</file>
|
||||
<file>img/cusdr4.png</file>
|
||||
<file>img/hpsdr4.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
1
Source/res/cusdr.rc
Normal file
@ -0,0 +1 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "img/cuSDR_64.ico"
|
||||
BIN
Source/res/img/MainBkg.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
Source/res/img/VolumeIcon.icns
Normal file
BIN
Source/res/img/VolumeIcon.psd
Normal file
BIN
Source/res/img/bottomBorder.png
Normal file
|
After Width: | Height: | Size: 164 B |
BIN
Source/res/img/close - Kopie.png
Normal file
|
After Width: | Height: | Size: 396 B |
BIN
Source/res/img/close.png
Normal file
|
After Width: | Height: | Size: 409 B |
BIN
Source/res/img/close_high.png
Normal file
|
After Width: | Height: | Size: 439 B |
BIN
Source/res/img/cuSDR.ico
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
Source/res/img/cuSDR_32.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
Source/res/img/cuSDR_64.ico
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
Source/res/img/cuSDR_big.ico
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
Source/res/img/cudaLogo.xcf
Normal file
BIN
Source/res/img/cudaSDRLogo.png
Normal file
|
After Width: | Height: | Size: 248 KiB |
BIN
Source/res/img/cusdr2.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
Source/res/img/cusdr3.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
Source/res/img/cusdr4.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
Source/res/img/cusdrLogo.png
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
Source/res/img/cusdrLogo2.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
Source/res/img/cusdrLogo2_org.png
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
Source/res/img/cusdrLogo3.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
Source/res/img/cusdr_hpsdr.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
Source/res/img/down_arrow.png
Normal file
|
After Width: | Height: | Size: 133 B |
BIN
Source/res/img/down_arrow_off.png
Normal file
|
After Width: | Height: | Size: 123 B |
BIN
Source/res/img/drawer.png
Normal file
|
After Width: | Height: | Size: 192 B |
BIN
Source/res/img/hide.png
Normal file
|
After Width: | Height: | Size: 435 B |
BIN
Source/res/img/hide_high.png
Normal file
|
After Width: | Height: | Size: 394 B |
BIN
Source/res/img/hpsdr4.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
Source/res/img/hpsdr5.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
Source/res/img/left - Kopie.png
Normal file
|
After Width: | Height: | Size: 94 B |
BIN
Source/res/img/left.png
Normal file
|
After Width: | Height: | Size: 184 B |
BIN
Source/res/img/leftBottom.png
Normal file
|
After Width: | Height: | Size: 193 B |
BIN
Source/res/img/leftMiddle.png
Normal file
|
After Width: | Height: | Size: 126 B |
BIN
Source/res/img/leftTop.png
Normal file
|
After Width: | Height: | Size: 162 B |
BIN
Source/res/img/left_arrow.png
Normal file
|
After Width: | Height: | Size: 197 B |
BIN
Source/res/img/maximize.png
Normal file
|
After Width: | Height: | Size: 417 B |
BIN
Source/res/img/maximize_high.png
Normal file
|
After Width: | Height: | Size: 398 B |
BIN
Source/res/img/minimize.png
Normal file
|
After Width: | Height: | Size: 499 B |
BIN
Source/res/img/minimize_high.png
Normal file
|
After Width: | Height: | Size: 467 B |
BIN
Source/res/img/record.png
Normal file
|
After Width: | Height: | Size: 670 B |
BIN
Source/res/img/right - Kopie.png
Normal file
|
After Width: | Height: | Size: 94 B |
BIN
Source/res/img/right.png
Normal file
|
After Width: | Height: | Size: 144 B |
BIN
Source/res/img/rightBottom.png
Normal file
|
After Width: | Height: | Size: 200 B |
BIN
Source/res/img/rightMiddle.png
Normal file
|
After Width: | Height: | Size: 133 B |
BIN
Source/res/img/rightTop.png
Normal file
|
After Width: | Height: | Size: 166 B |
BIN
Source/res/img/right_arrow.png
Normal file
|
After Width: | Height: | Size: 197 B |
BIN
Source/res/img/settings.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
Source/res/img/splash.psd
Normal file
BIN
Source/res/img/topBorder.png
Normal file
|
After Width: | Height: | Size: 144 B |
BIN
Source/res/img/topBorder2.png
Normal file
|
After Width: | Height: | Size: 282 B |
BIN
Source/res/img/up_arrow.png
Normal file
|
After Width: | Height: | Size: 125 B |
BIN
Source/res/img/up_arrow_off.png
Normal file
|
After Width: | Height: | Size: 126 B |
BIN
Source/res/img/upd-error.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Source/res/img/upd-info.png
Normal file
|
After Width: | Height: | Size: 955 B |
BIN
Source/res/img/upd-warning.png
Normal file
|
After Width: | Height: | Size: 853 B |
BIN
Source/res/img/warn.png
Normal file
|
After Width: | Height: | Size: 219 B |
BIN
Source/res/img/warning.png
Normal file
|
After Width: | Height: | Size: 853 B |
BIN
Source/res/img/warningMediumIcon.png
Normal file
|
After Width: | Height: | Size: 592 B |
20963
Source/res/qrc_cusdr.cpp
Normal file
1465
Source/src/AudioEngine/cusdr_audio_engine.cpp
Normal file
442
Source/src/AudioEngine/cusdr_audio_engine.h
Normal file
@ -0,0 +1,442 @@
|
||||
/**
|
||||
* @file cusdr_audio_engine.h
|
||||
* @brief cuSDR audio engine header file
|
||||
* @author adaptation for cuSDR by Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-04-02
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _CUSDR_AUDIOENGINE_H
|
||||
#define _CUSDR_AUDIOENGINE_H
|
||||
|
||||
#include "cusdr_audio_spectrum.h"
|
||||
#include "cusdr_audio_spectrumanalyser.h"
|
||||
#include "cusdr_audio_wavfile.h"
|
||||
#include "cusdr_audio_settingsdialog.h"
|
||||
|
||||
//#include <QObject>
|
||||
//#include <QByteArray>
|
||||
//#include <QBuffer>
|
||||
//#include <QVector>
|
||||
//#include <QFile>
|
||||
|
||||
#ifdef LOG_AUDIO_ENGINE
|
||||
# define AUDIO_ENGINE_DEBUG qDebug().nospace() << "AudioEngine::\t"
|
||||
#else
|
||||
# define AUDIO_ENGINE_DEBUG nullDebug()
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DUMP_CAPTURED_AUDIO
|
||||
#define DUMP_DATA
|
||||
#endif
|
||||
|
||||
#ifdef DUMP_SPECTRUM
|
||||
#define DUMP_DATA
|
||||
#endif
|
||||
|
||||
#ifdef DUMP_DATA
|
||||
#include <QDir>
|
||||
#endif
|
||||
|
||||
#define AUDIO_SAMPLE_TYPE short
|
||||
|
||||
//class SettingsDialog;
|
||||
class FrequencySpectrum;
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QAudioInput)
|
||||
QT_FORWARD_DECLARE_CLASS(QAudioOutput)
|
||||
QT_FORWARD_DECLARE_CLASS(QFile)
|
||||
|
||||
|
||||
class AudiofileBuffer;
|
||||
|
||||
typedef AUDIO_SAMPLE_TYPE(*SAMPLE_FUNCTION_TYPE)(AudiofileBuffer *abuffer, int pos, int channel);
|
||||
|
||||
|
||||
/**
|
||||
* This class interfaces with the QtMultimedia audio classes. Its role is
|
||||
* to manage the capture and playback of audio data.
|
||||
*/
|
||||
|
||||
class AudioEngine : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//AudioEngine(QObject *parent = 0);
|
||||
AudioEngine(QWidget *parent = 0);
|
||||
~AudioEngine();
|
||||
|
||||
const QList<QAudioDeviceInfo>& availableAudioInputDevices() const
|
||||
{ return m_availableAudioInputDevices; }
|
||||
|
||||
const QList<QAudioDeviceInfo>& availableAudioOutputDevices() const
|
||||
{ return m_availableAudioOutputDevices; }
|
||||
|
||||
QAudio::Mode mode() const { return m_mode; }
|
||||
QAudio::State state() const { return m_state; }
|
||||
|
||||
/**
|
||||
* \return Current audio format
|
||||
* \note May be QAudioFormat() if engine is not initialized
|
||||
*/
|
||||
const QAudioFormat& format() const { return m_format; }
|
||||
|
||||
/**
|
||||
* Stop any ongoing recording or playback, and reset to ground state.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Load data from WAV file
|
||||
*/
|
||||
bool loadFile(const QString &fileName);
|
||||
|
||||
/**
|
||||
* Generate tone
|
||||
*/
|
||||
bool generateTone(const Tone &tone);
|
||||
|
||||
/**
|
||||
* Generate tone
|
||||
*/
|
||||
//bool generateSweptTone(qreal amplitude);
|
||||
bool generateSweptTone();
|
||||
|
||||
/**
|
||||
* Generate local chirp signal
|
||||
*/
|
||||
bool generateLocalChirp();
|
||||
|
||||
/**
|
||||
* Initialize for recording
|
||||
*/
|
||||
bool initializeRecord();
|
||||
|
||||
/**
|
||||
* Position of the audio input device.
|
||||
* \return Position in bytes.
|
||||
*/
|
||||
qint64 recordPosition() const { return m_recordPosition; }
|
||||
|
||||
/**
|
||||
* RMS level of the most recently processed set of audio samples.
|
||||
* \return Level in range (0.0, 1.0)
|
||||
*/
|
||||
qreal rmsLevel() const { return m_rmsLevel; }
|
||||
|
||||
/**
|
||||
* Peak level of the most recently processed set of audio samples.
|
||||
* \return Level in range (0.0, 1.0)
|
||||
*/
|
||||
qreal peakLevel() const { return m_peakLevel; }
|
||||
|
||||
/**
|
||||
* Position of the audio output device.
|
||||
* \return Position in bytes.
|
||||
*/
|
||||
qint64 playPosition() const { return m_playPosition; }
|
||||
|
||||
/**
|
||||
* Length of the internal engine buffer.
|
||||
* \return Buffer length in bytes.
|
||||
*/
|
||||
qint64 bufferLength() const;
|
||||
|
||||
/**
|
||||
* Amount of data held in the buffer.
|
||||
* \return Data length in bytes.
|
||||
*/
|
||||
qint64 dataLength() const { return m_dataLength; }
|
||||
|
||||
/**
|
||||
* Set window function applied to audio data before spectral analysis.
|
||||
*/
|
||||
void setWindowFunction(WindowFunction type);
|
||||
|
||||
public slots:
|
||||
void startRecording();
|
||||
void startPlayback();
|
||||
void showSettingsDialog();
|
||||
void suspend();
|
||||
void setAudioInputDevice(const QAudioDeviceInfo &device);
|
||||
void setAudioOutputDevice(const QAudioDeviceInfo &device);
|
||||
|
||||
void setSystemState(
|
||||
QSDR::_Error err,
|
||||
QSDR::_HWInterfaceMode hwmode,
|
||||
QSDR::_ServerMode mode,
|
||||
QSDR::_DataEngineState state);
|
||||
|
||||
/**
|
||||
* set Chirp tone parameters
|
||||
*/
|
||||
void setChirpSignalMode(QObject *);
|
||||
//void generateChirpSignal(const SweptTone &tone);
|
||||
void generateAudioChirpSignal(const SweptTone &tone, const QAudioFormat &format, QByteArray &buffer);
|
||||
void setChirpLowerFrequency(QObject *sender, int lo);
|
||||
void setChirpUpperFrequency(QObject *sender, int lo);
|
||||
void setChirpAmplitude(QObject *sender, qreal amp);
|
||||
void setChirpBufferDurationUs(QObject *sender, qint64 value);
|
||||
void setChirpRepetitionTimes(QObject *sender, int value);
|
||||
void sampleRateChanged(QObject *sender, int value);
|
||||
|
||||
signals:
|
||||
void stateChanged(QAudio::Mode mode, QAudio::State state);
|
||||
|
||||
/**
|
||||
* Informational message for non-modal display
|
||||
*/
|
||||
void messageEvent(QString msg);
|
||||
void infoMessage(const QString &message, int durationMs);
|
||||
|
||||
/**
|
||||
* Error message for modal display
|
||||
*/
|
||||
void errorMessage(const QString &heading, const QString &detail);
|
||||
|
||||
/**
|
||||
* Format of audio data has changed
|
||||
*/
|
||||
void formatChanged(QObject *sender, const QAudioFormat &format);
|
||||
|
||||
/**
|
||||
* Length of buffer has changed.
|
||||
* \param duration Duration in microseconds
|
||||
*/
|
||||
void bufferLengthChanged(qint64 duration);
|
||||
|
||||
/**
|
||||
* Amount of data in buffer has changed.
|
||||
* \param Length of data in bytes
|
||||
*/
|
||||
void dataLengthChanged(qint64 duration);
|
||||
|
||||
/**
|
||||
* Position of the audio input device has changed.
|
||||
* \param position Position in bytes
|
||||
*/
|
||||
void recordPositionChanged(qint64 position);
|
||||
|
||||
/**
|
||||
* Position of the audio output device has changed.
|
||||
* \param position Position in bytes
|
||||
*/
|
||||
void playPositionChanged(QObject *sender, qint64 position);
|
||||
|
||||
/**
|
||||
* Level changed
|
||||
* \param rmsLevel RMS level in range 0.0 - 1.0
|
||||
* \param peakLevel Peak level in range 0.0 - 1.0
|
||||
* \param numSamples Number of audio samples analyzed
|
||||
*/
|
||||
void levelChanged(qreal rmsLevel, qreal peakLevel, int numSamples);
|
||||
|
||||
/**
|
||||
* Spectrum has changed.
|
||||
* \param position Position of start of window in bytes
|
||||
* \param length Length of window in bytes
|
||||
* \param spectrum Resulting frequency spectrum
|
||||
*/
|
||||
void spectrumChanged(qint64 position, qint64 length, const FrequencySpectrum &spectrum);
|
||||
|
||||
/**
|
||||
* Buffer containing audio data has changed.
|
||||
* \param position Position of start of buffer in bytes
|
||||
* \param buffer Buffer
|
||||
*/
|
||||
void bufferChanged(QObject *sender, qint64 position, qint64 length, const QByteArray &buffer);
|
||||
//void chirpBufferChanged(qint64 length, const QList<qreal> &buffer);
|
||||
|
||||
void chirpSignalChanged();
|
||||
void audiofileBufferChanged(const QList<qreal> &buffer);
|
||||
|
||||
private slots:
|
||||
void audioNotify();
|
||||
void audioStateChanged(QAudio::State state);
|
||||
void audioDataReady();
|
||||
void spectrumChanged(const FrequencySpectrum &spectrum);
|
||||
void spectrumListChanged(const QList<FrequencySpectrum> &spectrumList);
|
||||
|
||||
private:
|
||||
void setupConnections();
|
||||
void resetAudioDevices();
|
||||
bool initializePCMS16LE();
|
||||
bool initializePCMS32LE();
|
||||
bool selectFormat();
|
||||
void stopRecording();
|
||||
void stopPlayback();
|
||||
void setAudioState(QAudio::State state);
|
||||
void setAudioState(QAudio::Mode mode, QAudio::State state);
|
||||
void setFormat(const QAudioFormat &format);
|
||||
void setRecordPosition(qint64 position, bool forceEmit = false);
|
||||
void setPlayPosition(qint64 position, bool forceEmit = false);
|
||||
void calculateLevel(qint64 position, qint64 length);
|
||||
void calculateSpectrum(qint64 position);
|
||||
void calculateTotalSpectrum();
|
||||
void setLevel(qreal rmsLevel, qreal peakLevel, int numSamples);
|
||||
|
||||
#ifdef DUMP_DATA
|
||||
void createOutputDir();
|
||||
QString outputPath() const { return m_outputDir.path(); }
|
||||
#endif
|
||||
|
||||
#ifdef DUMP_CAPTURED_AUDIO
|
||||
void dumpData();
|
||||
#endif
|
||||
|
||||
private:
|
||||
Settings *set;
|
||||
|
||||
QAudio::Mode m_mode;
|
||||
QAudio::State m_state;
|
||||
|
||||
QSDR::_Error m_error;
|
||||
QSDR::_ServerMode m_serverMode;
|
||||
QSDR::_HWInterfaceMode m_hwInterface;
|
||||
QSDR::_DataEngineState m_dataEngineState;
|
||||
|
||||
QString m_message;
|
||||
|
||||
bool m_generateTone;
|
||||
bool m_generateLocalChirp;
|
||||
SweptTone m_tone;
|
||||
int m_lowerChirpFreq;
|
||||
int m_upperChirpFreq;
|
||||
qreal m_chirpAmplitude;
|
||||
int m_chirpSamplingFreq;
|
||||
int m_downRate;
|
||||
qint64 m_chirpBufferDurationUs;
|
||||
int m_chirpChannels;
|
||||
int m_chirpRepetition;
|
||||
|
||||
WavFile *m_file;
|
||||
// We need a second file handle via which to read data into m_buffer
|
||||
// for analysis
|
||||
WavFile *m_analysisFile;
|
||||
|
||||
QAudioFormat m_format;
|
||||
|
||||
const QList<QAudioDeviceInfo> m_availableAudioInputDevices;
|
||||
QAudioDeviceInfo m_audioInputDevice;
|
||||
QAudioInput* m_audioInput;
|
||||
QIODevice* m_audioInputIODevice;
|
||||
qint64 m_recordPosition;
|
||||
|
||||
const QList<QAudioDeviceInfo> m_availableAudioOutputDevices;
|
||||
QAudioDeviceInfo m_audioOutputDevice;
|
||||
QAudioOutput* m_audioOutput;
|
||||
qint64 m_playPosition;
|
||||
QBuffer m_audioOutputIODevice;
|
||||
|
||||
QByteArray m_buffer;
|
||||
qint64 m_bufferPosition;
|
||||
qint64 m_bufferLength;
|
||||
qint64 m_dataLength;
|
||||
|
||||
int m_levelBufferLength;
|
||||
qreal m_rmsLevel;
|
||||
qreal m_peakLevel;
|
||||
|
||||
int m_spectrumBufferLength;
|
||||
QByteArray m_spectrumBuffer;
|
||||
SpectrumAnalyser m_spectrumAnalyser;
|
||||
qint64 m_spectrumPosition;
|
||||
|
||||
int m_count;
|
||||
|
||||
SettingsDialog* setDialog;
|
||||
|
||||
int m_sampleRate;
|
||||
|
||||
AudiofileBuffer *m_audioFileBuffer;
|
||||
|
||||
#ifdef DUMP_DATA
|
||||
QDir m_outputDir;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
// *********************************************************************
|
||||
// AudiofileBuffer Class
|
||||
|
||||
class AudiofileBuffer {
|
||||
|
||||
public:
|
||||
AudiofileBuffer();
|
||||
virtual ~AudiofileBuffer();
|
||||
|
||||
static AudiofileBuffer *loadWav(QString fileName);
|
||||
//static AudiofileBuffer *loadWav( FILE *wavFile ); // support for stdio
|
||||
|
||||
void reallocate( int length );
|
||||
|
||||
inline void *getRawData() { return m_data; }
|
||||
inline int getDataLength() { return m_dataLength; }
|
||||
|
||||
inline int getBytesPerSample() { return (m_bitsPerSample >> 3); }
|
||||
inline int getBitsPerSample() { return m_bitsPerSample; }
|
||||
inline int getSamplesPerSec() { return m_samplesPerSec; }
|
||||
inline short getNofChannels() { return m_nofChannels; }
|
||||
|
||||
inline SAMPLE_FUNCTION_TYPE getSampleFunction() { return m_sampleFunction; }
|
||||
|
||||
// static implementations of sample functions
|
||||
static AUDIO_SAMPLE_TYPE sampleFunction8bitMono(AudiofileBuffer *abuffer, int pos, int channel);
|
||||
static AUDIO_SAMPLE_TYPE sampleFunction16bitMono(AudiofileBuffer *abuffer, int pos, int channel);
|
||||
static AUDIO_SAMPLE_TYPE sampleFunction8bitStereo(AudiofileBuffer *abuffer, int pos, int channel);
|
||||
static AUDIO_SAMPLE_TYPE sampleFunction16bitStereo(AudiofileBuffer *abuffer, int pos, int channel);
|
||||
|
||||
protected:
|
||||
SAMPLE_FUNCTION_TYPE m_sampleFunction;
|
||||
|
||||
short m_nofChannels;
|
||||
void *m_data;
|
||||
int m_dataLength; // in bytes
|
||||
short m_bitsPerSample;
|
||||
bool m_signedData;
|
||||
int m_samplesPerSec;
|
||||
};
|
||||
|
||||
#endif // _CUSDR_AUDIOENGINE_H
|
||||
226
Source/src/AudioEngine/cusdr_audio_settingsdialog.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
/**
|
||||
* @file cusdr_audio_settingsdialog.cpp
|
||||
* @brief cuSDR audio settings dialogue class
|
||||
* @author adaptation for cuSDR by Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-04-02
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "cusdr_audio_settingsdialog.h"
|
||||
#include "Util/cusdr_buttons.h"
|
||||
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QCheckBox>
|
||||
#include <QSlider>
|
||||
#include <QSpinBox>
|
||||
|
||||
#define btn_height 18
|
||||
#define btn_width 74
|
||||
|
||||
SettingsDialog::SettingsDialog(
|
||||
const QList<QAudioDeviceInfo> &availableInputDevices,
|
||||
const QList<QAudioDeviceInfo> &availableOutputDevices,
|
||||
QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, set(Settings::instance())
|
||||
, m_inputDeviceComboBox(new QComboBox(this))
|
||||
, m_outputDeviceComboBox(new QComboBox(this))
|
||||
//, m_windowFunction(DefaultWindowFunction)
|
||||
//, m_windowFunctionComboBox(new QComboBox(this))
|
||||
{
|
||||
if (parent)
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
|
||||
else
|
||||
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
|
||||
|
||||
setWindowModality(Qt::NonModal);
|
||||
setWindowOpacity(0.9);
|
||||
setStyleSheet(set->getDialogStyle());
|
||||
|
||||
setMouseTracking(true);
|
||||
|
||||
m_titleFont.setStyleStrategy(QFont::PreferAntialias);
|
||||
m_titleFont.setFixedPitch(true);
|
||||
#ifdef Q_OS_MAC
|
||||
m_titleFont.setPixelSize(10);
|
||||
m_titleFont.setFamily("Arial");
|
||||
//m_titleFont.setBold(true);
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
m_titleFont.setPixelSize(13);
|
||||
m_titleFont.setFamily("Arial");
|
||||
m_titleFont.setBold(true);
|
||||
//m_titleFont.setItalic(true);
|
||||
#endif
|
||||
|
||||
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
|
||||
|
||||
// Populate combo boxes
|
||||
|
||||
QAudioDeviceInfo device;
|
||||
foreach (device, availableInputDevices)
|
||||
m_inputDeviceComboBox->addItem(device.deviceName(),
|
||||
qVariantFromValue(device));
|
||||
foreach (device, availableOutputDevices)
|
||||
m_outputDeviceComboBox->addItem(device.deviceName(),
|
||||
qVariantFromValue(device));
|
||||
|
||||
//m_windowFunctionComboBox->addItem(tr("None"), qVariantFromValue(int(NoWindow)));
|
||||
//m_windowFunctionComboBox->addItem("Hann", qVariantFromValue(int(HannWindow)));
|
||||
//m_windowFunctionComboBox->setCurrentIndex(m_windowFunction);
|
||||
|
||||
m_inputDeviceComboBox->setStyleSheet(set->getComboBoxStyle());
|
||||
m_inputDeviceComboBox->setMinimumContentsLength(30);
|
||||
m_outputDeviceComboBox->setStyleSheet(set->getComboBoxStyle());
|
||||
m_outputDeviceComboBox->setMinimumContentsLength(30);
|
||||
|
||||
// Initialize default devices
|
||||
if (!availableInputDevices.empty())
|
||||
m_inputDevice = availableInputDevices.front();
|
||||
if (!availableOutputDevices.empty())
|
||||
m_outputDevice = availableOutputDevices.front();
|
||||
|
||||
// Add widgets to layout
|
||||
|
||||
QScopedPointer<QHBoxLayout> titleLayout(new QHBoxLayout);
|
||||
QLabel *titleLabel = new QLabel(tr("Audio Settings:"), this);
|
||||
titleLabel->setFont(m_titleFont);
|
||||
titleLabel->setStyleSheet(set->getLabelStyle());
|
||||
titleLayout->addWidget(titleLabel);
|
||||
dialogLayout->addLayout(titleLayout.data());
|
||||
titleLayout.take(); // ownership transferred to dialogLayout
|
||||
|
||||
QScopedPointer<QHBoxLayout> inputDeviceLayout(new QHBoxLayout);
|
||||
QLabel *inputDeviceLabel = new QLabel(tr("Input device"), this);
|
||||
inputDeviceLabel->setStyleSheet(set->getLabelStyle());
|
||||
inputDeviceLayout->addWidget(inputDeviceLabel);
|
||||
inputDeviceLayout->addWidget(m_inputDeviceComboBox);
|
||||
dialogLayout->addLayout(inputDeviceLayout.data());
|
||||
inputDeviceLayout.take(); // ownership transferred to dialogLayout
|
||||
|
||||
QScopedPointer<QHBoxLayout> outputDeviceLayout(new QHBoxLayout);
|
||||
QLabel *outputDeviceLabel = new QLabel(tr("Output device"), this);
|
||||
outputDeviceLabel->setStyleSheet(set->getLabelStyle());
|
||||
outputDeviceLayout->addWidget(outputDeviceLabel);
|
||||
outputDeviceLayout->addWidget(m_outputDeviceComboBox);
|
||||
dialogLayout->addLayout(outputDeviceLayout.data());
|
||||
outputDeviceLayout.take(); // ownership transferred to dialogLayout
|
||||
|
||||
//QScopedPointer<QHBoxLayout> windowFunctionLayout(new QHBoxLayout);
|
||||
//QLabel *windowFunctionLabel = new QLabel(tr("Window function"), this);
|
||||
//windowFunctionLayout->addWidget(windowFunctionLabel);
|
||||
//windowFunctionLayout->addWidget(m_windowFunctionComboBox);
|
||||
//dialogLayout->addLayout(windowFunctionLayout.data());
|
||||
//windowFunctionLayout.take(); // ownership transferred to dialogLayout
|
||||
|
||||
// Connect
|
||||
CHECKED_CONNECT(
|
||||
m_inputDeviceComboBox,
|
||||
SIGNAL(activated(int)),
|
||||
this,
|
||||
SLOT(inputDeviceChanged(int)));
|
||||
|
||||
CHECKED_CONNECT(
|
||||
m_outputDeviceComboBox,
|
||||
SIGNAL(activated(int)),
|
||||
this,
|
||||
SLOT(outputDeviceChanged(int)));
|
||||
|
||||
/*CHECKED_CONNECT(
|
||||
m_windowFunctionComboBox,
|
||||
SIGNAL(activated(int)),
|
||||
this,
|
||||
SLOT(windowFunctionChanged(int)));*/
|
||||
|
||||
AeroButton* okBtn = new AeroButton("Ok", this);
|
||||
okBtn->setRoundness(10);
|
||||
okBtn->setFixedSize(btn_width, btn_height);
|
||||
CHECKED_CONNECT(
|
||||
okBtn,
|
||||
SIGNAL(clicked()),
|
||||
this,
|
||||
SLOT(accept()));
|
||||
|
||||
AeroButton* cancelBtn = new AeroButton("Cancel", this);
|
||||
cancelBtn->setRoundness(10);
|
||||
cancelBtn->setFixedSize(btn_width, btn_height);
|
||||
CHECKED_CONNECT(
|
||||
cancelBtn,
|
||||
SIGNAL(clicked()),
|
||||
this,
|
||||
SLOT(reject()));
|
||||
|
||||
QHBoxLayout *hbox = new QHBoxLayout;
|
||||
hbox->setSpacing(1);
|
||||
hbox->addWidget(okBtn);
|
||||
hbox->addWidget(cancelBtn);
|
||||
|
||||
dialogLayout->addLayout(hbox);
|
||||
|
||||
setLayout(dialogLayout);
|
||||
}
|
||||
|
||||
SettingsDialog::~SettingsDialog() {
|
||||
}
|
||||
|
||||
//void SettingsDialog::windowFunctionChanged(int index)
|
||||
//{
|
||||
// m_windowFunction = static_cast<WindowFunction>(
|
||||
// m_windowFunctionComboBox->itemData(index).value<int>());
|
||||
//}
|
||||
|
||||
void SettingsDialog::inputDeviceChanged(int index) {
|
||||
|
||||
m_inputDevice = m_inputDeviceComboBox->itemData(index).value<QAudioDeviceInfo>();
|
||||
}
|
||||
|
||||
void SettingsDialog::outputDeviceChanged(int index) {
|
||||
|
||||
m_outputDevice = m_outputDeviceComboBox->itemData(index).value<QAudioDeviceInfo>();
|
||||
}
|
||||
|
||||
100
Source/src/AudioEngine/cusdr_audio_settingsdialog.h
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* @file cusdr_audio_settingsdialog.h
|
||||
* @brief cuSDR audio settings dialogue header file
|
||||
* @author adaptation for cuSDR by Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-04-02
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef SETTINGSDIALOG_H
|
||||
#define SETTINGSDIALOG_H
|
||||
|
||||
//#include "spectrum.h"
|
||||
#include <QDialog>
|
||||
#include <QAudioDeviceInfo>
|
||||
|
||||
#include "cusdr_settings.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QComboBox)
|
||||
QT_FORWARD_DECLARE_CLASS(QCheckBox)
|
||||
QT_FORWARD_DECLARE_CLASS(QSlider)
|
||||
QT_FORWARD_DECLARE_CLASS(QSpinBox)
|
||||
QT_FORWARD_DECLARE_CLASS(QGridLayout)
|
||||
|
||||
/**
|
||||
* Dialog used to control settings such as the audio input / output device
|
||||
* and the windowing function.
|
||||
*/
|
||||
class SettingsDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SettingsDialog(const QList<QAudioDeviceInfo> &availableInputDevices,
|
||||
const QList<QAudioDeviceInfo> &availableOutputDevices,
|
||||
QWidget *parent = 0);
|
||||
~SettingsDialog();
|
||||
|
||||
//WindowFunction windowFunction() const { return m_windowFunction; }
|
||||
const QAudioDeviceInfo& inputDevice() const { return m_inputDevice; }
|
||||
const QAudioDeviceInfo& outputDevice() const { return m_outputDevice; }
|
||||
|
||||
private slots:
|
||||
//void windowFunctionChanged(int index);
|
||||
void inputDeviceChanged(int index);
|
||||
void outputDeviceChanged(int index);
|
||||
|
||||
private:
|
||||
Settings* set;
|
||||
|
||||
QFont m_titleFont;
|
||||
//WindowFunction m_windowFunction;
|
||||
QAudioDeviceInfo m_inputDevice;
|
||||
QAudioDeviceInfo m_outputDevice;
|
||||
|
||||
QComboBox* m_inputDeviceComboBox;
|
||||
QComboBox* m_outputDeviceComboBox;
|
||||
|
||||
//QComboBox* m_windowFunctionComboBox;
|
||||
|
||||
};
|
||||
|
||||
#endif // SETTINGSDIALOG_H
|
||||
142
Source/src/AudioEngine/cusdr_audio_spectrum.h
Normal file
@ -0,0 +1,142 @@
|
||||
/**
|
||||
* @file cusdr_audio_spectrum.h
|
||||
* @brief cuSDR audio engine spectrum header file
|
||||
* @author adaptation for cuSDR by Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-04-02
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _CUSDR_AUDIO_SPECTRUM_H
|
||||
#define _CUSDR_AUDIO_SPECTRUM_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include "cusdr_audio_utils.h"
|
||||
//#include "fftreal_wrapper.h" // For FFTLengthPowerOfTwo
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Number of audio samples used to calculate the frequency spectrum
|
||||
//const int SpectrumLengthSamples = PowerOfTwo<FFTLengthPowerOfTwo>::Result;
|
||||
const int SpectrumLengthSamples = 2048;//4096;//1024;//256;//512;//
|
||||
|
||||
// Number of bands in the frequency spectrum
|
||||
const int SpectrumNumBands = 10;
|
||||
|
||||
// Lower bound of first band in the spectrum
|
||||
const qreal SpectrumLowFreq = 0.0; // Hz
|
||||
|
||||
// Upper band of last band in the spectrum
|
||||
const qreal SpectrumHighFreq = 1000.0; // Hz
|
||||
|
||||
// Waveform window size in microseconds
|
||||
const qint64 WaveformWindowDuration = 500 * 1000;
|
||||
|
||||
// Length of waveform tiles in bytes
|
||||
// Ideally, these would match the QAudio*::bufferSize(), but that isn't
|
||||
// available until some time after QAudio*::start() has been called, and we
|
||||
// need this value in order to initialize the waveform display.
|
||||
// We therefore just choose a sensible value.
|
||||
const int WaveformTileLength = 4096;
|
||||
|
||||
// Fudge factor used to calculate the spectrum bar heights
|
||||
const qreal SpectrumAnalyserMultiplier = 0.15;
|
||||
|
||||
// Disable message timeout
|
||||
const int NullMessageTimeout = -1;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Types and data structures
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
enum WindowFunction {
|
||||
NoWindow,
|
||||
HannWindow,
|
||||
BlackmanHarrisWindow
|
||||
};
|
||||
|
||||
const WindowFunction DefaultWindowFunction = HannWindow;//NoWindow;//BlackmanHarrisWindow;//
|
||||
|
||||
struct Tone {
|
||||
Tone(qreal freq = 0.0, qreal amp = 0.0, qint64 dur = 0)
|
||||
: frequency(freq), amplitude(amp), duration(dur)
|
||||
{ }
|
||||
|
||||
// Start and end frequencies for swept tone generation
|
||||
qreal frequency;
|
||||
|
||||
// Amplitude in range [0.0, 1.0]
|
||||
qreal amplitude;
|
||||
|
||||
// tone duration in micro seconds
|
||||
qint64 duration;
|
||||
};
|
||||
|
||||
struct SweptTone {
|
||||
SweptTone(qreal start = 0.0, qreal end = 0.0, qreal amp = 0.0, qint64 dur = 0)
|
||||
: startFreq(start), endFreq(end), amplitude(amp), duration(dur)
|
||||
{ Q_ASSERT(end >= start); }
|
||||
|
||||
SweptTone(const Tone &tone)
|
||||
: startFreq(tone.frequency), endFreq(tone.frequency), amplitude(tone.amplitude), duration(tone.duration)
|
||||
{ }
|
||||
|
||||
// Start and end frequencies for swept tone generation
|
||||
qreal startFreq;
|
||||
qreal endFreq;
|
||||
|
||||
// Amplitude in range [0.0, 1.0]
|
||||
qreal amplitude;
|
||||
|
||||
// tone duration in micro seconds
|
||||
qint64 duration;
|
||||
};
|
||||
|
||||
#ifdef DISABLE_WAVEFORM
|
||||
#undef SUPERIMPOSE_PROGRESS_ON_WAVEFORM
|
||||
#endif
|
||||
|
||||
#endif // _CUSDR_AUDIO_SPECTRUM_H
|
||||
|
||||
422
Source/src/AudioEngine/cusdr_audio_spectrumanalyser.cpp
Normal file
@ -0,0 +1,422 @@
|
||||
/**
|
||||
* @file cusdr_audio_spectrumanalyser.cpp
|
||||
* @brief cuSDR audio engine spectrumanalyser class
|
||||
* @author adaptation for cuSDR by Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-04-02
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
//#define LOG_SPECTRUMANALYSER
|
||||
//#define DUMP_SPECTRUMANALYSER
|
||||
|
||||
#include "cusdr_audio_spectrumanalyser.h"
|
||||
#include "cusdr_audio_utils.h"
|
||||
#include "cusdr_settings.h"
|
||||
|
||||
#include <QtCore/qmath.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
#include <QThread>
|
||||
|
||||
|
||||
|
||||
SpectrumAnalyserThread::SpectrumAnalyserThread(QObject *parent)
|
||||
: QObject(parent)
|
||||
, set(Settings::instance())
|
||||
, m_numSamples(SpectrumLengthSamples)
|
||||
, m_windowFunction(DefaultWindowFunction)
|
||||
, m_window(SpectrumLengthSamples, 0.0)
|
||||
, m_input(SpectrumLengthSamples, 0.0)
|
||||
, m_output(SpectrumLengthSamples, 0.0)
|
||||
, m_spectrum(SpectrumLengthSamples)
|
||||
#ifdef SPECTRUM_ANALYSER_SEPARATE_THREAD
|
||||
, m_thread(new QThread(this))
|
||||
#endif
|
||||
{
|
||||
#ifdef SPECTRUM_ANALYSER_SEPARATE_THREAD
|
||||
// moveToThread() cannot be called on a QObject with a parent
|
||||
setParent(0);
|
||||
moveToThread(m_thread);
|
||||
m_thread->start();
|
||||
#endif
|
||||
|
||||
//m_cpxInput = mallocCPX(SpectrumLengthSamples);
|
||||
m_cpxInput.resize(SpectrumLengthSamples);
|
||||
//m_cpxOutput = mallocCPX(SpectrumLengthSamples);
|
||||
m_cpxOutput.resize(SpectrumLengthSamples);
|
||||
|
||||
m_fft = new QFFT(SpectrumLengthSamples);
|
||||
|
||||
//memset(m_cpxInput, 0, SpectrumLengthSamples * sizeof(CPX));
|
||||
//memset(m_cpxOutput, 0, SpectrumLengthSamples * sizeof(CPX));
|
||||
|
||||
calculateWindow();
|
||||
}
|
||||
|
||||
SpectrumAnalyserThread::~SpectrumAnalyserThread() {
|
||||
|
||||
delete m_fft;
|
||||
}
|
||||
|
||||
void SpectrumAnalyserThread::setWindowFunction(WindowFunction type) {
|
||||
|
||||
m_windowFunction = type;
|
||||
calculateWindow();
|
||||
}
|
||||
|
||||
void SpectrumAnalyserThread::calculateWindow() {
|
||||
|
||||
for (int i = 0; i < m_numSamples; ++i) {
|
||||
|
||||
DataType x = 0.0;
|
||||
|
||||
switch (m_windowFunction) {
|
||||
|
||||
case NoWindow:
|
||||
x = 1.0;
|
||||
break;
|
||||
|
||||
case HannWindow:
|
||||
x = 0.5 * (1 - qCos((TWOPI * i) / (m_numSamples - 1)));
|
||||
break;
|
||||
|
||||
case BlackmanHarrisWindow: {
|
||||
float
|
||||
a0 = 0.35875F,
|
||||
a1 = 0.48829F,
|
||||
a2 = 0.14128F,
|
||||
a3 = 0.01168F;
|
||||
|
||||
|
||||
x = a0 - a1* cos(TWOPI * (i + 0.5) / m_numSamples)
|
||||
+ a2* cos(2.0 * TWOPI * (i + 0.5) / m_numSamples)
|
||||
- a3* cos(3.0 * TWOPI * (i + 0.5) / m_numSamples);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
m_window[i] = x;
|
||||
}
|
||||
}
|
||||
|
||||
void SpectrumAnalyserThread::calculateTotalSpectrum(const QByteArray &buffer, int inputFrequency, int bytesPerSample) {
|
||||
|
||||
if (m_spectrumList.count() > 0)
|
||||
m_spectrumList.clear();
|
||||
|
||||
int samples = bytesPerSample * m_numSamples;
|
||||
int buffers = qRound((float) buffer.size() / samples);
|
||||
|
||||
// cycle over all buffers
|
||||
for (int i = 0; i < buffers; i++) {
|
||||
|
||||
//if (i == buffers-1 && overhead > 0)
|
||||
m_tmp = QByteArray::fromRawData(buffer.constData() + i * samples, samples);
|
||||
|
||||
//Q_ASSERT(m_tmp.size() == m_numSamples * bytesPerSample);
|
||||
|
||||
// Initialize data array
|
||||
const char *ptr = m_tmp.constData();
|
||||
|
||||
for (int j = 0; j < m_numSamples; ++j) {
|
||||
|
||||
const qint16 pcmSample = *reinterpret_cast<const qint16*>(ptr);
|
||||
// Scale down to range [-1.0, 1.0]
|
||||
const DataType realSample = pcmToReal(pcmSample);
|
||||
const DataType windowedSample = realSample * m_window[j];
|
||||
|
||||
m_cpxInput[j].re = windowedSample;
|
||||
m_cpxInput[j].im = 0.0f;
|
||||
|
||||
ptr += bytesPerSample;
|
||||
}
|
||||
|
||||
// calculate the FFT
|
||||
m_fft->DoFFTWForward(m_cpxInput, m_cpxOutput, SpectrumLengthSamples);
|
||||
|
||||
/*for (int i = 0; i < BUFFER_SIZE; i += 32) {
|
||||
qDebug() << "m_cpxOutput.re =" << m_cpxOutput[i].re << "m_cpxOutput.im =" << m_cpxOutput[i].im;
|
||||
}*/
|
||||
|
||||
// Analyze output to obtain amplitude and phase for each frequency
|
||||
for (int i = 2; i <= m_numSamples / 2; ++i) {
|
||||
|
||||
// Calculate frequency of this complex sample
|
||||
m_spectrum[i].frequency = qreal(i * inputFrequency) / (m_numSamples);
|
||||
|
||||
//const qreal real = m_output[i];
|
||||
const qreal real = m_cpxOutput[i].re;
|
||||
qreal imag = 0.0;
|
||||
|
||||
if (i > 0 && i < m_numSamples / 2)
|
||||
imag = m_cpxOutput[m_numSamples/2 + i].re;
|
||||
|
||||
const qreal magnitude = sqrt(real*real + imag*imag);
|
||||
qreal amplitude = SpectrumAnalyserMultiplier * log(magnitude);
|
||||
|
||||
// Bound amplitude to [0.0, 1.0]
|
||||
m_spectrum[i].clipped = (amplitude > 1.0);
|
||||
amplitude = qMax(qreal(0.0), amplitude);
|
||||
amplitude = qMin(qreal(1.0), amplitude);
|
||||
m_spectrum[i].amplitude = amplitude;
|
||||
}
|
||||
m_spectrumList.append(m_spectrum);
|
||||
}
|
||||
emit calculationTotalComplete(m_spectrumList);
|
||||
}
|
||||
|
||||
void SpectrumAnalyserThread::calculateSpectrum(const QByteArray &buffer, int inputFrequency, int bytesPerSample) {
|
||||
|
||||
Q_ASSERT(buffer.size() == m_numSamples * bytesPerSample);
|
||||
|
||||
// Initialize data array
|
||||
const char *ptr = buffer.constData();
|
||||
for (int i = 0; i < m_numSamples; ++i) {
|
||||
|
||||
const qint16 pcmSample = *reinterpret_cast<const qint16*>(ptr);
|
||||
// Scale down to range [-1.0, 1.0]
|
||||
const DataType realSample = pcmToReal(pcmSample);
|
||||
const DataType windowedSample = realSample * m_window[i];
|
||||
m_input[i] = windowedSample;
|
||||
m_cpxInput[i].re = windowedSample;
|
||||
m_cpxInput[i].im = 0.0f;
|
||||
ptr += bytesPerSample;
|
||||
}
|
||||
|
||||
// Calculate the FFT
|
||||
m_fft->DoFFTWForward(m_cpxInput, m_cpxOutput, SpectrumLengthSamples);
|
||||
|
||||
// Analyze output to obtain amplitude and phase for each frequency
|
||||
for (int i = 2; i <= m_numSamples / 2; ++i) {
|
||||
// Calculate frequency of this complex sample
|
||||
m_spectrum[i].frequency = qreal(i * inputFrequency) / (m_numSamples);
|
||||
|
||||
//const qreal real = m_output[i];
|
||||
const qreal real = m_cpxOutput[i].re;
|
||||
qreal imag = 0.0;
|
||||
if (i > 0 && i < m_numSamples / 2)
|
||||
//imag = m_output[m_numSamples/2 + i];
|
||||
imag = m_cpxOutput[m_numSamples/2 + i].re;
|
||||
|
||||
const qreal magnitude = sqrt(real*real + imag*imag);
|
||||
qreal amplitude = SpectrumAnalyserMultiplier * log(magnitude);
|
||||
|
||||
// Bound amplitude to [0.0, 1.0]
|
||||
m_spectrum[i].clipped = (amplitude > 1.0);
|
||||
amplitude = qMax(qreal(0.0), amplitude);
|
||||
amplitude = qMin(qreal(1.0), amplitude);
|
||||
m_spectrum[i].amplitude = amplitude;
|
||||
}
|
||||
|
||||
emit calculationComplete(m_spectrum);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// SpectrumAnalyser
|
||||
//=============================================================================
|
||||
|
||||
SpectrumAnalyser::SpectrumAnalyser(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_thread(new SpectrumAnalyserThread(this))
|
||||
, m_state(Idle)
|
||||
#ifdef DUMP_SPECTRUMANALYSER
|
||||
, m_count(0)
|
||||
#endif
|
||||
{
|
||||
CHECKED_CONNECT(
|
||||
m_thread,
|
||||
SIGNAL(calculationComplete(FrequencySpectrum)),
|
||||
this,
|
||||
SLOT(calculationComplete(FrequencySpectrum)));
|
||||
|
||||
CHECKED_CONNECT(
|
||||
m_thread,
|
||||
SIGNAL(calculationTotalComplete(QList<FrequencySpectrum>)),
|
||||
this,
|
||||
SLOT(calculationTotalComplete(QList<FrequencySpectrum>)));
|
||||
}
|
||||
|
||||
SpectrumAnalyser::~SpectrumAnalyser() {
|
||||
}
|
||||
|
||||
#ifdef DUMP_SPECTRUMANALYSER
|
||||
void SpectrumAnalyser::setOutputPath(const QString &outputDir)
|
||||
{
|
||||
m_outputDir.setPath(outputDir);
|
||||
m_textFile.setFileName(m_outputDir.filePath("spectrum.txt"));
|
||||
m_textFile.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
m_textStream.setDevice(&m_textFile);
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SpectrumAnalyser::setWindowFunction(WindowFunction type) {
|
||||
|
||||
const bool b = QMetaObject::invokeMethod(m_thread, "setWindowFunction",
|
||||
Qt::AutoConnection,
|
||||
Q_ARG(WindowFunction, type));
|
||||
Q_ASSERT(b);
|
||||
Q_UNUSED(b) // suppress warnings in release builds
|
||||
}
|
||||
|
||||
void SpectrumAnalyser::calculateTotal(
|
||||
qint64 position,
|
||||
qint64 length,
|
||||
const QAudioFormat &format,
|
||||
const QByteArray &buffer
|
||||
) {
|
||||
Q_UNUSED(position)
|
||||
Q_UNUSED(length)
|
||||
|
||||
SPECTRUMANALYSER_DEBUG << "SpectrumAnalyser::calculateTotal"
|
||||
<< QThread::currentThread()
|
||||
<< "state" << m_state;
|
||||
|
||||
SPECTRUMANALYSER_DEBUG << "buffer size =" << buffer.size();
|
||||
|
||||
if (isReady()) {
|
||||
Q_ASSERT(isPCMS16LE(format));
|
||||
|
||||
const int bytesPerSample = format.sampleSize() * format.channelCount() / 8;
|
||||
|
||||
m_state = Busy;
|
||||
|
||||
// Invoke SpectrumAnalyserThread::calculateTotalSpectrum using QMetaObject.
|
||||
// If m_thread is in a different thread from the current thread, the
|
||||
// calculation will be done in the child thread.
|
||||
// Once the calculation is finished, a calculationChanged signal will be
|
||||
// emitted by m_thread.
|
||||
const bool b = QMetaObject::invokeMethod(m_thread, "calculateTotalSpectrum",
|
||||
Qt::AutoConnection,
|
||||
Q_ARG(QByteArray, buffer),
|
||||
Q_ARG(int, format.sampleRate()),
|
||||
Q_ARG(int, bytesPerSample));
|
||||
Q_ASSERT(b);
|
||||
Q_UNUSED(b) // suppress warnings in release builds
|
||||
}
|
||||
}
|
||||
|
||||
void SpectrumAnalyser::calculate(const QByteArray &buffer,
|
||||
const QAudioFormat &format)
|
||||
{
|
||||
// QThread::currentThread is marked 'for internal use only', but
|
||||
// we're only using it for debug output here, so it's probably OK :)
|
||||
SPECTRUMANALYSER_DEBUG << "SpectrumAnalyser::calculate"
|
||||
<< QThread::currentThread()
|
||||
<< "state" << m_state;
|
||||
|
||||
SPECTRUMANALYSER_DEBUG << "buffer size =" << buffer.size();
|
||||
|
||||
if (isReady()) {
|
||||
Q_ASSERT(isPCMS16LE(format));
|
||||
|
||||
const int bytesPerSample = format.sampleSize() * format.channelCount() / 8;
|
||||
|
||||
m_state = Busy;
|
||||
|
||||
// Invoke SpectrumAnalyserThread::calculateSpectrum using QMetaObject. If
|
||||
// m_thread is in a different thread from the current thread, the
|
||||
// calculation will be done in the child thread.
|
||||
// Once the calculation is finished, a calculationChanged signal will be
|
||||
// emitted by m_thread.
|
||||
const bool b = QMetaObject::invokeMethod(m_thread, "calculateSpectrum",
|
||||
Qt::AutoConnection,
|
||||
Q_ARG(QByteArray, buffer),
|
||||
Q_ARG(int, format.sampleRate()),
|
||||
Q_ARG(int, bytesPerSample));
|
||||
Q_ASSERT(b);
|
||||
Q_UNUSED(b) // suppress warnings in release builds
|
||||
|
||||
#ifdef DUMP_SPECTRUMANALYSER
|
||||
m_textStream << "FrequencySpectrum " << m_count << "\n";
|
||||
FrequencySpectrum::const_iterator x = m_spectrum.begin();
|
||||
for (int i=0; i<m_numSamples; ++i, ++x)
|
||||
m_textStream << i << "\t"
|
||||
<< x->frequency << "\t"
|
||||
<< x->amplitude<< "\t"
|
||||
<< x->phase << "\n";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool SpectrumAnalyser::isReady() const {
|
||||
|
||||
return (Idle == m_state);
|
||||
}
|
||||
|
||||
void SpectrumAnalyser::cancelCalculation() {
|
||||
|
||||
if (Busy == m_state)
|
||||
m_state = Cancelled;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Private slots
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SpectrumAnalyser::calculationComplete(const FrequencySpectrum &spectrum) {
|
||||
|
||||
Q_ASSERT(Idle != m_state);
|
||||
if (Busy == m_state)
|
||||
emit spectrumChanged(spectrum);
|
||||
m_state = Idle;
|
||||
}
|
||||
|
||||
void SpectrumAnalyser::calculationTotalComplete(const QList<FrequencySpectrum> &m_spectrumList) {
|
||||
|
||||
Q_ASSERT(Idle != m_state);
|
||||
if (Busy == m_state)
|
||||
emit spectrumListChanged(m_spectrumList);
|
||||
m_state = Idle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
229
Source/src/AudioEngine/cusdr_audio_spectrumanalyser.h
Normal file
@ -0,0 +1,229 @@
|
||||
/**
|
||||
* @file cusdr_audio_spectrumanalyser.h
|
||||
* @brief cuSDR audio engine spectrumanalyser header file
|
||||
* @author adaptation for cuSDR by Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-04-02
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _CUSDR_AUDIO_SPECTRUMANALYSER_H
|
||||
#define _CUSDR_AUDIO_SPECTRUMANALYSER_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
#ifdef DUMP_SPECTRUMANALYSER
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#endif
|
||||
|
||||
//#define SPECTRUM_ANALYSER_SEPARATE_THREAD
|
||||
|
||||
//#include "frequencyspectrum.h"
|
||||
#include "cusdr_audio_spectrum.h"
|
||||
#include "cusdr_settings.h"
|
||||
#include "QtDSP/qtdsp_fft.h"
|
||||
#include "QtDSP/qtdsp_qComplex.h"
|
||||
//#include "cusdr_filter.h"
|
||||
|
||||
#ifdef LOG_SPECTRUMANALYSER
|
||||
# define SPECTRUMANALYSER_DEBUG qDebug().nospace() << "SpectrumAnalyzer::\t"
|
||||
#else
|
||||
# define SPECTRUMANALYSER_DEBUG nullDebug()
|
||||
#endif
|
||||
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QAudioFormat)
|
||||
QT_FORWARD_DECLARE_CLASS(QThread)
|
||||
|
||||
//class SpectrumAnalyserThreadPrivate;
|
||||
|
||||
/**
|
||||
* Implementation of the spectrum analysis which can be run in a
|
||||
* separate thread.
|
||||
*/
|
||||
class SpectrumAnalyserThread : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SpectrumAnalyserThread(QObject *parent);
|
||||
~SpectrumAnalyserThread();
|
||||
|
||||
public slots:
|
||||
void setWindowFunction(WindowFunction type);
|
||||
|
||||
void calculateSpectrum(
|
||||
const QByteArray &buffer,
|
||||
int inputFrequency,
|
||||
int bytesPerSample);
|
||||
|
||||
void calculateTotalSpectrum(
|
||||
const QByteArray &buffer,
|
||||
int inputFrequency,
|
||||
int bytesPerSample);
|
||||
|
||||
signals:
|
||||
void calculationComplete(const FrequencySpectrum &spectrum);
|
||||
void calculationTotalComplete(const QList<FrequencySpectrum> &spectrumList);
|
||||
|
||||
private:
|
||||
void calculateWindow();
|
||||
|
||||
private:
|
||||
Settings* set;
|
||||
int m_numSamples;
|
||||
|
||||
WindowFunction m_windowFunction;
|
||||
|
||||
//typedef qreal DataType;
|
||||
typedef float DataType;
|
||||
|
||||
QVector<DataType> m_window;
|
||||
|
||||
QVector<DataType> m_input;
|
||||
QVector<DataType> m_output;
|
||||
|
||||
CPX m_cpxInput;
|
||||
CPX m_cpxOutput;
|
||||
|
||||
QFFT *m_fft;
|
||||
|
||||
QByteArray m_tmp;
|
||||
|
||||
FrequencySpectrum m_spectrum;
|
||||
|
||||
QList<FrequencySpectrum> m_spectrumList;
|
||||
|
||||
#ifdef SPECTRUM_ANALYSER_SEPARATE_THREAD
|
||||
QThread* m_thread;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Class which performs frequency spectrum analysis on a window of
|
||||
* audio samples, provided to it by the Engine.
|
||||
*/
|
||||
class SpectrumAnalyser : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SpectrumAnalyser(QObject *parent = 0);
|
||||
~SpectrumAnalyser();
|
||||
|
||||
#ifdef DUMP_SPECTRUMANALYSER
|
||||
void setOutputPath(const QString &outputPath);
|
||||
#endif
|
||||
|
||||
public:
|
||||
/*
|
||||
* Set the windowing function which is applied before calculating the FFT
|
||||
*/
|
||||
void setWindowFunction(WindowFunction type);
|
||||
|
||||
/*
|
||||
* Calculate a frequency spectrum
|
||||
*
|
||||
* \param buffer Audio data
|
||||
* \param format Format of audio data
|
||||
*
|
||||
* Frequency spectrum is calculated asynchronously. The result is returned
|
||||
* via the spectrumChanged signal.
|
||||
*
|
||||
* An ongoing calculation can be cancelled by calling cancelCalculation().
|
||||
*
|
||||
*/
|
||||
void calculate(const QByteArray &buffer, const QAudioFormat &format);
|
||||
|
||||
void calculateTotal(
|
||||
qint64 position,
|
||||
qint64 length,
|
||||
const QAudioFormat &format,
|
||||
const QByteArray &buffer);
|
||||
|
||||
/*
|
||||
* Check whether the object is ready to perform another calculation
|
||||
*/
|
||||
bool isReady() const;
|
||||
|
||||
/*
|
||||
* Cancel an ongoing calculation
|
||||
*
|
||||
* Note that cancelling is asynchronous.
|
||||
*/
|
||||
void cancelCalculation();
|
||||
|
||||
signals:
|
||||
void spectrumChanged(const FrequencySpectrum &spectrum);
|
||||
void spectrumListChanged(const QList<FrequencySpectrum> &spectrumList);
|
||||
|
||||
private slots:
|
||||
void calculationComplete(const FrequencySpectrum &spectrum);
|
||||
void calculationTotalComplete(const QList<FrequencySpectrum> &m_spectrumList);
|
||||
|
||||
private:
|
||||
void calculateWindow();
|
||||
|
||||
private:
|
||||
|
||||
SpectrumAnalyserThread* m_thread;
|
||||
|
||||
enum State {
|
||||
Idle,
|
||||
Busy,
|
||||
Cancelled
|
||||
};
|
||||
|
||||
State m_state;
|
||||
|
||||
#ifdef DUMP_SPECTRUMANALYSER
|
||||
QDir m_outputDir;
|
||||
int m_count;
|
||||
QFile m_textFile;
|
||||
QTextStream m_textStream;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // _CUSDR_AUDIO_SPECTRUMANALYSER_H
|
||||
|
||||
155
Source/src/AudioEngine/cusdr_audio_utils.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
/**
|
||||
* @file cusdr_audio_utils.cpp
|
||||
* @brief cuSDR audio utils class
|
||||
* @author adaptation for cuSDR by Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-04-02
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "cusdr_audio_utils.h"
|
||||
|
||||
qint64 audioDuration(const QAudioFormat &format, qint64 bytes) {
|
||||
|
||||
return (bytes * 1000000) /
|
||||
(format.sampleRate() * format.channelCount() * (format.sampleSize() / 8));
|
||||
}
|
||||
|
||||
qint64 audioLength(const QAudioFormat &format, qint64 microSeconds) {
|
||||
|
||||
qint64 result = (format.sampleRate() * format.channelCount() * (format.sampleSize() / 8))
|
||||
* microSeconds / 1000000;
|
||||
result -= result % (format.channelCount() * format.sampleSize());
|
||||
return result;
|
||||
}
|
||||
|
||||
qreal nyquistFrequency(const QAudioFormat &format) {
|
||||
|
||||
return format.sampleRate() / 2;
|
||||
}
|
||||
|
||||
QString formatToString(const QAudioFormat &format) {
|
||||
|
||||
QString result;
|
||||
|
||||
if (QAudioFormat() != format) {
|
||||
if (format.codec() == "audio/pcm") {
|
||||
Q_ASSERT(format.sampleType() == QAudioFormat::SignedInt);
|
||||
|
||||
const QString formatEndian = (format.byteOrder() == QAudioFormat::LittleEndian)
|
||||
? QString("LE") : QString("BE");
|
||||
|
||||
QString formatType;
|
||||
switch(format.sampleType()) {
|
||||
case QAudioFormat::SignedInt:
|
||||
formatType = "signed";
|
||||
break;
|
||||
case QAudioFormat::UnSignedInt:
|
||||
formatType = "unsigned";
|
||||
break;
|
||||
case QAudioFormat::Float:
|
||||
formatType = "float";
|
||||
break;
|
||||
case QAudioFormat::Unknown:
|
||||
formatType = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
QString formatChannels = QString("%1 channels").arg(format.channelCount());
|
||||
switch (format.channelCount()) {
|
||||
case 1:
|
||||
formatChannels = "mono";
|
||||
break;
|
||||
case 2:
|
||||
formatChannels = "stereo";
|
||||
break;
|
||||
}
|
||||
|
||||
result = QString("%1 Hz %2 bit %3 %4 %5")
|
||||
.arg(format.sampleRate())
|
||||
.arg(format.sampleSize())
|
||||
.arg(formatType)
|
||||
.arg(formatEndian)
|
||||
.arg(formatChannels);
|
||||
} else {
|
||||
result = format.codec();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isPCM(const QAudioFormat &format) {
|
||||
|
||||
return (format.codec() == "audio/pcm");
|
||||
}
|
||||
|
||||
|
||||
bool isPCMS16LE(const QAudioFormat &format) {
|
||||
|
||||
return (isPCM(format) &&
|
||||
format.sampleType() == QAudioFormat::SignedInt &&
|
||||
format.sampleSize() == 16 &&
|
||||
format.byteOrder() == QAudioFormat::LittleEndian);
|
||||
}
|
||||
|
||||
bool isPCMS32LE(const QAudioFormat &format) {
|
||||
|
||||
return (isPCM(format) &&
|
||||
format.sampleType() == QAudioFormat::SignedInt &&
|
||||
format.sampleSize() == 32 &&
|
||||
format.byteOrder() == QAudioFormat::LittleEndian);
|
||||
}
|
||||
|
||||
const qint16 PCMS16MaxValue = 32767;
|
||||
const quint16 PCMS16MaxAmplitude = 32768; // because minimum is -32768
|
||||
|
||||
qreal pcmToReal(qint16 pcm) {
|
||||
|
||||
return qreal(pcm) / PCMS16MaxAmplitude;
|
||||
}
|
||||
|
||||
qint16 realToPcm(qreal real) {
|
||||
|
||||
return real * PCMS16MaxValue;
|
||||
}
|
||||
96
Source/src/AudioEngine/cusdr_audio_utils.h
Normal file
@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @file cusdr_audio_utils.h
|
||||
* @brief cuSDR audio utils header file
|
||||
* @author adaptation for cuSDR by Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-04-02
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _CUSDR_AUDIO_UTILS_H
|
||||
#define _CUSDR_AUDIO_UTILS_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QDebug>
|
||||
|
||||
#include <QAudioFormat>
|
||||
|
||||
#if defined(Q_OS_WIN32)
|
||||
QT_FORWARD_DECLARE_CLASS(QAudioFormat)
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Miscellaneous utility functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
qint64 audioDuration(const QAudioFormat &format, qint64 bytes);
|
||||
qint64 audioLength(const QAudioFormat &format, qint64 microSeconds);
|
||||
|
||||
QString formatToString(const QAudioFormat &format);
|
||||
|
||||
qreal nyquistFrequency(const QAudioFormat &format);
|
||||
|
||||
// Scale PCM value to [-1.0, 1.0]
|
||||
qreal pcmToReal(qint16 pcm);
|
||||
|
||||
// Scale real value in [-1.0, 1.0] to PCM
|
||||
qint16 realToPcm(qreal real);
|
||||
|
||||
// Check whether the audio format is PCM
|
||||
bool isPCM(const QAudioFormat &format);
|
||||
|
||||
// Check whether the audio format is signed, little-endian, 16-bit PCM
|
||||
bool isPCMS16LE(const QAudioFormat &format);
|
||||
|
||||
// Check whether the audio format is float, little-endian, 32-bit PCM
|
||||
bool isPCMS32LE(const QAudioFormat &format);
|
||||
|
||||
// Compile-time calculation of powers of two
|
||||
|
||||
template<int N> class PowerOfTwo
|
||||
{ public: static const int Result = PowerOfTwo<N-1>::Result * 2; };
|
||||
|
||||
template<> class PowerOfTwo<0>
|
||||
{ public: static const int Result = 1; };
|
||||
|
||||
|
||||
#endif // _CUSDR_AUDIO_UTILS_H
|
||||
484
Source/src/AudioEngine/cusdr_audio_waveform.cpp
Normal file
@ -0,0 +1,484 @@
|
||||
/**
|
||||
* @file cusdr_audio_waveform.cpp
|
||||
* @brief cuSDR waveform graphics
|
||||
* @author adaptation for cuSDR by Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-04-02
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
//#define LOG_WAVEFORM
|
||||
//#define LOG_PAINT_EVENT
|
||||
|
||||
#include "cusdr_audio_utils.h"
|
||||
#include "cusdr_audio_waveform.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QResizeEvent>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
|
||||
Waveform::Waveform(QObject *parent)
|
||||
: QObject(parent)
|
||||
, set(Settings::instance())
|
||||
, m_bufferPosition(0)
|
||||
, m_bufferLength(0)
|
||||
, m_audioPosition(0)
|
||||
, m_active(false)
|
||||
, m_tileLength(0)
|
||||
, m_tileArrayStart(0)
|
||||
, m_windowPosition(0)
|
||||
, m_windowLength(0)
|
||||
, m_waveformDisplayWidth(0)
|
||||
{
|
||||
}
|
||||
|
||||
Waveform::~Waveform() {
|
||||
|
||||
deletePixmaps();
|
||||
}
|
||||
|
||||
QImage* Waveform::createWaveformImage(const QRect &rect) {
|
||||
|
||||
if (!rect.isValid()) return NULL;
|
||||
|
||||
QImage *image = new QImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
|
||||
if (!image) return NULL;
|
||||
|
||||
m_waveformDisplayWidth = image->width();
|
||||
|
||||
image->fill(QColor(0, 0, 0, 255).rgba());
|
||||
|
||||
QPainter painter(image);
|
||||
|
||||
if (m_active) {
|
||||
|
||||
WAVEFORM_PAINT_DEBUG << "paintEvent"
|
||||
<< "windowPosition" << m_windowPosition
|
||||
<< "windowLength" << m_windowLength;
|
||||
qint64 pos = m_windowPosition;
|
||||
const qint64 windowEnd = m_windowPosition + m_windowLength;
|
||||
int destLeft = 0;
|
||||
int destRight = 0;
|
||||
while (pos < windowEnd) {
|
||||
|
||||
const TilePoint point = tilePoint(pos);
|
||||
WAVEFORM_PAINT_DEBUG << "paintEvent" << "pos" << pos
|
||||
<< "tileIndex" << point.index
|
||||
<< "positionOffset" << point.positionOffset
|
||||
<< "pixelOffset" << point.pixelOffset;
|
||||
|
||||
if (point.index != NullIndex) {
|
||||
|
||||
const Tile &tile = m_tiles[point.index];
|
||||
if (tile.painted) {
|
||||
|
||||
const qint64 sectionLength = qMin((m_tileLength - point.positionOffset),
|
||||
(windowEnd - pos));
|
||||
Q_ASSERT(sectionLength > 0);
|
||||
|
||||
const int sourceRight = tilePixelOffset(point.positionOffset + sectionLength);
|
||||
//destRight = windowPixelOffset(pos - m_windowPosition + sectionLength);
|
||||
destRight = windowPixelOffset(pos - m_windowPosition + sectionLength, rect);
|
||||
|
||||
QRect destRect = rect;//();
|
||||
destRect.setTop(20);
|
||||
destRect.setHeight(rect.height() - 20);
|
||||
destRect.setLeft(destLeft);
|
||||
destRect.setRight(destRight);
|
||||
//destRect.setRect(0, 0, destLeft + destRight, rect.height());
|
||||
|
||||
QRect sourceRect(QPoint(), m_pixmapSize);
|
||||
sourceRect.setLeft(point.pixelOffset);
|
||||
sourceRect.setRight(sourceRight);
|
||||
|
||||
WAVEFORM_PAINT_DEBUG << "paintEvent" << "tileIndex" << point.index
|
||||
<< "source" << point.pixelOffset << sourceRight
|
||||
<< "dest" << destLeft << destRight;
|
||||
|
||||
//painter.drawPixmap(destRect, *tile.pixmap, sourceRect);
|
||||
painter.drawPixmap(destRect, *tile.pixmap, sourceRect);
|
||||
|
||||
destLeft = destRight;
|
||||
|
||||
if (point.index < m_tiles.count()) {
|
||||
|
||||
pos = tilePosition(point.index + 1);
|
||||
WAVEFORM_PAINT_DEBUG << "paintEvent" << "pos ->" << pos;
|
||||
}
|
||||
else {
|
||||
// Reached end of tile array
|
||||
WAVEFORM_PAINT_DEBUG << "paintEvent" << "reached end of tile array";
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Passed last tile which is painted
|
||||
WAVEFORM_PAINT_DEBUG << "paintEvent" << "tile" << point.index << "not painted";
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// pos is past end of tile array
|
||||
WAVEFORM_PAINT_DEBUG << "paintEvent" << "pos" << pos << "past end of tile array";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WAVEFORM_PAINT_DEBUG << "paintEvent" << "final pos" << pos << "final x" << destRight;
|
||||
}
|
||||
painter.end();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void Waveform::initialize(const QAudioFormat &format, qint64 audioBufferSize, qint64 windowDurationUs, const QRect &rect) {
|
||||
|
||||
WAVEFORM_DEBUG << "initialize"
|
||||
<< "audioBufferSize" << audioBufferSize
|
||||
<< "windowDurationUs" << windowDurationUs;
|
||||
|
||||
reset();
|
||||
|
||||
m_format = format;
|
||||
m_audioRect = rect;
|
||||
|
||||
// Calculate tile size
|
||||
m_tileLength = audioBufferSize;
|
||||
|
||||
// Calculate window size
|
||||
m_windowLength = audioLength(m_format, windowDurationUs);
|
||||
|
||||
// Calculate number of tiles required
|
||||
int nTiles;
|
||||
if (m_tileLength > m_windowLength) {
|
||||
nTiles = 2;
|
||||
} else {
|
||||
nTiles = m_windowLength / m_tileLength + 1;
|
||||
if (m_windowLength % m_tileLength)
|
||||
++nTiles;
|
||||
}
|
||||
|
||||
WAVEFORM_DEBUG << "initialize"
|
||||
<< "tileLength" << m_tileLength
|
||||
<< "windowLength" << m_windowLength
|
||||
<< "nTiles" << nTiles;
|
||||
|
||||
m_pixmaps.fill(0, nTiles);
|
||||
m_tiles.resize(nTiles);
|
||||
|
||||
createPixmaps(m_audioRect.size());
|
||||
|
||||
m_active = true;
|
||||
}
|
||||
|
||||
void Waveform::reset()
|
||||
{
|
||||
WAVEFORM_DEBUG << "reset";
|
||||
|
||||
m_bufferPosition = 0;
|
||||
m_buffer = QByteArray();
|
||||
m_audioPosition = 0;
|
||||
m_format = QAudioFormat();
|
||||
m_active = false;
|
||||
deletePixmaps();
|
||||
m_tiles.clear();
|
||||
m_tileLength = 0;
|
||||
m_tileArrayStart = 0;
|
||||
m_windowPosition = 0;
|
||||
m_windowLength = 0;
|
||||
}
|
||||
|
||||
void Waveform::bufferChanged(QObject *sender, qint64 position, qint64 length, const QByteArray &buffer) {
|
||||
|
||||
Q_UNUSED (sender)
|
||||
|
||||
WAVEFORM_DEBUG << "bufferChanged"
|
||||
<< "audioPosition" << m_audioPosition
|
||||
<< "bufferPosition" << position
|
||||
<< "bufferLength" << length;
|
||||
m_bufferPosition = position;
|
||||
m_bufferLength = length;
|
||||
m_buffer = buffer;
|
||||
paintTiles();
|
||||
}
|
||||
|
||||
void Waveform::audioPositionChanged(QObject *sender, qint64 position)
|
||||
{
|
||||
Q_UNUSED (sender)
|
||||
|
||||
WAVEFORM_DEBUG << "audioPositionChanged"
|
||||
<< "audioPosition" << position
|
||||
<< "bufferPosition" << m_bufferPosition
|
||||
<< "bufferLength" << m_bufferLength;
|
||||
|
||||
if (position >= m_bufferPosition) {
|
||||
if (position + m_windowLength > m_bufferPosition + m_bufferLength)
|
||||
position = qMax(qint64(0), m_bufferPosition + m_bufferLength - m_windowLength);
|
||||
m_audioPosition = position;
|
||||
setWindowPosition(position);
|
||||
}
|
||||
}
|
||||
|
||||
void Waveform::deletePixmaps()
|
||||
{
|
||||
QPixmap *pixmap;
|
||||
foreach (pixmap, m_pixmaps)
|
||||
delete pixmap;
|
||||
m_pixmaps.clear();
|
||||
}
|
||||
|
||||
void Waveform::createPixmaps(const QSize &rect) {
|
||||
|
||||
m_pixmapSize = rect;
|
||||
|
||||
if (m_windowLength > 0)
|
||||
m_pixmapSize.setWidth(qreal(rect.width()) * m_tileLength / m_windowLength);
|
||||
else
|
||||
m_pixmapSize.setWidth(qreal(rect.width()));
|
||||
|
||||
WAVEFORM_DEBUG << "createPixmaps"
|
||||
<< "rectSize" << rect
|
||||
<< "pixmapSize" << m_pixmapSize;
|
||||
|
||||
Q_ASSERT(m_tiles.count() == m_pixmaps.count());
|
||||
|
||||
// (Re)create pixmaps
|
||||
for (int i = 0; i < m_pixmaps.size(); ++i) {
|
||||
|
||||
delete m_pixmaps[i];
|
||||
m_pixmaps[i] = 0;
|
||||
m_pixmaps[i] = new QPixmap(m_pixmapSize);
|
||||
}
|
||||
|
||||
// Update tile pixmap pointers, and mark for repainting
|
||||
for (int i = 0; i < m_tiles.count(); ++i) {
|
||||
|
||||
m_tiles[i].pixmap = m_pixmaps[i];
|
||||
m_tiles[i].painted = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Waveform::setWindowPosition(qint64 position)
|
||||
{
|
||||
WAVEFORM_DEBUG << "setWindowPosition"
|
||||
<< "old" << m_windowPosition << "new" << position
|
||||
<< "tileArrayStart" << m_tileArrayStart;
|
||||
|
||||
const qint64 oldPosition = m_windowPosition;
|
||||
m_windowPosition = position;
|
||||
|
||||
if((m_windowPosition >= oldPosition) &&
|
||||
(m_windowPosition - m_tileArrayStart < (m_tiles.count() * m_tileLength))) {
|
||||
// Work out how many tiles need to be shuffled
|
||||
const qint64 offset = m_windowPosition - m_tileArrayStart;
|
||||
const int nTiles = offset / m_tileLength;
|
||||
shuffleTiles(nTiles);
|
||||
} else {
|
||||
resetTiles(m_windowPosition);
|
||||
}
|
||||
|
||||
if(!paintTiles() && m_windowPosition != oldPosition)
|
||||
emit waveformImageChanged(true);
|
||||
// update();
|
||||
}
|
||||
|
||||
qint64 Waveform::tilePosition(int index) const {
|
||||
|
||||
return m_tileArrayStart + index * m_tileLength;
|
||||
}
|
||||
|
||||
Waveform::TilePoint Waveform::tilePoint(qint64 position) const {
|
||||
|
||||
TilePoint result;
|
||||
|
||||
if (position >= m_tileArrayStart) {
|
||||
|
||||
const qint64 tileArrayEnd = m_tileArrayStart + m_tiles.count() * m_tileLength;
|
||||
|
||||
if (position < tileArrayEnd) {
|
||||
|
||||
const qint64 offsetIntoTileArray = position - m_tileArrayStart;
|
||||
result.index = offsetIntoTileArray / m_tileLength;
|
||||
Q_ASSERT(result.index >= 0 && result.index <= m_tiles.count());
|
||||
result.positionOffset = offsetIntoTileArray % m_tileLength;
|
||||
result.pixelOffset = tilePixelOffset(result.positionOffset);
|
||||
Q_ASSERT(result.pixelOffset >= 0 && result.pixelOffset <= m_pixmapSize.width());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int Waveform::tilePixelOffset(qint64 positionOffset) const {
|
||||
|
||||
Q_ASSERT(positionOffset >= 0 && positionOffset <= m_tileLength);
|
||||
const int result = (qreal(positionOffset) / m_tileLength) * m_pixmapSize.width();
|
||||
return result;
|
||||
}
|
||||
|
||||
int Waveform::windowPixelOffset(qint64 positionOffset, const QRect &rect) const {
|
||||
|
||||
Q_ASSERT(positionOffset >= 0 && positionOffset <= m_windowLength);
|
||||
|
||||
const int result = (qreal(positionOffset) / m_windowLength) * rect.width();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Waveform::paintTiles() {
|
||||
|
||||
WAVEFORM_DEBUG << "paintTiles";
|
||||
bool updateRequired = false;
|
||||
|
||||
for (int i = 0; i < m_tiles.count(); ++i) {
|
||||
//for (int i = 0; i < 1; ++i) {
|
||||
|
||||
const Tile &tile = m_tiles[i];
|
||||
|
||||
if (!tile.painted) {
|
||||
|
||||
const qint64 tileStart = m_tileArrayStart + i * m_tileLength;
|
||||
const qint64 tileEnd = tileStart + m_tileLength;
|
||||
|
||||
if (m_bufferPosition <= tileStart && m_bufferPosition + m_bufferLength >= tileEnd) {
|
||||
|
||||
paintTile(i);
|
||||
updateRequired = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updateRequired)
|
||||
emit waveformImageChanged(true);
|
||||
|
||||
return updateRequired;
|
||||
}
|
||||
|
||||
void Waveform::paintTile(int index) {
|
||||
|
||||
const qint64 tileStart = m_tileArrayStart + index * m_tileLength;
|
||||
|
||||
WAVEFORM_DEBUG << "paintTile"
|
||||
<< "index" << index
|
||||
<< "bufferPosition" << m_bufferPosition
|
||||
<< "bufferLength" << m_bufferLength
|
||||
<< "start" << tileStart
|
||||
<< "end" << tileStart + m_tileLength;
|
||||
|
||||
Q_ASSERT(m_bufferPosition <= tileStart);
|
||||
Q_ASSERT(m_bufferPosition + m_bufferLength >= tileStart + m_tileLength);
|
||||
|
||||
Tile &tile = m_tiles[index];
|
||||
Q_ASSERT(!tile.painted);
|
||||
|
||||
const qint16* base = reinterpret_cast<const qint16*>(m_buffer.constData());
|
||||
const qint16* buffer = base + ((tileStart - m_bufferPosition) / 2);
|
||||
const int numSamples = m_tileLength / (2 * m_format.channelCount());
|
||||
|
||||
QPainter painter(tile.pixmap);
|
||||
|
||||
painter.fillRect(tile.pixmap->rect(), Qt::black);
|
||||
//painter.fillRect(tile.pixmap->rect(), QColor(60, 60, 60));
|
||||
|
||||
//QPen pen(Qt::white);
|
||||
QPen pen(QColor(85, 210, 250));
|
||||
painter.setPen(pen);
|
||||
|
||||
// Calculate initial PCM value
|
||||
qint16 previousPcmValue = 0;
|
||||
if (buffer > base)
|
||||
previousPcmValue = *(buffer - m_format.channelCount());
|
||||
|
||||
// Calculate initial point
|
||||
const qreal previousRealValue = pcmToReal(previousPcmValue);
|
||||
const int originY = ((previousRealValue + 1.0) / 2) * m_pixmapSize.height();
|
||||
const QPoint origin(0, originY);
|
||||
|
||||
QLine line(origin, origin);
|
||||
|
||||
for (int i = 0; i < numSamples; ++i) {
|
||||
|
||||
const qint16* ptr = buffer + i * m_format.channelCount();
|
||||
|
||||
Q_ASSERT((reinterpret_cast<const char*>(ptr) - m_buffer.constData()) >= 0);
|
||||
Q_ASSERT((reinterpret_cast<const char*>(ptr) - m_buffer.constData()) < m_bufferLength);
|
||||
|
||||
const qint16 pcmValue = *ptr;
|
||||
const qreal realValue = pcmToReal(pcmValue);
|
||||
|
||||
const int x = tilePixelOffset(i * 2 * m_format.channelCount());
|
||||
const int y = ((realValue + 1.0) / 2) * m_pixmapSize.height();
|
||||
|
||||
line.setP2(QPoint(x, y));
|
||||
painter.drawLine(line);
|
||||
line.setP1(line.p2());
|
||||
}
|
||||
|
||||
tile.painted = true;
|
||||
}
|
||||
|
||||
void Waveform::shuffleTiles(int n)
|
||||
{
|
||||
WAVEFORM_DEBUG << "shuffleTiles" << "n" << n;
|
||||
|
||||
while (n--) {
|
||||
Tile tile = m_tiles.first();
|
||||
tile.painted = false;
|
||||
m_tiles.erase(m_tiles.begin());
|
||||
m_tiles += tile;
|
||||
m_tileArrayStart += m_tileLength;
|
||||
}
|
||||
|
||||
WAVEFORM_DEBUG << "shuffleTiles" << "tileArrayStart" << m_tileArrayStart;
|
||||
}
|
||||
|
||||
void Waveform::resetTiles(qint64 newStartPos)
|
||||
{
|
||||
WAVEFORM_DEBUG << "resetTiles" << "newStartPos" << newStartPos;
|
||||
|
||||
QVector<Tile>::iterator i = m_tiles.begin();
|
||||
for ( ; i != m_tiles.end(); ++i)
|
||||
i->painted = false;
|
||||
|
||||
m_tileArrayStart = newStartPos;
|
||||
}
|
||||
|
||||
237
Source/src/AudioEngine/cusdr_audio_waveform.h
Normal file
@ -0,0 +1,237 @@
|
||||
/**
|
||||
* @file cusdr_audio_waveform.h
|
||||
* @brief cuSDR waveform graphics header file
|
||||
* @author adaptation for cuSDR by Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-04-02
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _CUSDR_WAVEFORM_H
|
||||
#define _CUSDR_WAVEFORM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QPixmap>
|
||||
#include <QScopedPointer>
|
||||
|
||||
#include "cusdr_settings.h"
|
||||
|
||||
#ifdef LOG_WAVEFORM
|
||||
# define WAVEFORM_DEBUG qDebug().nospace() << "WaveForm::\t"
|
||||
#else
|
||||
# define WAVEFORM_DEBUG nullDebug()
|
||||
#endif
|
||||
|
||||
#ifdef LOG_PAINT_EVENT
|
||||
# define WAVEFORM_PAINT_DEBUG qDebug().nospace() << "WaveFormPaint::\t"
|
||||
#else
|
||||
# define WAVEFORM_PAINT_DEBUG nullDebug()
|
||||
#endif
|
||||
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QByteArray)
|
||||
|
||||
/**
|
||||
* QObject which draws a section of the audio waveform.
|
||||
*
|
||||
* The waveform is rendered on a set of QPixmaps which form a group of tiles
|
||||
* whose extent covers the widget. As the audio position is updated, these
|
||||
* tiles are scrolled from left to right; when the left-most tile scrolls
|
||||
* outside the widget, it is moved to the right end of the tile array and
|
||||
* painted with the next section of the waveform.
|
||||
*/
|
||||
|
||||
class Waveform : public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Waveform(QObject *parent = 0);
|
||||
~Waveform();
|
||||
|
||||
void initialize(
|
||||
const QAudioFormat &format,
|
||||
qint64 audioBufferSize,
|
||||
qint64 windowDurationUs,
|
||||
const QRect &rect);
|
||||
|
||||
void reset();
|
||||
|
||||
void setAutoUpdatePosition(bool enabled);
|
||||
|
||||
public slots:
|
||||
void bufferChanged(QObject *sender, qint64 position, qint64 length, const QByteArray &buffer);
|
||||
void audioPositionChanged(QObject *sender, qint64 position);
|
||||
|
||||
QImage* createWaveformImage(const QRect &rect);
|
||||
|
||||
private:
|
||||
static const int NullIndex = -1;
|
||||
|
||||
void deletePixmaps();
|
||||
|
||||
/*
|
||||
* (Re)create all pixmaps, repaint and update the display.
|
||||
* Triggers an update();
|
||||
*/
|
||||
void createPixmaps(const QSize &newSize);
|
||||
|
||||
/*
|
||||
* Update window position.
|
||||
* Triggers an update().
|
||||
*/
|
||||
void setWindowPosition(qint64 position);
|
||||
|
||||
/*
|
||||
* Base position of tile
|
||||
*/
|
||||
qint64 tilePosition(int index) const;
|
||||
|
||||
/*
|
||||
* Structure which identifies a point within a given
|
||||
* tile.
|
||||
*/
|
||||
struct TilePoint
|
||||
{
|
||||
TilePoint(int idx = 0, qint64 pos = 0, qint64 pix = 0)
|
||||
: index(idx), positionOffset(pos), pixelOffset(pix)
|
||||
{ }
|
||||
|
||||
// Index of tile
|
||||
int index;
|
||||
|
||||
// Number of bytes from start of tile
|
||||
qint64 positionOffset;
|
||||
|
||||
// Number of pixels from left of corresponding pixmap
|
||||
int pixelOffset;
|
||||
};
|
||||
|
||||
/*
|
||||
* Convert position in m_buffer into a tile index and an offset in pixels
|
||||
* into the corresponding pixmap.
|
||||
*
|
||||
* \param position Offset into m_buffer, in bytes
|
||||
|
||||
* If position is outside the tile array, index is NullIndex and
|
||||
* offset is zero.
|
||||
*/
|
||||
TilePoint tilePoint(qint64 position) const;
|
||||
|
||||
/*
|
||||
* Convert offset in bytes into a tile into an offset in pixels
|
||||
* within that tile.
|
||||
*/
|
||||
int tilePixelOffset(qint64 positionOffset) const;
|
||||
|
||||
/*
|
||||
* Convert offset in bytes into the window into an offset in pixels
|
||||
* within the widget rect().
|
||||
*/
|
||||
int windowPixelOffset(qint64 positionOffset, const QRect &rect) const;
|
||||
|
||||
/*
|
||||
* Paint all tiles which can be painted.
|
||||
* \return true iff update() was called
|
||||
*/
|
||||
bool paintTiles();
|
||||
|
||||
/*
|
||||
* Paint the specified tile
|
||||
*
|
||||
* \pre Sufficient data is available to completely paint the tile, i.e.
|
||||
* m_dataLength is greater than the upper bound of the tile.
|
||||
*/
|
||||
void paintTile(int index);
|
||||
|
||||
/*
|
||||
* Move the first n tiles to the end of the array, and mark them as not
|
||||
* painted.
|
||||
*/
|
||||
void shuffleTiles(int n);
|
||||
|
||||
/*
|
||||
* Reset tile array
|
||||
*/
|
||||
void resetTiles(qint64 newStartPos);
|
||||
|
||||
private:
|
||||
Settings* set;
|
||||
|
||||
QRect m_audioRect;
|
||||
qint64 m_bufferPosition;
|
||||
qint64 m_bufferLength;
|
||||
QByteArray m_buffer;
|
||||
|
||||
qint64 m_audioPosition;
|
||||
QAudioFormat m_format;
|
||||
|
||||
bool m_active;
|
||||
|
||||
QSize m_pixmapSize;
|
||||
QVector<QPixmap*> m_pixmaps;
|
||||
|
||||
struct Tile {
|
||||
// Pointer into parent m_pixmaps array
|
||||
QPixmap* pixmap;
|
||||
|
||||
// Flag indicating whether this tile has been painted
|
||||
bool painted;
|
||||
};
|
||||
|
||||
QVector<Tile> m_tiles;
|
||||
|
||||
// Length of audio data in bytes depicted by each tile
|
||||
qint64 m_tileLength;
|
||||
|
||||
// Position in bytes of the first tile, relative to m_buffer
|
||||
qint64 m_tileArrayStart;
|
||||
|
||||
qint64 m_windowPosition;
|
||||
qint64 m_windowLength;
|
||||
int m_waveformDisplayWidth;
|
||||
|
||||
signals:
|
||||
void waveformImageChanged(bool value);
|
||||
};
|
||||
|
||||
#endif // _CUSDR_WAVEFORM_H
|
||||
165
Source/src/AudioEngine/cusdr_audio_wavfile.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
/**
|
||||
* @file cusdr_audio_wavfile.cpp
|
||||
* @brief cuSDR audio wav-file class
|
||||
* @author adaptation for cuSDR by Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-04-02
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
//#define LOG_AUDIO_WAVFILE
|
||||
|
||||
#include <QtCore/qendian.h>
|
||||
#include <QVector>
|
||||
#include <QDebug>
|
||||
#include "cusdr_audio_utils.h"
|
||||
#include "cusdr_audio_wavfile.h"
|
||||
|
||||
struct chunk {
|
||||
|
||||
char id[4];
|
||||
quint32 size;
|
||||
};
|
||||
|
||||
struct RIFFHeader {
|
||||
|
||||
chunk descriptor; // "RIFF"
|
||||
char type[4]; // "WAVE"
|
||||
};
|
||||
|
||||
struct WAVEHeader {
|
||||
|
||||
chunk descriptor;
|
||||
quint16 audioFormat;
|
||||
quint16 numChannels;
|
||||
quint32 sampleRate;
|
||||
quint32 byteRate;
|
||||
quint16 blockAlign;
|
||||
quint16 bitsPerSample;
|
||||
};
|
||||
|
||||
struct DATAHeader {
|
||||
|
||||
chunk descriptor;
|
||||
};
|
||||
|
||||
struct CombinedHeader {
|
||||
|
||||
RIFFHeader riff;
|
||||
WAVEHeader wave;
|
||||
};
|
||||
|
||||
WavFile::WavFile(QObject *parent)
|
||||
: QFile(parent)
|
||||
, m_headerLength(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool WavFile::open(const QString &fileName) {
|
||||
|
||||
close();
|
||||
setFileName(fileName);
|
||||
return QFile::open(QIODevice::ReadOnly) && readHeader();
|
||||
}
|
||||
|
||||
const QAudioFormat &WavFile::fileFormat() const {
|
||||
|
||||
return m_fileFormat;
|
||||
}
|
||||
|
||||
qint64 WavFile::headerLength() const {
|
||||
|
||||
return m_headerLength;
|
||||
}
|
||||
|
||||
bool WavFile::readHeader() {
|
||||
|
||||
seek(0);
|
||||
CombinedHeader header;
|
||||
bool result = read(reinterpret_cast<char *>(&header), sizeof(CombinedHeader)) == sizeof(CombinedHeader);
|
||||
|
||||
AUDIO_WAVFILE_DEBUG << "header.id" << header.riff.descriptor.id;
|
||||
AUDIO_WAVFILE_DEBUG << "header.type" << header.riff.type;
|
||||
AUDIO_WAVFILE_DEBUG << "header.descriptor.id" << header.wave.descriptor.id;
|
||||
AUDIO_WAVFILE_DEBUG << "header.audioFormat" << header.wave.audioFormat;
|
||||
|
||||
if (result) {
|
||||
if ((memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0
|
||||
|| memcmp(&header.riff.descriptor.id, "RIFX", 4) == 0)
|
||||
&& memcmp(&header.riff.type, "WAVE", 4) == 0
|
||||
&& memcmp(&header.wave.descriptor.id, "fmt ", 4) == 0
|
||||
&& (header.wave.audioFormat == 1 || header.wave.audioFormat == 0 || header.wave.audioFormat == 3)) {
|
||||
|
||||
// Read off remaining header information
|
||||
DATAHeader dataHeader;
|
||||
|
||||
if (qFromLittleEndian<quint32>(header.wave.descriptor.size) > sizeof(WAVEHeader)) {
|
||||
// Extended data available
|
||||
quint16 extraFormatBytes;
|
||||
if (peek((char*)&extraFormatBytes, sizeof(quint16)) != sizeof(quint16))
|
||||
return false;
|
||||
const qint64 throwAwayBytes = sizeof(quint16) + qFromLittleEndian<quint16>(extraFormatBytes);
|
||||
if (read(throwAwayBytes).size() != throwAwayBytes)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (read((char*)&dataHeader, sizeof(DATAHeader)) != sizeof(DATAHeader))
|
||||
return false;
|
||||
|
||||
// Establish format
|
||||
if (memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0)
|
||||
m_fileFormat.setByteOrder(QAudioFormat::LittleEndian);
|
||||
else
|
||||
m_fileFormat.setByteOrder(QAudioFormat::BigEndian);
|
||||
|
||||
int bps = qFromLittleEndian<quint16>(header.wave.bitsPerSample);
|
||||
m_fileFormat.setChannelCount(qFromLittleEndian<quint16>(header.wave.numChannels));
|
||||
m_fileFormat.setCodec("audio/pcm");
|
||||
m_fileFormat.setSampleRate(qFromLittleEndian<quint32>(header.wave.sampleRate));
|
||||
m_fileFormat.setSampleSize(qFromLittleEndian<quint16>(header.wave.bitsPerSample));
|
||||
m_fileFormat.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt);
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
m_headerLength = pos();
|
||||
return result;
|
||||
}
|
||||
83
Source/src/AudioEngine/cusdr_audio_wavfile.h
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* @file cusdr_audio_wavfile.h
|
||||
* @brief cuSDR audio wav file header file
|
||||
* @author adaptation for cuSDR by Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-04-02
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef _CUSDR_AUDIO_WAVFILE_H
|
||||
#define _CUSDR_AUDIO_WAVFILE_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qfile.h>
|
||||
#include "cusdr_settings.h"
|
||||
|
||||
#ifdef LOG_AUDIO_WAVFILE
|
||||
# define AUDIO_WAVFILE_DEBUG qDebug().nospace() << "AudioWavFile::\t"
|
||||
#else
|
||||
# define AUDIO_WAVFILE_DEBUG nullDebug()
|
||||
#endif
|
||||
|
||||
|
||||
class WavFile : public QFile
|
||||
{
|
||||
public:
|
||||
WavFile(QObject *parent = 0);
|
||||
|
||||
bool open(const QString &fileName);
|
||||
const QAudioFormat &fileFormat() const;
|
||||
qint64 headerLength() const;
|
||||
|
||||
private:
|
||||
bool readHeader();
|
||||
|
||||
private:
|
||||
QAudioFormat m_fileFormat;
|
||||
qint64 m_headerLength;
|
||||
|
||||
};
|
||||
|
||||
#endif // _CUSDR_AUDIO_WAVFILE_H
|
||||
|
||||
94
Source/src/AudioEngine/cusdr_fspectrum.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* @file cusdr_fspectrum.cpp
|
||||
* @brief audio frequency spectrum class for cuSDR
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "cusdr_fspectrum.h"
|
||||
|
||||
FrequencySpectrum::FrequencySpectrum(int numPoints)
|
||||
: m_elements(numPoints)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FrequencySpectrum::reset() {
|
||||
|
||||
iterator i = begin();
|
||||
for ( ; i != end(); ++i)
|
||||
*i = Element();
|
||||
}
|
||||
|
||||
int FrequencySpectrum::count() const {
|
||||
|
||||
return m_elements.count();
|
||||
}
|
||||
|
||||
FrequencySpectrum::Element& FrequencySpectrum::operator[](int index) {
|
||||
|
||||
return m_elements[index];
|
||||
}
|
||||
|
||||
const FrequencySpectrum::Element& FrequencySpectrum::operator[](int index) const {
|
||||
|
||||
return m_elements[index];
|
||||
}
|
||||
|
||||
FrequencySpectrum::iterator FrequencySpectrum::begin() {
|
||||
|
||||
return m_elements.begin();
|
||||
}
|
||||
|
||||
FrequencySpectrum::iterator FrequencySpectrum::end() {
|
||||
|
||||
return m_elements.end();
|
||||
}
|
||||
|
||||
FrequencySpectrum::const_iterator FrequencySpectrum::begin() const {
|
||||
|
||||
return m_elements.begin();
|
||||
}
|
||||
|
||||
FrequencySpectrum::const_iterator FrequencySpectrum::end() const {
|
||||
|
||||
return m_elements.end();
|
||||
}
|
||||
103
Source/src/AudioEngine/cusdr_fspectrum.h
Normal file
@ -0,0 +1,103 @@
|
||||
/**
|
||||
* @file cusdr_fspectrum.h
|
||||
* @brief audio frequency spectrum header file for cuSDR
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef FREQUENCYSPECTRUM_H
|
||||
#define FREQUENCYSPECTRUM_H
|
||||
|
||||
#include <QtCore/QVector>
|
||||
|
||||
/**
|
||||
* Represents a frequency spectrum as a series of elements, each of which
|
||||
* consists of a frequency, an amplitude and a phase.
|
||||
*/
|
||||
class FrequencySpectrum {
|
||||
public:
|
||||
FrequencySpectrum(int numPoints = 0);
|
||||
|
||||
struct Element {
|
||||
Element()
|
||||
: frequency(0.0), amplitude(0.0), phase(0.0), clipped(false)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Frequency in Hertz
|
||||
*/
|
||||
qreal frequency;
|
||||
|
||||
/**
|
||||
* Amplitude in range [0.0, 1.0]
|
||||
*/
|
||||
qreal amplitude;
|
||||
|
||||
/**
|
||||
* Phase in range [0.0, 2*PI]
|
||||
*/
|
||||
qreal phase;
|
||||
|
||||
/**
|
||||
* Indicates whether value has been clipped during spectrum analysis
|
||||
*/
|
||||
bool clipped;
|
||||
};
|
||||
|
||||
typedef QVector<Element>::iterator iterator;
|
||||
typedef QVector<Element>::const_iterator const_iterator;
|
||||
|
||||
void reset();
|
||||
|
||||
int count() const;
|
||||
Element& operator[](int index);
|
||||
const Element& operator[](int index) const;
|
||||
iterator begin();
|
||||
iterator end();
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
private:
|
||||
QVector<Element> m_elements;
|
||||
|
||||
};
|
||||
|
||||
#endif // FREQUENCYSPECTRUM_H
|
||||
167
Source/src/CL/qclbuffer.h
Normal file
@ -0,0 +1,167 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLBUFFER_H
|
||||
#define QCLBUFFER_H
|
||||
|
||||
#include "qclmemoryobject.h"
|
||||
#include "qclevent.h"
|
||||
#include <QtCore/qrect.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLImage2D;
|
||||
class QCLImage3D;
|
||||
|
||||
class Q_CL_EXPORT QCLBuffer : public QCLMemoryObject
|
||||
{
|
||||
public:
|
||||
QCLBuffer() {}
|
||||
QCLBuffer(QCLContext *context, cl_mem id)
|
||||
: QCLMemoryObject(context, id) {}
|
||||
QCLBuffer(const QCLBuffer &other)
|
||||
: QCLMemoryObject() { setId(other.context(), other.memoryId()); }
|
||||
|
||||
QCLBuffer &operator=(const QCLBuffer &other)
|
||||
{
|
||||
setId(other.context(), other.memoryId());
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool read(void *data, size_t size);
|
||||
bool read(size_t offset, void *data, size_t size);
|
||||
QCLEvent readAsync(size_t offset, void *data, size_t size,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
|
||||
bool readRect(const QRect &rect, void *data,
|
||||
size_t bufferBytesPerLine, size_t hostBytesPerLine);
|
||||
bool readRect(const size_t origin[3], const size_t size[3], void *data,
|
||||
size_t bufferBytesPerLine, size_t bufferBytesPerSlice,
|
||||
size_t hostBytesPerLine, size_t hostBytesPerSlice);
|
||||
QCLEvent readRectAsync
|
||||
(const QRect &rect, void *data,
|
||||
size_t bufferBytesPerLine, size_t hostBytesPerLine,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
QCLEvent readRectAsync
|
||||
(const size_t origin[3], const size_t size[3], void *data,
|
||||
size_t bufferBytesPerLine, size_t bufferBytesPerSlice,
|
||||
size_t hostBytesPerLine, size_t hostBytesPerSlice,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
|
||||
bool write(const void *data, size_t size);
|
||||
bool write(size_t offset, const void *data, size_t size);
|
||||
QCLEvent writeAsync(size_t offset, const void *data, size_t size,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
|
||||
bool writeRect(const QRect &rect, const void *data,
|
||||
size_t bufferBytesPerLine, size_t hostBytesPerLine);
|
||||
bool writeRect(const size_t origin[3], const size_t size[3],
|
||||
const void *data, size_t bufferBytesPerLine,
|
||||
size_t bufferBytesPerSlice, size_t hostBytesPerLine,
|
||||
size_t hostBytesPerSlice);
|
||||
QCLEvent writeRectAsync
|
||||
(const QRect &rect, const void *data,
|
||||
size_t bufferBytesPerLine, size_t hostBytesPerLine,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
QCLEvent writeRectAsync
|
||||
(const size_t origin[3], const size_t size[3], const void *data,
|
||||
size_t bufferBytesPerLine, size_t bufferBytesPerSlice,
|
||||
size_t hostBytesPerLine, size_t hostBytesPerSlice,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
|
||||
bool copyTo(size_t offset, size_t size,
|
||||
const QCLBuffer &dest, size_t destOffset);
|
||||
bool copyTo(size_t offset, const QCLImage2D &dest, const QRect &rect);
|
||||
bool copyTo(size_t offset, const QCLImage3D &dest,
|
||||
const size_t origin[3], const size_t size[3]);
|
||||
|
||||
QCLEvent copyToAsync
|
||||
(size_t offset, size_t size,
|
||||
const QCLBuffer &dest, size_t destOffset,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
QCLEvent copyToAsync
|
||||
(size_t offset, const QCLImage2D &dest, const QRect &rect,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
QCLEvent copyToAsync
|
||||
(size_t offset, const QCLImage3D &dest,
|
||||
const size_t origin[3], const size_t size[3],
|
||||
const QCLEventList &after = QCLEventList());
|
||||
|
||||
bool copyToRect(const QRect &rect, const QCLBuffer &dest,
|
||||
const QPoint &destPoint, size_t bufferBytesPerLine,
|
||||
size_t destBytesPerLine);
|
||||
bool copyToRect(const size_t origin[3], const size_t size[3],
|
||||
const QCLBuffer &dest, const size_t destOrigin[3],
|
||||
size_t bufferBytesPerLine, size_t bufferBytesPerSlice,
|
||||
size_t destBytesPerLine, size_t destBytesPerSlice);
|
||||
QCLEvent copyToRectAsync
|
||||
(const QRect &rect, const QCLBuffer &dest, const QPoint &destPoint,
|
||||
size_t bufferBytesPerLine, size_t destBytesPerLine,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
QCLEvent copyToRectAsync
|
||||
(const size_t origin[3], const size_t size[3],
|
||||
const QCLBuffer &dest, const size_t destOrigin[3],
|
||||
size_t bufferBytesPerLine, size_t bufferBytesPerSlice,
|
||||
size_t destBytesPerLine, size_t destBytesPerSlice,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
|
||||
void *map(size_t offset, size_t size, QCLMemoryObject::Access access);
|
||||
void *map(QCLMemoryObject::Access access);
|
||||
QCLEvent mapAsync(void **ptr, size_t offset, size_t size,
|
||||
QCLMemoryObject::Access access,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
|
||||
QCLBuffer createSubBuffer
|
||||
(size_t offset, size_t size, QCLMemoryObject::Access access);
|
||||
|
||||
QCLBuffer parentBuffer() const;
|
||||
size_t offset() const;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
120
Source/src/CL/qclcommandqueue.h
Normal file
@ -0,0 +1,120 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLCOMMANDQUEUE_H
|
||||
#define QCLCOMMANDQUEUE_H
|
||||
|
||||
#include "qclglobal.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLContext;
|
||||
|
||||
class Q_CL_EXPORT QCLCommandQueue
|
||||
{
|
||||
public:
|
||||
QCLCommandQueue() : m_id(0) {}
|
||||
QCLCommandQueue(QCLContext *context, cl_command_queue id)
|
||||
: m_context(context), m_id(id) {}
|
||||
QCLCommandQueue(const QCLCommandQueue &other);
|
||||
~QCLCommandQueue();
|
||||
|
||||
QCLCommandQueue &operator=(const QCLCommandQueue &other);
|
||||
|
||||
bool isNull() const { return m_id == 0; }
|
||||
|
||||
bool isOutOfOrder() const;
|
||||
bool isProfilingEnabled() const;
|
||||
|
||||
cl_command_queue queueId() const { return m_id; }
|
||||
QCLContext *context() const { return m_context; }
|
||||
|
||||
bool operator==(const QCLCommandQueue &other) const;
|
||||
bool operator!=(const QCLCommandQueue &other) const;
|
||||
|
||||
private:
|
||||
QCLContext *m_context;
|
||||
cl_command_queue m_id;
|
||||
};
|
||||
|
||||
inline QCLCommandQueue::QCLCommandQueue(const QCLCommandQueue &other)
|
||||
: m_context(other.m_context), m_id(other.m_id)
|
||||
{
|
||||
if (m_id)
|
||||
clRetainCommandQueue(m_id);
|
||||
}
|
||||
|
||||
inline QCLCommandQueue::~QCLCommandQueue()
|
||||
{
|
||||
if (m_id)
|
||||
clReleaseCommandQueue(m_id);
|
||||
}
|
||||
|
||||
inline QCLCommandQueue &QCLCommandQueue::operator=(const QCLCommandQueue &other)
|
||||
{
|
||||
m_context = other.m_context;
|
||||
if (other.m_id)
|
||||
clRetainCommandQueue(other.m_id);
|
||||
if (m_id)
|
||||
clReleaseCommandQueue(m_id);
|
||||
m_id = other.m_id;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool QCLCommandQueue::operator==(const QCLCommandQueue &other) const
|
||||
{
|
||||
return m_id == other.m_id;
|
||||
}
|
||||
|
||||
inline bool QCLCommandQueue::operator!=(const QCLCommandQueue &other) const
|
||||
{
|
||||
return m_id != other.m_id;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
202
Source/src/CL/qclcontext.h
Normal file
@ -0,0 +1,202 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLCONTEXT_H
|
||||
#define QCLCONTEXT_H
|
||||
|
||||
#include "qcldevice.h"
|
||||
#include "qclcommandqueue.h"
|
||||
#include "qclbuffer.h"
|
||||
#include "qclvector.h"
|
||||
#include "qclimage.h"
|
||||
#include "qclsampler.h"
|
||||
#include "qclprogram.h"
|
||||
#include "qcluserevent.h"
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
#include <QtCore/qsize.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLContextPrivate;
|
||||
class QCLKernel;
|
||||
class QCLVectorBase;
|
||||
|
||||
class Q_CL_EXPORT QCLContext
|
||||
{
|
||||
public:
|
||||
QCLContext();
|
||||
virtual ~QCLContext();
|
||||
|
||||
bool isCreated() const;
|
||||
|
||||
bool create(QCLDevice::DeviceTypes type = QCLDevice::Default);
|
||||
bool create(const QList<QCLDevice> &devices);
|
||||
virtual void release();
|
||||
|
||||
cl_context contextId() const;
|
||||
void setContextId(cl_context id);
|
||||
|
||||
QList<QCLDevice> devices() const;
|
||||
QCLDevice defaultDevice() const;
|
||||
|
||||
cl_int lastError() const;
|
||||
void setLastError(cl_int error);
|
||||
|
||||
static QString errorName(cl_int code);
|
||||
|
||||
QCLCommandQueue commandQueue();
|
||||
void setCommandQueue(const QCLCommandQueue &queue);
|
||||
|
||||
QCLCommandQueue defaultCommandQueue();
|
||||
QCLCommandQueue createCommandQueue
|
||||
(cl_command_queue_properties properties,
|
||||
const QCLDevice &device = QCLDevice());
|
||||
|
||||
QCLBuffer createBufferDevice
|
||||
(size_t size, QCLMemoryObject::Access access);
|
||||
QCLBuffer createBufferHost
|
||||
(void *data, size_t size, QCLMemoryObject::Access access);
|
||||
QCLBuffer createBufferCopy
|
||||
(const void *data, size_t size, QCLMemoryObject::Access access);
|
||||
|
||||
template <typename T>
|
||||
QCLVector<T> createVector(int size, QCLMemoryObject::Access access = QCLMemoryObject::ReadWrite);
|
||||
|
||||
QCLImage2D createImage2DDevice
|
||||
(const QCLImageFormat &format, const QSize &size, QCLMemoryObject::Access access);
|
||||
QCLImage2D createImage2DHost
|
||||
(const QCLImageFormat &format, void *data, const QSize &size,
|
||||
QCLMemoryObject::Access access, int bytesPerLine = 0);
|
||||
QCLImage2D createImage2DHost(QImage *image, QCLMemoryObject::Access access);
|
||||
QCLImage2D createImage2DCopy
|
||||
(const QCLImageFormat &format, const void *data, const QSize &size,
|
||||
QCLMemoryObject::Access access, int bytesPerLine = 0);
|
||||
QCLImage2D createImage2DCopy
|
||||
(const QImage &image, QCLMemoryObject::Access access);
|
||||
|
||||
QCLImage3D createImage3DDevice
|
||||
(const QCLImageFormat &format, int width, int height, int depth,
|
||||
QCLMemoryObject::Access access);
|
||||
QCLImage3D createImage3DHost
|
||||
(const QCLImageFormat &format, void *data,
|
||||
int width, int height, int depth, QCLMemoryObject::Access access,
|
||||
int bytesPerLine = 0, int bytesPerSlice = 0);
|
||||
QCLImage3D createImage3DCopy
|
||||
(const QCLImageFormat &format, const void *data,
|
||||
int width, int height, int depth, QCLMemoryObject::Access access,
|
||||
int bytesPerLine = 0, int bytesPerSlice = 0);
|
||||
|
||||
QCLProgram createProgramFromSourceCode(const QByteArray &sourceCode);
|
||||
QCLProgram createProgramFromSourceFile(const QString &fileName);
|
||||
QCLProgram createProgramFromBinaryCode(const QByteArray &binary);
|
||||
QCLProgram createProgramFromBinaryFile(const QString &fileName);
|
||||
QCLProgram createProgramFromBinaries
|
||||
(const QList<QCLDevice> &devices, const QList<QByteArray> &binaries);
|
||||
|
||||
QCLProgram buildProgramFromSourceCode(const QByteArray &sourceCode);
|
||||
QCLProgram buildProgramFromSourceFile(const QString &fileName);
|
||||
QCLProgram buildProgramFromBinaryCode(const QByteArray &binary);
|
||||
QCLProgram buildProgramFromBinaryFile(const QString &fileName);
|
||||
QCLProgram buildProgramFromBinaries
|
||||
(const QList<QCLDevice> &devices, const QList<QByteArray> &binaries);
|
||||
|
||||
QList<QCLImageFormat> supportedImage2DFormats(cl_mem_flags flags) const;
|
||||
QList<QCLImageFormat> supportedImage3DFormats(cl_mem_flags flags) const;
|
||||
|
||||
QCLSampler createSampler
|
||||
(bool normalizedCoordinates, QCLSampler::AddressingMode addressingMode,
|
||||
QCLSampler::FilterMode filterMode);
|
||||
|
||||
QCLUserEvent createUserEvent();
|
||||
|
||||
void flush();
|
||||
void finish();
|
||||
|
||||
QCLEvent marker();
|
||||
|
||||
void sync();
|
||||
|
||||
void barrier();
|
||||
void barrier(const QCLEventList &events);
|
||||
|
||||
protected:
|
||||
void setDefaultDevice(const QCLDevice &device);
|
||||
|
||||
private:
|
||||
QScopedPointer<QCLContextPrivate> d_ptr;
|
||||
|
||||
Q_DISABLE_COPY(QCLContext)
|
||||
Q_DECLARE_PRIVATE(QCLContext)
|
||||
|
||||
cl_command_queue activeQueue(); // For quicker access from friends.
|
||||
|
||||
friend class QCLMemoryObject;
|
||||
friend class QCLBuffer;
|
||||
friend class QCLImage2D;
|
||||
friend class QCLImage3D;
|
||||
friend class QCLKernel;
|
||||
friend class QCLCommandQueue;
|
||||
friend class QCLProgram;
|
||||
friend class QCLVectorBase;
|
||||
friend class QCLSampler;
|
||||
|
||||
void reportError(const char *name, cl_int error);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE QCLVector<T> QCLContext::createVector
|
||||
(int size, QCLMemoryObject::Access access)
|
||||
{
|
||||
Q_ASSERT(size >= 1);
|
||||
return QCLVector<T>(this, size, access);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
208
Source/src/CL/qcldevice.h
Normal file
@ -0,0 +1,208 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLDEVICE_H
|
||||
#define QCLDEVICE_H
|
||||
|
||||
#include "qclplatform.h"
|
||||
#include "qclworksize.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class Q_CL_EXPORT QCLDevice
|
||||
{
|
||||
public:
|
||||
QCLDevice() : m_id(0), m_flags(0) {}
|
||||
QCLDevice(cl_device_id id) : m_id(id), m_flags(0) {}
|
||||
|
||||
enum DeviceType
|
||||
{
|
||||
Default = 0x00000001,
|
||||
CPU = 0x00000002,
|
||||
GPU = 0x00000004,
|
||||
Accelerator = 0x00000008,
|
||||
All = 0xFFFFFFFF
|
||||
};
|
||||
Q_DECLARE_FLAGS(DeviceTypes, DeviceType)
|
||||
|
||||
bool isNull() const { return m_id == 0; }
|
||||
|
||||
QCLDevice::DeviceTypes deviceType() const;
|
||||
QCLPlatform platform() const;
|
||||
uint vendorId() const;
|
||||
bool isAvailable() const;
|
||||
|
||||
bool hasCompiler() const;
|
||||
bool hasNativeKernels() const;
|
||||
bool hasOutOfOrderExecution() const;
|
||||
bool hasDouble() const;
|
||||
bool hasHalfFloat() const;
|
||||
bool hasErrorCorrectingMemory() const;
|
||||
bool hasUnifiedMemory() const;
|
||||
|
||||
int computeUnits() const;
|
||||
int clockFrequency() const;
|
||||
int addressBits() const;
|
||||
QSysInfo::Endian byteOrder() const;
|
||||
|
||||
QCLWorkSize maximumWorkItemSize() const;
|
||||
size_t maximumWorkItemsPerGroup() const;
|
||||
|
||||
bool hasImage2D() const;
|
||||
bool hasImage3D() const;
|
||||
bool hasWritableImage3D() const;
|
||||
QSize maximumImage2DSize() const;
|
||||
QCLWorkSize maximumImage3DSize() const;
|
||||
int maximumSamplers() const;
|
||||
int maximumReadImages() const;
|
||||
int maximumWriteImages() const;
|
||||
|
||||
int preferredCharVectorSize() const;
|
||||
int preferredShortVectorSize() const;
|
||||
int preferredIntVectorSize() const;
|
||||
int preferredLongVectorSize() const;
|
||||
int preferredFloatVectorSize() const;
|
||||
int preferredDoubleVectorSize() const;
|
||||
int preferredHalfFloatVectorSize() const;
|
||||
|
||||
int nativeCharVectorSize() const;
|
||||
int nativeShortVectorSize() const;
|
||||
int nativeIntVectorSize() const;
|
||||
int nativeLongVectorSize() const;
|
||||
int nativeFloatVectorSize() const;
|
||||
int nativeDoubleVectorSize() const;
|
||||
int nativeHalfFloatVectorSize() const;
|
||||
|
||||
enum FloatCapability
|
||||
{
|
||||
NotSupported = 0x0000,
|
||||
Denorm = 0x0001,
|
||||
InfinityNaN = 0x0002,
|
||||
RoundNearest = 0x0004,
|
||||
RoundZero = 0x0008,
|
||||
RoundInfinity = 0x0010,
|
||||
FusedMultiplyAdd = 0x0020
|
||||
};
|
||||
Q_DECLARE_FLAGS(FloatCapabilities, FloatCapability)
|
||||
|
||||
QCLDevice::FloatCapabilities floatCapabilities() const;
|
||||
QCLDevice::FloatCapabilities doubleCapabilities() const;
|
||||
QCLDevice::FloatCapabilities halfFloatCapabilities() const;
|
||||
|
||||
quint64 profilingTimerResolution() const;
|
||||
|
||||
enum CacheType
|
||||
{
|
||||
NoCache = 0,
|
||||
ReadOnlyCache = 1,
|
||||
ReadWriteCache = 2
|
||||
};
|
||||
|
||||
quint64 maximumAllocationSize() const;
|
||||
quint64 globalMemorySize() const;
|
||||
QCLDevice::CacheType globalMemoryCacheType() const;
|
||||
quint64 globalMemoryCacheSize() const;
|
||||
int globalMemoryCacheLineSize() const;
|
||||
quint64 localMemorySize() const;
|
||||
bool isLocalMemorySeparate() const;
|
||||
quint64 maximumConstantBufferSize() const;
|
||||
int maximumConstantArguments() const;
|
||||
|
||||
int defaultAlignment() const;
|
||||
int minimumAlignment() const;
|
||||
int maximumParameterBytes() const;
|
||||
|
||||
bool isFullProfile() const;
|
||||
bool isEmbeddedProfile() const;
|
||||
|
||||
QString profile() const;
|
||||
QString version() const;
|
||||
QString driverVersion() const;
|
||||
QString name() const;
|
||||
QString vendor() const;
|
||||
QStringList extensions() const;
|
||||
QString languageVersion() const;
|
||||
|
||||
bool hasExtension(const char *name) const;
|
||||
|
||||
QCLPlatform::VersionFlags versionFlags() const;
|
||||
|
||||
cl_device_id deviceId() const { return m_id; }
|
||||
|
||||
static QList<QCLDevice> allDevices();
|
||||
static QList<QCLDevice> devices
|
||||
(QCLDevice::DeviceTypes types,
|
||||
const QCLPlatform &platform = QCLPlatform());
|
||||
|
||||
bool operator==(const QCLDevice &other) const;
|
||||
bool operator!=(const QCLDevice &other) const;
|
||||
|
||||
private:
|
||||
cl_device_id m_id;
|
||||
mutable int m_flags;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QCLDevice::DeviceTypes)
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QCLDevice::FloatCapabilities)
|
||||
|
||||
inline bool QCLDevice::operator==(const QCLDevice &other) const
|
||||
{
|
||||
return m_id == other.m_id;
|
||||
}
|
||||
|
||||
inline bool QCLDevice::operator!=(const QCLDevice &other) const
|
||||
{
|
||||
return m_id != other.m_id;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
Q_CL_EXPORT QDebug operator<<(QDebug, const QCLDevice &);
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
230
Source/src/CL/qclevent.h
Normal file
@ -0,0 +1,230 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLEVENT_H
|
||||
#define QCLEVENT_H
|
||||
|
||||
#include "qclglobal.h"
|
||||
#include <QtCore/qvector.h>
|
||||
#include <QtCore/qfuture.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLUserEvent;
|
||||
|
||||
class Q_CL_EXPORT QCLEvent
|
||||
{
|
||||
public:
|
||||
QCLEvent() : m_id(0) {}
|
||||
QCLEvent(cl_event id) : m_id(id) {}
|
||||
QCLEvent(const QCLEvent &other);
|
||||
~QCLEvent();
|
||||
|
||||
QCLEvent &operator=(const QCLEvent &other);
|
||||
|
||||
bool isNull() const { return m_id == 0; }
|
||||
|
||||
cl_event eventId() const { return m_id; }
|
||||
|
||||
bool isQueued() const { return status() == CL_QUEUED; }
|
||||
bool isSubmitted() const { return status() == CL_SUBMITTED; }
|
||||
bool isRunning() const { return status() == CL_RUNNING; }
|
||||
bool isFinished() const { return status() == CL_COMPLETE; }
|
||||
bool isErrored() const { return status() < 0; }
|
||||
|
||||
cl_int status() const;
|
||||
cl_command_type commandType() const;
|
||||
|
||||
void waitForFinished();
|
||||
|
||||
quint64 queueTime() const;
|
||||
quint64 submitTime() const;
|
||||
quint64 runTime() const;
|
||||
quint64 finishTime() const;
|
||||
|
||||
bool operator==(const QCLEvent &other) const;
|
||||
bool operator!=(const QCLEvent &other) const;
|
||||
|
||||
#if !defined(QT_NO_CONCURRENT)
|
||||
QFuture<void> toFuture() const;
|
||||
operator QFuture<void>() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
cl_event m_id;
|
||||
|
||||
friend class QCLUserEvent;
|
||||
};
|
||||
|
||||
inline QCLEvent::QCLEvent(const QCLEvent &other)
|
||||
: m_id(other.m_id)
|
||||
{
|
||||
if (m_id)
|
||||
clRetainEvent(m_id);
|
||||
}
|
||||
|
||||
inline QCLEvent::~QCLEvent()
|
||||
{
|
||||
if (m_id)
|
||||
clReleaseEvent(m_id);
|
||||
}
|
||||
|
||||
inline QCLEvent &QCLEvent::operator=(const QCLEvent &other)
|
||||
{
|
||||
if (other.m_id)
|
||||
clRetainEvent(other.m_id);
|
||||
if (m_id)
|
||||
clReleaseEvent(m_id);
|
||||
m_id = other.m_id;
|
||||
return *this;
|
||||
}
|
||||
|
||||
class Q_CL_EXPORT QCLEventList
|
||||
{
|
||||
public:
|
||||
QCLEventList() {}
|
||||
QCLEventList(const QCLEvent &event);
|
||||
QCLEventList(const QCLEventList &other);
|
||||
~QCLEventList();
|
||||
|
||||
QCLEventList &operator=(const QCLEventList &other);
|
||||
|
||||
bool isEmpty() const { return m_events.isEmpty(); }
|
||||
int size() const { return m_events.size(); }
|
||||
|
||||
void append(const QCLEvent &event);
|
||||
void append(const QCLEventList &other);
|
||||
void remove(const QCLEvent &event);
|
||||
|
||||
QCLEvent at(int index) const;
|
||||
bool contains(const QCLEvent &event) const;
|
||||
|
||||
const cl_event *eventData() const;
|
||||
|
||||
QCLEventList &operator+=(const QCLEvent &event);
|
||||
QCLEventList &operator+=(const QCLEventList &other);
|
||||
|
||||
QCLEventList &operator<<(const QCLEvent &event);
|
||||
QCLEventList &operator<<(const QCLEventList &other);
|
||||
|
||||
void waitForFinished();
|
||||
|
||||
#ifndef QT_NO_CONCURRENT
|
||||
QFuture<void> toFuture() const;
|
||||
operator QFuture<void>() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
QVector<cl_event> m_events;
|
||||
};
|
||||
|
||||
inline bool QCLEvent::operator==(const QCLEvent &other) const
|
||||
{
|
||||
return m_id == other.m_id;
|
||||
}
|
||||
|
||||
inline bool QCLEvent::operator!=(const QCLEvent &other) const
|
||||
{
|
||||
return m_id != other.m_id;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CONCURRENT
|
||||
inline QCLEvent::operator QFuture<void>() const
|
||||
{
|
||||
return toFuture();
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool QCLEventList::contains(const QCLEvent &event) const
|
||||
{
|
||||
return m_events.contains(event.eventId());
|
||||
}
|
||||
|
||||
inline const cl_event *QCLEventList::eventData() const
|
||||
{
|
||||
return m_events.isEmpty() ? 0 : m_events.constData();
|
||||
}
|
||||
|
||||
inline QCLEventList &QCLEventList::operator+=(const QCLEvent &event)
|
||||
{
|
||||
append(event);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline QCLEventList &QCLEventList::operator+=(const QCLEventList &other)
|
||||
{
|
||||
append(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline QCLEventList &QCLEventList::operator<<(const QCLEvent &event)
|
||||
{
|
||||
append(event);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline QCLEventList &QCLEventList::operator<<(const QCLEventList &other)
|
||||
{
|
||||
append(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CONCURRENT
|
||||
inline QCLEventList::operator QFuture<void>() const
|
||||
{
|
||||
return toFuture();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
Q_CL_EXPORT QDebug operator<<(QDebug, const QCLEvent &);
|
||||
Q_CL_EXPORT QDebug operator<<(QDebug, const QCLEventList &);
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
131
Source/src/CL/qclext_p.h
Normal file
@ -0,0 +1,131 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLEXT_P_H
|
||||
#define QCLEXT_P_H
|
||||
|
||||
#include "qclglobal.h"
|
||||
|
||||
// This file provides standard and extension definitions
|
||||
// that we cannot rely upon being present in the system headers.
|
||||
|
||||
// OpenCL 1.1
|
||||
#ifndef CL_MISALIGNED_SUB_BUFFER_OFFSET
|
||||
#define CL_MISALIGNED_SUB_BUFFER_OFFSET -13
|
||||
#endif
|
||||
#ifndef CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST
|
||||
#define CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST -14
|
||||
#endif
|
||||
#ifndef CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF
|
||||
#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF 0x1034
|
||||
#endif
|
||||
#ifndef CL_DEVICE_HOST_UNIFIED_MEMORY
|
||||
#define CL_DEVICE_HOST_UNIFIED_MEMORY 0x1035
|
||||
#endif
|
||||
#ifndef CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR
|
||||
#define CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR 0x1036
|
||||
#define CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT 0x1037
|
||||
#define CL_DEVICE_NATIVE_VECTOR_WIDTH_INT 0x1038
|
||||
#define CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG 0x1039
|
||||
#define CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT 0x103A
|
||||
#define CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE 0x103B
|
||||
#define CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF 0x103C
|
||||
#endif
|
||||
#ifndef CL_DEVICE_OPENCL_C_VERSION
|
||||
#define CL_DEVICE_OPENCL_C_VERSION 0x103D
|
||||
#endif
|
||||
#ifndef CL_COMMAND_READ_BUFFER_RECT
|
||||
#define CL_COMMAND_READ_BUFFER_RECT 0x1201
|
||||
#endif
|
||||
#ifndef CL_COMMAND_WRITE_BUFFER_RECT
|
||||
#define CL_COMMAND_WRITE_BUFFER_RECT 0x1202
|
||||
#endif
|
||||
#ifndef CL_COMMAND_COPY_BUFFER_RECT
|
||||
#define CL_COMMAND_COPY_BUFFER_RECT 0x1203
|
||||
#endif
|
||||
#ifndef CL_COMMAND_USER
|
||||
#define CL_COMMAND_USER 0x1204
|
||||
#endif
|
||||
#ifndef CL_MEM_ASSOCIATED_MEMOBJECT
|
||||
#define CL_MEM_ASSOCIATED_MEMOBJECT 0x1107
|
||||
#endif
|
||||
#ifndef CL_MEM_OFFSET
|
||||
#define CL_MEM_OFFSET 0x1108
|
||||
#endif
|
||||
#ifndef CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE
|
||||
#define CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 0x11B3
|
||||
#endif
|
||||
|
||||
// OpenCL-OpenGL sharing.
|
||||
#ifndef CL_INVALID_CL_SHAREGROUP_REFERENCE_KHR
|
||||
#define CL_INVALID_CL_SHAREGROUP_REFERENCE_KHR -1000
|
||||
#endif
|
||||
|
||||
// cl_khr_fp64
|
||||
#ifndef CL_DEVICE_DOUBLE_FP_CONFIG
|
||||
#define CL_DEVICE_DOUBLE_FP_CONFIG 0x1032
|
||||
#endif
|
||||
|
||||
// cl_khr_fp16
|
||||
#ifndef CL_DEVICE_HALF_FP_CONFIG
|
||||
#define CL_DEVICE_HALF_FP_CONFIG 0x1033
|
||||
#endif
|
||||
|
||||
// cl_khr_icd
|
||||
#ifndef CL_PLATFORM_ICD_SUFFIX_KHR
|
||||
#define CL_PLATFORM_ICD_SUFFIX_KHR 0x0920
|
||||
#endif
|
||||
#ifndef CL_PLATFORM_NOT_FOUND_KHR
|
||||
#define CL_PLATFORM_NOT_FOUND_KHR -1001
|
||||
#endif
|
||||
|
||||
// cl_ext_device_fission
|
||||
#ifndef CL_DEVICE_PARTITION_FAILED_EXT
|
||||
#define CL_DEVICE_PARTITION_FAILED_EXT -1057
|
||||
#endif
|
||||
#ifndef CL_INVALID_PARTITION_COUNT_EXT
|
||||
#define CL_INVALID_PARTITION_COUNT_EXT -1058
|
||||
#endif
|
||||
#ifndef CL_INVALID_PARTITION_NAME_EXT
|
||||
#define CL_INVALID_PARTITION_NAME_EXT -1059
|
||||
#endif
|
||||
|
||||
#endif
|
||||
92
Source/src/CL/qclglobal.h
Normal file
@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLGLOBAL_H
|
||||
#define QCLGLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
// XXX: Move to qglobal.h eventually.
|
||||
QT_LICENSED_MODULE(CL)
|
||||
#if defined(Q_OS_WIN) && defined(QT_MAKEDLL)
|
||||
# if defined(QT_BUILD_CL_LIB)
|
||||
# define Q_CL_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define Q_CL_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#elif defined(Q_OS_WIN) && defined(QT_DLL)
|
||||
# define Q_CL_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
#if !defined(Q_CL_EXPORT)
|
||||
# if defined(QT_SHARED)
|
||||
# define Q_CL_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define Q_CL_EXPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
QT_LICENSED_MODULE(CLGL)
|
||||
#if defined(Q_OS_WIN) && defined(QT_MAKEDLL)
|
||||
# if defined(QT_BUILD_CLGL_LIB)
|
||||
# define Q_CLGL_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define Q_CLGL_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#elif defined(Q_OS_WIN) && defined(QT_DLL)
|
||||
# define Q_CLGL_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
#if !defined(Q_CLGL_EXPORT)
|
||||
# if defined(QT_SHARED)
|
||||
# define Q_CLGL_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define Q_CLGL_EXPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(__MACOSX)
|
||||
#include <OpenCL/cl_platform.h>
|
||||
#include <OpenCL/cl.h>
|
||||
#else
|
||||
#include <CL/cl_platform.h>
|
||||
#include <CL/cl.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
214
Source/src/CL/qclimage.h
Normal file
@ -0,0 +1,214 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLIMAGE_H
|
||||
#define QCLIMAGE_H
|
||||
|
||||
#include "qclmemoryobject.h"
|
||||
#include "qclimageformat.h"
|
||||
#include "qclevent.h"
|
||||
#include <QtCore/qrect.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLImage2DPrivate;
|
||||
class QCLImage3D;
|
||||
class QCLBuffer;
|
||||
class QPainter;
|
||||
|
||||
class Q_CL_EXPORT QCLImage2D : public QCLMemoryObject
|
||||
{
|
||||
public:
|
||||
QCLImage2D() : d_ptr(0) {}
|
||||
QCLImage2D(QCLContext *context, cl_mem id)
|
||||
: QCLMemoryObject(context, id), d_ptr(0) {}
|
||||
QCLImage2D(const QCLImage2D &other);
|
||||
~QCLImage2D();
|
||||
|
||||
QCLImage2D &operator=(const QCLImage2D &other);
|
||||
|
||||
QCLImageFormat format() const;
|
||||
|
||||
int width() const;
|
||||
int height() const;
|
||||
|
||||
int bytesPerElement() const;
|
||||
int bytesPerLine() const;
|
||||
|
||||
bool read(void *data, const QRect &rect, int bytesPerLine = 0);
|
||||
bool read(QImage *image, const QRect &rect = QRect());
|
||||
QCLEvent readAsync(void *data, const QRect &rect,
|
||||
const QCLEventList &after = QCLEventList(),
|
||||
int bytesPerLine = 0);
|
||||
|
||||
bool write(const void *data, const QRect &rect, int bytesPerLine = 0);
|
||||
bool write(const QImage &image, const QRect &rect = QRect());
|
||||
QCLEvent writeAsync
|
||||
(const void *data, const QRect &rect,
|
||||
const QCLEventList &after = QCLEventList(),
|
||||
int bytesPerLine = 0);
|
||||
|
||||
bool copyTo(const QRect &rect, const QCLImage2D &dest,
|
||||
const QPoint &destOffset);
|
||||
bool copyTo(const QRect &rect, const QCLImage3D &dest,
|
||||
const size_t destOffset[3]);
|
||||
bool copyTo(const QRect &rect, const QCLBuffer &dest,
|
||||
size_t destOffset);
|
||||
QCLEvent copyToAsync
|
||||
(const QRect &rect, const QCLImage2D &dest, const QPoint &destOffset,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
QCLEvent copyToAsync
|
||||
(const QRect &rect, const QCLImage3D &dest, const size_t destOffset[3],
|
||||
const QCLEventList &after = QCLEventList());
|
||||
QCLEvent copyToAsync
|
||||
(const QRect &rect, const QCLBuffer &dest, size_t destOffset,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
|
||||
void *map(const QRect &rect, QCLMemoryObject::Access access,
|
||||
int *bytesPerLine = 0);
|
||||
QCLEvent mapAsync(void **ptr, const QRect &rect,
|
||||
QCLMemoryObject::Access access,
|
||||
const QCLEventList &after = QCLEventList(),
|
||||
int *bytesPerLine = 0);
|
||||
|
||||
QImage toQImage(bool cached = true);
|
||||
|
||||
void drawImage(QPainter *painter, const QPoint &point,
|
||||
const QRect &subRect = QRect(),
|
||||
Qt::ImageConversionFlags flags = Qt::AutoColor);
|
||||
void drawImage(QPainter *painter, const QRect &targetRect,
|
||||
const QRect &subRect = QRect(),
|
||||
Qt::ImageConversionFlags flags = Qt::AutoColor);
|
||||
|
||||
private:
|
||||
mutable QCLImage2DPrivate *d_ptr;
|
||||
|
||||
Q_DECLARE_PRIVATE(QCLImage2D)
|
||||
|
||||
QCLImage2D(QCLContext *context, cl_mem id, const QCLImageFormat& format);
|
||||
|
||||
friend class QCLContext;
|
||||
};
|
||||
|
||||
class Q_CL_EXPORT QCLImage3D : public QCLMemoryObject
|
||||
{
|
||||
public:
|
||||
QCLImage3D() {}
|
||||
QCLImage3D(QCLContext *context, cl_mem id)
|
||||
: QCLMemoryObject(context, id) {}
|
||||
QCLImage3D(const QCLImage3D &other)
|
||||
: QCLMemoryObject() { setId(other.context(), other.memoryId()); }
|
||||
|
||||
QCLImage3D &operator=(const QCLImage3D &other)
|
||||
{
|
||||
setId(other.context(), other.memoryId());
|
||||
return *this;
|
||||
}
|
||||
|
||||
QCLImageFormat format() const;
|
||||
|
||||
int width() const;
|
||||
int height() const;
|
||||
int depth() const;
|
||||
|
||||
int bytesPerElement() const;
|
||||
int bytesPerLine() const;
|
||||
int bytesPerSlice() const;
|
||||
|
||||
bool read(void *data, const size_t origin[3], const size_t size[3],
|
||||
int bytesPerLine = 0, int bytesPerSlice = 0);
|
||||
QCLEvent readAsync
|
||||
(void *data, const size_t origin[3], const size_t size[3],
|
||||
const QCLEventList &after = QCLEventList(),
|
||||
int bytesPerLine = 0, int bytesPerSlice = 0);
|
||||
|
||||
bool write(const void *data, const size_t origin[3], const size_t size[3],
|
||||
int bytesPerLine = 0, int bytesPerSlice = 0);
|
||||
QCLEvent writeAsync
|
||||
(const void *data, const size_t origin[3], const size_t size[3],
|
||||
const QCLEventList &after = QCLEventList(),
|
||||
int bytesPerLine = 0, int bytesPerSlice = 0);
|
||||
|
||||
bool copyTo(const size_t origin[3], const size_t size[3],
|
||||
const QCLImage3D &dest, const size_t destOffset[3]);
|
||||
bool copyTo(const size_t origin[3], const QSize &size,
|
||||
const QCLImage2D &dest, const QPoint &destOffset);
|
||||
bool copyTo(const size_t origin[3], const size_t size[3],
|
||||
const QCLBuffer &dest, size_t destOffset);
|
||||
QCLEvent copyToAsync
|
||||
(const size_t origin[3], const size_t size[3],
|
||||
const QCLImage3D &dest, const size_t destOffset[3],
|
||||
const QCLEventList &after = QCLEventList());
|
||||
QCLEvent copyToAsync
|
||||
(const size_t origin[3], const QSize &size,
|
||||
const QCLImage2D &dest, const QPoint &destOffset,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
QCLEvent copyToAsync
|
||||
(const size_t origin[3], const size_t size[3],
|
||||
const QCLBuffer &dest, size_t destOffset,
|
||||
const QCLEventList &after = QCLEventList());
|
||||
|
||||
void *map(const size_t origin[3], const size_t size[3],
|
||||
QCLMemoryObject::Access access,
|
||||
int *bytesPerLine = 0, int *bytesPerSlice = 0);
|
||||
QCLEvent mapAsync
|
||||
(void **ptr, const size_t origin[3], const size_t size[3],
|
||||
QCLMemoryObject::Access access,
|
||||
const QCLEventList &after = QCLEventList(),
|
||||
int *bytesPerLine = 0, int *bytesPerSlice = 0);
|
||||
};
|
||||
|
||||
inline void QCLImage2D::drawImage
|
||||
(QPainter *painter, const QPoint &point,
|
||||
const QRect &subRect, Qt::ImageConversionFlags flags)
|
||||
{
|
||||
drawImage(painter, QRect(point.x(), point.y(), -1, -1), subRect, flags);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
167
Source/src/CL/qclimageformat.h
Normal file
@ -0,0 +1,167 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLIMAGEFORMAT_H
|
||||
#define QCLIMAGEFORMAT_H
|
||||
|
||||
#include "qclglobal.h"
|
||||
#include <QtGui/qimage.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLContext;
|
||||
|
||||
class Q_CL_EXPORT QCLImageFormat
|
||||
{
|
||||
public:
|
||||
enum ChannelOrder
|
||||
{
|
||||
Order_R = 0x10B0,
|
||||
Order_A = 0x10B1,
|
||||
Order_RG = 0x10B2,
|
||||
Order_RA = 0x10B3,
|
||||
Order_RGB = 0x10B4,
|
||||
Order_RGBA = 0x10B5,
|
||||
Order_BGRA = 0x10B6,
|
||||
Order_ARGB = 0x10B7,
|
||||
Order_Intensity = 0x10B8,
|
||||
Order_Luminence = 0x10B9,
|
||||
Order_Rx = 0x10BA, // OpenCL 1.1
|
||||
Order_RGx = 0x10BB, // OpenCL 1.1
|
||||
Order_RGBx = 0x10BC // OpenCL 1.1
|
||||
};
|
||||
|
||||
enum ChannelType
|
||||
{
|
||||
Type_Normalized_Int8 = 0x10D0,
|
||||
Type_Normalized_Int16 = 0x10D1,
|
||||
Type_Normalized_UInt8 = 0x10D2,
|
||||
Type_Normalized_UInt16 = 0x10D3,
|
||||
Type_Normalized_565 = 0x10D4,
|
||||
Type_Normalized_555 = 0x10D5,
|
||||
Type_Normalized_101010 = 0x10D6,
|
||||
Type_Unnormalized_Int8 = 0x10D7,
|
||||
Type_Unnormalized_Int16 = 0x10D8,
|
||||
Type_Unnormalized_Int32 = 0x10D9,
|
||||
Type_Unnormalized_UInt8 = 0x10DA,
|
||||
Type_Unnormalized_UInt16 = 0x10DB,
|
||||
Type_Unnormalized_UInt32 = 0x10DC,
|
||||
Type_Half_Float = 0x10DD,
|
||||
Type_Float = 0x10DE
|
||||
};
|
||||
|
||||
QCLImageFormat();
|
||||
QCLImageFormat(QCLImageFormat::ChannelOrder order,
|
||||
QCLImageFormat::ChannelType type);
|
||||
QCLImageFormat(QImage::Format format);
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
QCLImageFormat::ChannelOrder channelOrder() const;
|
||||
QCLImageFormat::ChannelType channelType() const;
|
||||
|
||||
bool operator==(const QCLImageFormat &other);
|
||||
bool operator!=(const QCLImageFormat &other);
|
||||
|
||||
QImage::Format toQImageFormat() const { return m_qformat; }
|
||||
|
||||
private:
|
||||
cl_image_format m_format;
|
||||
QImage::Format m_qformat;
|
||||
|
||||
friend class QCLContext;
|
||||
};
|
||||
|
||||
inline QCLImageFormat::QCLImageFormat()
|
||||
{
|
||||
m_format.image_channel_order = 0;
|
||||
m_format.image_channel_data_type = 0;
|
||||
m_qformat = QImage::Format_Invalid;
|
||||
}
|
||||
|
||||
inline bool QCLImageFormat::isNull() const
|
||||
{
|
||||
return m_format.image_channel_order == 0 &&
|
||||
m_format.image_channel_data_type == 0 &&
|
||||
m_qformat == QImage::Format_Invalid;
|
||||
}
|
||||
|
||||
inline QCLImageFormat::ChannelOrder QCLImageFormat::channelOrder() const
|
||||
{
|
||||
return QCLImageFormat::ChannelOrder(m_format.image_channel_order);
|
||||
}
|
||||
|
||||
inline QCLImageFormat::ChannelType QCLImageFormat::channelType() const
|
||||
{
|
||||
return QCLImageFormat::ChannelType(m_format.image_channel_data_type);
|
||||
}
|
||||
|
||||
inline bool QCLImageFormat::operator==(const QCLImageFormat &other)
|
||||
{
|
||||
return m_format.image_channel_order ==
|
||||
other.m_format.image_channel_order &&
|
||||
m_format.image_channel_data_type ==
|
||||
other.m_format.image_channel_data_type &&
|
||||
m_qformat == other.m_qformat;
|
||||
}
|
||||
|
||||
inline bool QCLImageFormat::operator!=(const QCLImageFormat &other)
|
||||
{
|
||||
return m_format.image_channel_order !=
|
||||
other.m_format.image_channel_order ||
|
||||
m_format.image_channel_data_type !=
|
||||
other.m_format.image_channel_data_type ||
|
||||
m_qformat != other.m_qformat;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
Q_CL_EXPORT QDebug operator<<(QDebug, const QCLImageFormat &);
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
480
Source/src/CL/qclkernel.h
Normal file
@ -0,0 +1,480 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLKERNEL_H
|
||||
#define QCLKERNEL_H
|
||||
|
||||
#include "qclglobal.h"
|
||||
#include "qclevent.h"
|
||||
#include "qclworksize.h"
|
||||
#include "qclmemoryobject.h"
|
||||
#include "qclsampler.h"
|
||||
#include "qclvector.h"
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
#include <QtCore/qtconcurrentrun.h>
|
||||
#include <QtCore/qpoint.h>
|
||||
#include <QtGui/qvector2d.h>
|
||||
#include <QtGui/qvector3d.h>
|
||||
#include <QtGui/qvector4d.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLContext;
|
||||
class QCLProgram;
|
||||
class QCLVectorBase;
|
||||
class QCLDevice;
|
||||
class QMatrix4x4;
|
||||
class QColor;
|
||||
|
||||
class QCLKernelPrivate;
|
||||
|
||||
class Q_CL_EXPORT QCLKernel
|
||||
{
|
||||
public:
|
||||
QCLKernel();
|
||||
QCLKernel(QCLContext *context, cl_kernel id);
|
||||
QCLKernel(const QCLKernel &other);
|
||||
~QCLKernel();
|
||||
|
||||
QCLKernel &operator=(const QCLKernel &other);
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
bool operator==(const QCLKernel &other) const;
|
||||
bool operator!=(const QCLKernel &other) const;
|
||||
|
||||
cl_kernel kernelId() const;
|
||||
QCLContext *context() const;
|
||||
|
||||
QCLProgram program() const;
|
||||
QString name() const;
|
||||
int argCount() const;
|
||||
|
||||
QCLWorkSize declaredWorkGroupSize() const;
|
||||
QCLWorkSize declaredWorkGroupSize(const QCLDevice &device) const;
|
||||
|
||||
QCLWorkSize globalWorkSize() const;
|
||||
void setGlobalWorkSize(const QCLWorkSize &size);
|
||||
void setGlobalWorkSize(size_t width, size_t height);
|
||||
void setGlobalWorkSize(size_t width, size_t height, size_t depth);
|
||||
|
||||
void setRoundedGlobalWorkSize(const QCLWorkSize &size);
|
||||
void setRoundedGlobalWorkSize(size_t width, size_t height);
|
||||
void setRoundedGlobalWorkSize(size_t width, size_t height, size_t depth);
|
||||
|
||||
QCLWorkSize localWorkSize() const;
|
||||
void setLocalWorkSize(const QCLWorkSize &size);
|
||||
void setLocalWorkSize(size_t width, size_t height);
|
||||
void setLocalWorkSize(size_t width, size_t height, size_t depth);
|
||||
|
||||
QCLWorkSize bestLocalWorkSizeImage2D() const;
|
||||
QCLWorkSize bestLocalWorkSizeImage3D() const;
|
||||
|
||||
size_t preferredWorkSizeMultiple() const;
|
||||
|
||||
void setArg(int index, cl_int value);
|
||||
void setArg(int index, cl_uint value);
|
||||
void setArg(int index, cl_long value);
|
||||
void setArg(int index, cl_ulong value);
|
||||
void setArg(int index, float value);
|
||||
void setArg(int index, const QVector2D &value);
|
||||
void setArg(int index, const QVector3D &value);
|
||||
void setArg(int index, const QVector4D &value);
|
||||
void setArg(int index, const QColor &value);
|
||||
void setArg(int index, Qt::GlobalColor value);
|
||||
void setArg(int index, const QPoint &value);
|
||||
void setArg(int index, const QPointF &value);
|
||||
void setArg(int index, const QMatrix4x4 &value);
|
||||
void setArg(int index, const QCLMemoryObject &value);
|
||||
#if defined(qdoc)
|
||||
void setArg(int index, const QCLVector<T> &value);
|
||||
#else
|
||||
void setArg(int index, const QCLVectorBase &value);
|
||||
#endif
|
||||
void setArg(int index, const QCLSampler &value);
|
||||
void setArg(int index, const void *data, size_t size);
|
||||
|
||||
QCLEvent run();
|
||||
QCLEvent run(const QCLEventList &after);
|
||||
|
||||
inline QCLEvent operator()() { return run(); }
|
||||
|
||||
template <typename T1>
|
||||
inline QCLEvent operator()(const T1 &arg1)
|
||||
{
|
||||
setArg(0, arg1);
|
||||
return run();
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline QCLEvent operator()(const T1 &arg1, const T2 &arg2)
|
||||
{
|
||||
setArg(0, arg1);
|
||||
setArg(1, arg2);
|
||||
return run();
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
inline QCLEvent operator()
|
||||
(const T1 &arg1, const T2 &arg2, const T3 &arg3)
|
||||
{
|
||||
setArg(0, arg1);
|
||||
setArg(1, arg2);
|
||||
setArg(2, arg3);
|
||||
return run();
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
inline QCLEvent operator()
|
||||
(const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4)
|
||||
{
|
||||
setArg(0, arg1);
|
||||
setArg(1, arg2);
|
||||
setArg(2, arg3);
|
||||
setArg(3, arg4);
|
||||
return run();
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4,
|
||||
typename T5>
|
||||
inline QCLEvent operator()
|
||||
(const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4,
|
||||
const T5 &arg5)
|
||||
{
|
||||
setArg(0, arg1);
|
||||
setArg(1, arg2);
|
||||
setArg(2, arg3);
|
||||
setArg(3, arg4);
|
||||
setArg(4, arg5);
|
||||
return run();
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4,
|
||||
typename T5, typename T6>
|
||||
inline QCLEvent operator()
|
||||
(const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4,
|
||||
const T5 &arg5, const T6 &arg6)
|
||||
{
|
||||
setArg(0, arg1);
|
||||
setArg(1, arg2);
|
||||
setArg(2, arg3);
|
||||
setArg(3, arg4);
|
||||
setArg(4, arg5);
|
||||
setArg(5, arg6);
|
||||
return run();
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4,
|
||||
typename T5, typename T6, typename T7>
|
||||
inline QCLEvent operator()
|
||||
(const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4,
|
||||
const T5 &arg5, const T6 &arg6, const T7 &arg7)
|
||||
{
|
||||
setArg(0, arg1);
|
||||
setArg(1, arg2);
|
||||
setArg(2, arg3);
|
||||
setArg(3, arg4);
|
||||
setArg(4, arg5);
|
||||
setArg(5, arg6);
|
||||
setArg(6, arg7);
|
||||
return run();
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4,
|
||||
typename T5, typename T6, typename T7, typename T8>
|
||||
inline QCLEvent operator()
|
||||
(const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4,
|
||||
const T5 &arg5, const T6 &arg6, const T7 &arg7, const T8 &arg8)
|
||||
{
|
||||
setArg(0, arg1);
|
||||
setArg(1, arg2);
|
||||
setArg(2, arg3);
|
||||
setArg(3, arg4);
|
||||
setArg(4, arg5);
|
||||
setArg(5, arg6);
|
||||
setArg(6, arg7);
|
||||
setArg(7, arg8);
|
||||
return run();
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4,
|
||||
typename T5, typename T6, typename T7, typename T8,
|
||||
typename T9>
|
||||
inline QCLEvent operator()
|
||||
(const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4,
|
||||
const T5 &arg5, const T6 &arg6, const T7 &arg7, const T8 &arg8,
|
||||
const T9 &arg9)
|
||||
{
|
||||
setArg(0, arg1);
|
||||
setArg(1, arg2);
|
||||
setArg(2, arg3);
|
||||
setArg(3, arg4);
|
||||
setArg(4, arg5);
|
||||
setArg(5, arg6);
|
||||
setArg(6, arg7);
|
||||
setArg(7, arg8);
|
||||
setArg(8, arg9);
|
||||
return run();
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4,
|
||||
typename T5, typename T6, typename T7, typename T8,
|
||||
typename T9, typename T10>
|
||||
inline QCLEvent operator()
|
||||
(const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4,
|
||||
const T5 &arg5, const T6 &arg6, const T7 &arg7, const T8 &arg8,
|
||||
const T9 &arg9, const T10 &arg10)
|
||||
{
|
||||
setArg(0, arg1);
|
||||
setArg(1, arg2);
|
||||
setArg(2, arg3);
|
||||
setArg(3, arg4);
|
||||
setArg(4, arg5);
|
||||
setArg(5, arg6);
|
||||
setArg(6, arg7);
|
||||
setArg(7, arg8);
|
||||
setArg(8, arg9);
|
||||
setArg(9, arg10);
|
||||
return run();
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CONCURRENT
|
||||
QFuture<void> runInThread();
|
||||
#endif
|
||||
|
||||
private:
|
||||
QScopedPointer<QCLKernelPrivate> d_ptr;
|
||||
cl_kernel m_kernelId;
|
||||
|
||||
Q_DECLARE_PRIVATE(QCLKernel)
|
||||
};
|
||||
|
||||
inline void QCLKernel::setGlobalWorkSize(size_t width, size_t height)
|
||||
{
|
||||
setGlobalWorkSize(QCLWorkSize(width, height));
|
||||
}
|
||||
|
||||
inline void QCLKernel::setGlobalWorkSize(size_t width, size_t height, size_t depth)
|
||||
{
|
||||
setGlobalWorkSize(QCLWorkSize(width, height, depth));
|
||||
}
|
||||
|
||||
inline void QCLKernel::setRoundedGlobalWorkSize(const QCLWorkSize &size)
|
||||
{
|
||||
setGlobalWorkSize(size.roundTo(localWorkSize()));
|
||||
}
|
||||
|
||||
inline void QCLKernel::setRoundedGlobalWorkSize(size_t width, size_t height)
|
||||
{
|
||||
setRoundedGlobalWorkSize(QCLWorkSize(width, height));
|
||||
}
|
||||
|
||||
inline void QCLKernel::setRoundedGlobalWorkSize(size_t width, size_t height, size_t depth)
|
||||
{
|
||||
setRoundedGlobalWorkSize(QCLWorkSize(width, height, depth));
|
||||
}
|
||||
|
||||
inline void QCLKernel::setLocalWorkSize(size_t width, size_t height)
|
||||
{
|
||||
setLocalWorkSize(QCLWorkSize(width, height));
|
||||
}
|
||||
|
||||
inline void QCLKernel::setLocalWorkSize(size_t width, size_t height, size_t depth)
|
||||
{
|
||||
setLocalWorkSize(QCLWorkSize(width, height, depth));
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, cl_int value)
|
||||
{
|
||||
clSetKernelArg(m_kernelId, index, sizeof(value), &value);
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, cl_uint value)
|
||||
{
|
||||
clSetKernelArg(m_kernelId, index, sizeof(value), &value);
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, cl_long value)
|
||||
{
|
||||
clSetKernelArg(m_kernelId, index, sizeof(value), &value);
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, cl_ulong value)
|
||||
{
|
||||
clSetKernelArg(m_kernelId, index, sizeof(value), &value);
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, float value)
|
||||
{
|
||||
clSetKernelArg(m_kernelId, index, sizeof(value), &value);
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, const QVector2D &value)
|
||||
{
|
||||
if (sizeof(value) == (sizeof(float) * 2)) {
|
||||
clSetKernelArg(m_kernelId, index, sizeof(value), &value);
|
||||
} else {
|
||||
float values[2] = {(float)value.x(), (float)value.y()};
|
||||
clSetKernelArg(m_kernelId, index, sizeof(values), values);
|
||||
}
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, const QVector3D &value)
|
||||
{
|
||||
float values[4] = {(float)value.x(), (float)value.y(), (float)value.z(), 1.0f};
|
||||
clSetKernelArg(m_kernelId, index, sizeof(values), values);
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, const QVector4D &value)
|
||||
{
|
||||
if (sizeof(value) == (sizeof(float) * 4)) {
|
||||
clSetKernelArg(m_kernelId, index, sizeof(value), &value);
|
||||
} else {
|
||||
float values[4] = {(float)value.x(), (float)value.y(), (float)value.z(), (float)value.w()};
|
||||
clSetKernelArg(m_kernelId, index, sizeof(values), values);
|
||||
}
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, const QPoint &value)
|
||||
{
|
||||
cl_int values[2] = {value.x(), value.y()};
|
||||
clSetKernelArg(m_kernelId, index, sizeof(values), values);
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, const QPointF &value)
|
||||
{
|
||||
if (sizeof(value) == (sizeof(float) * 2)) {
|
||||
clSetKernelArg(m_kernelId, index, sizeof(value), &value);
|
||||
} else {
|
||||
float values[2] = {(float)value.x(), (float)value.y()};
|
||||
clSetKernelArg(m_kernelId, index, sizeof(values), values);
|
||||
}
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, const QCLMemoryObject &value)
|
||||
{
|
||||
cl_mem id = value.memoryId();
|
||||
clSetKernelArg(m_kernelId, index, sizeof(id), &id);
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, const QCLVectorBase &value)
|
||||
{
|
||||
cl_mem id = value.kernelArg();
|
||||
clSetKernelArg(m_kernelId, index, sizeof(id), &id);
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, const QCLSampler &value)
|
||||
{
|
||||
cl_sampler id = value.samplerId();
|
||||
clSetKernelArg(m_kernelId, index, sizeof(id), &id);
|
||||
}
|
||||
|
||||
inline void QCLKernel::setArg(int index, const void *data, size_t size)
|
||||
{
|
||||
clSetKernelArg(m_kernelId, index, size, data);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_CONCURRENT
|
||||
|
||||
// Convenience function definitions that make it possible to say
|
||||
// QtConcurrent::run(kernel, ...) and have it do the right thing.
|
||||
namespace QtConcurrent
|
||||
{
|
||||
|
||||
inline QFuture<void> run(QCLKernel &kernel)
|
||||
{
|
||||
return kernel.runInThread();
|
||||
}
|
||||
template <typename Arg1>
|
||||
inline QFuture<void> run(QCLKernel &kernel, const Arg1 &arg1)
|
||||
{
|
||||
kernel.setArg(0, arg1);
|
||||
return kernel.runInThread();
|
||||
}
|
||||
template <typename Arg1, typename Arg2>
|
||||
inline QFuture<void> run(QCLKernel &kernel, const Arg1 &arg1, const Arg2 &arg2)
|
||||
{
|
||||
kernel.setArg(0, arg1);
|
||||
kernel.setArg(1, arg2);
|
||||
return kernel.runInThread();
|
||||
}
|
||||
template <typename Arg1, typename Arg2, typename Arg3>
|
||||
inline QFuture<void> run(QCLKernel &kernel, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3)
|
||||
{
|
||||
kernel.setArg(0, arg1);
|
||||
kernel.setArg(1, arg2);
|
||||
kernel.setArg(2, arg3);
|
||||
return kernel.runInThread();
|
||||
}
|
||||
template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
|
||||
inline QFuture<void> run(QCLKernel &kernel, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4)
|
||||
{
|
||||
kernel.setArg(0, arg1);
|
||||
kernel.setArg(1, arg2);
|
||||
kernel.setArg(2, arg3);
|
||||
kernel.setArg(3, arg4);
|
||||
return kernel.runInThread();
|
||||
}
|
||||
template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
|
||||
inline QFuture<void> run(QCLKernel &kernel, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3, const Arg4 &arg4, const Arg5 &arg5)
|
||||
{
|
||||
kernel.setArg(0, arg1);
|
||||
kernel.setArg(1, arg2);
|
||||
kernel.setArg(2, arg3);
|
||||
kernel.setArg(3, arg4);
|
||||
kernel.setArg(4, arg5);
|
||||
return kernel.runInThread();
|
||||
}
|
||||
|
||||
} // namespace QtConcurrent
|
||||
|
||||
#endif // QT_NO_CONCURRENT
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
128
Source/src/CL/qclmemoryobject.h
Normal file
@ -0,0 +1,128 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLMEMORYOBJECT_H
|
||||
#define QCLMEMORYOBJECT_H
|
||||
|
||||
#include "qclevent.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLContext;
|
||||
|
||||
class Q_CL_EXPORT QCLMemoryObject
|
||||
{
|
||||
protected:
|
||||
QCLMemoryObject(QCLContext *context = 0) : m_context(context), m_id(0) {}
|
||||
QCLMemoryObject(QCLContext *context, cl_mem id)
|
||||
: m_context(context), m_id(id) {}
|
||||
~QCLMemoryObject();
|
||||
|
||||
public:
|
||||
enum Access
|
||||
{
|
||||
ReadWrite = 0x0001,
|
||||
WriteOnly = 0x0002,
|
||||
ReadOnly = 0x0004
|
||||
};
|
||||
|
||||
bool isNull() const { return m_id == 0; }
|
||||
|
||||
cl_mem memoryId() const { return m_id; }
|
||||
QCLContext *context() const { return m_context; }
|
||||
|
||||
QCLMemoryObject::Access access() const;
|
||||
cl_mem_flags flags() const;
|
||||
void *hostPointer() const;
|
||||
size_t size() const;
|
||||
|
||||
void unmap(void *ptr);
|
||||
QCLEvent unmapAsync
|
||||
(void *ptr, const QCLEventList &after = QCLEventList());
|
||||
|
||||
bool operator==(const QCLMemoryObject &other) const;
|
||||
bool operator!=(const QCLMemoryObject &other) const;
|
||||
|
||||
protected:
|
||||
void setId(QCLContext *context, cl_mem id);
|
||||
|
||||
private:
|
||||
QCLContext *m_context;
|
||||
cl_mem m_id;
|
||||
|
||||
Q_DISABLE_COPY(QCLMemoryObject)
|
||||
};
|
||||
|
||||
inline QCLMemoryObject::~QCLMemoryObject()
|
||||
{
|
||||
if (m_id)
|
||||
clReleaseMemObject(m_id);
|
||||
}
|
||||
|
||||
inline bool QCLMemoryObject::operator==(const QCLMemoryObject &other) const
|
||||
{
|
||||
return m_id == other.m_id;
|
||||
}
|
||||
|
||||
inline bool QCLMemoryObject::operator!=(const QCLMemoryObject &other) const
|
||||
{
|
||||
return m_id != other.m_id;
|
||||
}
|
||||
|
||||
inline void QCLMemoryObject::setId(QCLContext *context, cl_mem id)
|
||||
{
|
||||
m_context = context;
|
||||
if (id)
|
||||
clRetainMemObject(id);
|
||||
if (m_id)
|
||||
clReleaseMemObject(m_id);
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
117
Source/src/CL/qclplatform.h
Normal file
@ -0,0 +1,117 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLPLATFORM_H
|
||||
#define QCLPLATFORM_H
|
||||
|
||||
#include "qclglobal.h"
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class Q_CL_EXPORT QCLPlatform
|
||||
{
|
||||
public:
|
||||
QCLPlatform() : m_id(0), m_flags(0) {}
|
||||
QCLPlatform(cl_platform_id id) : m_id(id), m_flags(0) {}
|
||||
|
||||
bool isNull() const { return m_id == 0; }
|
||||
|
||||
bool isFullProfile() const;
|
||||
bool isEmbeddedProfile() const;
|
||||
|
||||
QString profile() const;
|
||||
QString version() const;
|
||||
QString name() const;
|
||||
QString vendor() const;
|
||||
QString extensionSuffix() const;
|
||||
QStringList extensions() const;
|
||||
|
||||
bool hasExtension(const char *name) const;
|
||||
|
||||
enum VersionFlag
|
||||
{
|
||||
Version_1_0 = 0x0001,
|
||||
Version_1_1 = 0x0002
|
||||
};
|
||||
Q_DECLARE_FLAGS(VersionFlags, VersionFlag)
|
||||
|
||||
QCLPlatform::VersionFlags versionFlags() const;
|
||||
|
||||
cl_platform_id platformId() const { return m_id; }
|
||||
|
||||
static QList<QCLPlatform> platforms();
|
||||
|
||||
bool operator==(const QCLPlatform &other) const;
|
||||
bool operator!=(const QCLPlatform &other) const;
|
||||
|
||||
private:
|
||||
cl_platform_id m_id;
|
||||
mutable int m_flags;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QCLPlatform::VersionFlags)
|
||||
|
||||
inline bool QCLPlatform::operator==(const QCLPlatform &other) const
|
||||
{
|
||||
return m_id == other.m_id;
|
||||
}
|
||||
|
||||
inline bool QCLPlatform::operator!=(const QCLPlatform &other) const
|
||||
{
|
||||
return m_id != other.m_id;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
Q_CL_EXPORT QDebug operator<<(QDebug, const QCLPlatform &);
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
137
Source/src/CL/qclprogram.h
Normal file
@ -0,0 +1,137 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLPROGRAM_H
|
||||
#define QCLPROGRAM_H
|
||||
|
||||
#include "qcldevice.h"
|
||||
#include "qclkernel.h"
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLContext;
|
||||
|
||||
class Q_CL_EXPORT QCLProgram
|
||||
{
|
||||
public:
|
||||
QCLProgram() : m_context(0), m_id(0) {}
|
||||
QCLProgram(QCLContext *context, cl_program id)
|
||||
: m_context(context), m_id(id) {}
|
||||
QCLProgram(const QCLProgram &other);
|
||||
~QCLProgram();
|
||||
|
||||
QCLProgram &operator=(const QCLProgram &other);
|
||||
|
||||
bool isNull() const { return m_id == 0; }
|
||||
|
||||
cl_program programId() const { return m_id; }
|
||||
QCLContext *context() const { return m_context; }
|
||||
|
||||
bool build(const QString &options = QString());
|
||||
bool build(const QList<QCLDevice> &devices, const QString &options = QString());
|
||||
|
||||
QString log() const;
|
||||
|
||||
QList<QCLDevice> devices() const;
|
||||
QByteArray sourceCode() const;
|
||||
QList<QByteArray> binaries() const;
|
||||
|
||||
QCLKernel createKernel(const char *name) const;
|
||||
QCLKernel createKernel(const QByteArray &name) const;
|
||||
QCLKernel createKernel(const QString &name) const;
|
||||
|
||||
QList<QCLKernel> createKernels() const;
|
||||
|
||||
static void unloadCompiler();
|
||||
|
||||
bool operator==(const QCLProgram &other) const;
|
||||
bool operator!=(const QCLProgram &other) const;
|
||||
|
||||
private:
|
||||
QCLContext *m_context;
|
||||
cl_program m_id;
|
||||
};
|
||||
|
||||
inline bool QCLProgram::operator==(const QCLProgram &other) const
|
||||
{
|
||||
return m_id == other.m_id;
|
||||
}
|
||||
|
||||
inline QCLProgram::QCLProgram(const QCLProgram &other)
|
||||
: m_context(other.m_context), m_id(other.m_id)
|
||||
{
|
||||
if (m_id)
|
||||
clRetainProgram(m_id);
|
||||
}
|
||||
|
||||
inline QCLProgram::~QCLProgram()
|
||||
{
|
||||
if (m_id)
|
||||
clReleaseProgram(m_id);
|
||||
}
|
||||
|
||||
inline QCLProgram &QCLProgram::operator=(const QCLProgram &other)
|
||||
{
|
||||
m_context = other.m_context;
|
||||
if (other.m_id)
|
||||
clRetainProgram(other.m_id);
|
||||
if (m_id)
|
||||
clReleaseProgram(m_id);
|
||||
m_id = other.m_id;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool QCLProgram::operator!=(const QCLProgram &other) const
|
||||
{
|
||||
return m_id != other.m_id;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
137
Source/src/CL/qclsampler.h
Normal file
@ -0,0 +1,137 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLSAMPLER_H
|
||||
#define QCLSAMPLER_H
|
||||
|
||||
#include "qclglobal.h"
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLSamplerPrivate;
|
||||
class QCLContext;
|
||||
|
||||
class Q_CL_EXPORT QCLSampler
|
||||
{
|
||||
public:
|
||||
QCLSampler() : m_context(0), m_id(0) {}
|
||||
QCLSampler(QCLContext *context, cl_sampler id)
|
||||
: m_context(context), m_id(id) {}
|
||||
QCLSampler(const QCLSampler &other);
|
||||
~QCLSampler();
|
||||
|
||||
QCLSampler &operator=(const QCLSampler &other);
|
||||
|
||||
enum AddressingMode
|
||||
{
|
||||
None = 0x1130, // CL_ADDRESS_NONE
|
||||
ClampToEdge = 0x1131, // CL_ADDRESS_CLAMP_TO_EDGE
|
||||
Clamp = 0x1132, // CL_ADDRESS_CLAMP
|
||||
Repeat = 0x1133 // CL_ADDRESS_REPEAT
|
||||
};
|
||||
|
||||
enum FilterMode
|
||||
{
|
||||
Nearest = 0x1140, // CL_FILTER_NEAREST
|
||||
Linear = 0x1141 // CL_FILTER_LINEAR
|
||||
};
|
||||
|
||||
bool isNull() const { return m_id == 0; }
|
||||
|
||||
bool normalizedCoordinates() const;
|
||||
QCLSampler::AddressingMode addressingMode() const;
|
||||
QCLSampler::FilterMode filterMode() const;
|
||||
|
||||
cl_sampler samplerId() const { return m_id; }
|
||||
QCLContext *context() const { return m_context; }
|
||||
|
||||
bool operator==(const QCLSampler &other) const;
|
||||
bool operator!=(const QCLSampler &other) const;
|
||||
|
||||
private:
|
||||
QCLContext *m_context;
|
||||
cl_sampler m_id;
|
||||
};
|
||||
|
||||
inline QCLSampler::QCLSampler(const QCLSampler &other)
|
||||
: m_context(other.m_context), m_id(other.m_id)
|
||||
{
|
||||
if (m_id)
|
||||
clRetainSampler(m_id);
|
||||
}
|
||||
|
||||
inline QCLSampler::~QCLSampler()
|
||||
{
|
||||
if (m_id)
|
||||
clReleaseSampler(m_id);
|
||||
}
|
||||
|
||||
inline QCLSampler &QCLSampler::operator=(const QCLSampler &other)
|
||||
{
|
||||
m_context = other.m_context;
|
||||
if (other.m_id)
|
||||
clRetainSampler(other.m_id);
|
||||
if (m_id)
|
||||
clReleaseSampler(m_id);
|
||||
m_id = other.m_id;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool QCLSampler::operator==(const QCLSampler &other) const
|
||||
{
|
||||
return m_id == other.m_id;
|
||||
}
|
||||
|
||||
inline bool QCLSampler::operator!=(const QCLSampler &other) const
|
||||
{
|
||||
return m_id != other.m_id;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
87
Source/src/CL/qcluserevent.h
Normal file
@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLUSEREVENT_H
|
||||
#define QCLUSEREVENT_H
|
||||
|
||||
#include "qclevent.h"
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLContext;
|
||||
|
||||
class Q_CL_EXPORT QCLUserEvent : public QCLEvent
|
||||
{
|
||||
public:
|
||||
QCLUserEvent() : QCLEvent() {}
|
||||
QCLUserEvent(cl_event id);
|
||||
QCLUserEvent(const QCLEvent &other);
|
||||
|
||||
QCLUserEvent &operator=(const QCLEvent &other);
|
||||
|
||||
void setFinished();
|
||||
void setStatus(cl_int status);
|
||||
|
||||
private:
|
||||
void validateEvent();
|
||||
|
||||
// Used by QCLContext::createUserEvent() to avoid
|
||||
// the overhead of validateEvent().
|
||||
QCLUserEvent(cl_event id, bool dummy)
|
||||
: QCLEvent(id) { Q_UNUSED(dummy); }
|
||||
|
||||
friend class QCLContext;
|
||||
};
|
||||
|
||||
inline void QCLUserEvent::setFinished()
|
||||
{
|
||||
setStatus(CL_COMPLETE);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
228
Source/src/CL/qclvector.h
Normal file
@ -0,0 +1,228 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLVECTOR_H
|
||||
#define QCLVECTOR_H
|
||||
|
||||
#include "qclbuffer.h"
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
#include <QtCore/qvector.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLContext;
|
||||
class QCLKernel;
|
||||
class QCLVectorBasePrivate;
|
||||
|
||||
class Q_CL_EXPORT QCLVectorBase
|
||||
{
|
||||
protected:
|
||||
QCLVectorBase(size_t elemSize);
|
||||
QCLVectorBase(size_t elemSize, const QCLVectorBase &other);
|
||||
~QCLVectorBase();
|
||||
|
||||
QCLVectorBasePrivate *d_ptr;
|
||||
size_t m_elemSize;
|
||||
size_t m_size;
|
||||
mutable void *m_mapped;
|
||||
|
||||
void assign(const QCLVectorBase &other);
|
||||
|
||||
void create(QCLContext *context, int size, QCLMemoryObject::Access access);
|
||||
void release();
|
||||
|
||||
void map();
|
||||
void unmap() const;
|
||||
|
||||
void read(void *data, int count, int offset);
|
||||
void write(const void *data, int count, int offset);
|
||||
|
||||
cl_mem memoryId() const;
|
||||
QCLContext *context() const;
|
||||
|
||||
cl_mem kernelArg() const;
|
||||
|
||||
friend class QCLKernel;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class QCLVector : public QCLVectorBase
|
||||
{
|
||||
public:
|
||||
QCLVector();
|
||||
QCLVector(const QCLVector<T> &other);
|
||||
~QCLVector();
|
||||
|
||||
QCLVector<T> &operator=(const QCLVector<T> &other);
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
void release();
|
||||
|
||||
inline bool isEmpty() const { return m_size == 0; }
|
||||
inline int size() const { return m_size; }
|
||||
|
||||
T &operator[](int index);
|
||||
const T &operator[](int index) const;
|
||||
|
||||
void read(T *data, int count, int offset = 0);
|
||||
void write(const T *data, int count, int offset = 0);
|
||||
void write(const QVector<T> &data, int offset = 0);
|
||||
|
||||
QCLContext *context() const;
|
||||
QCLBuffer toBuffer() const;
|
||||
|
||||
private:
|
||||
QCLVector(QCLContext *context, int size, QCLMemoryObject::Access access);
|
||||
|
||||
friend class QCLContext;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE QCLVector<T>::QCLVector()
|
||||
: QCLVectorBase(sizeof(T)) {}
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE QCLVector<T>::QCLVector
|
||||
(QCLContext *context, int size, QCLMemoryObject::Access access)
|
||||
: QCLVectorBase(sizeof(T))
|
||||
{
|
||||
QCLVectorBase::create(context, size, access);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE QCLVector<T>::QCLVector(const QCLVector<T> &other)
|
||||
: QCLVectorBase(sizeof(T), other)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE QCLVector<T>::~QCLVector() {}
|
||||
|
||||
template <typename T>
|
||||
QCLVector<T> &QCLVector<T>::operator=(const QCLVector<T> &other)
|
||||
{
|
||||
assign(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE bool QCLVector<T>::isNull() const
|
||||
{
|
||||
return d_ptr == 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE void QCLVector<T>::release()
|
||||
{
|
||||
QCLVectorBase::release();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE T &QCLVector<T>::operator[](int index)
|
||||
{
|
||||
Q_ASSERT_X(index >= 0 && index < int(m_size), "QCLVector<T>::operator[]",
|
||||
"index out of range");
|
||||
if (!m_mapped)
|
||||
map();
|
||||
return (reinterpret_cast<T *>(m_mapped))[index];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE const T &QCLVector<T>::operator[](int index) const
|
||||
{
|
||||
Q_ASSERT_X(index >= 0 && index < int(m_size), "QCLVector<T>::operator[]",
|
||||
"index out of range");
|
||||
if (!m_mapped)
|
||||
const_cast<QCLVector<T> *>(this)->map();
|
||||
return (reinterpret_cast<T *>(m_mapped))[index];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE void QCLVector<T>::write
|
||||
(const T *data, int count, int offset)
|
||||
{
|
||||
Q_ASSERT(count >= 0 && offset >= 0 && (offset + count) <= int(m_size));
|
||||
QCLVectorBase::write(data, count * sizeof(T), offset * sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE void QCLVector<T>::read
|
||||
(T *data, int count, int offset)
|
||||
{
|
||||
Q_ASSERT(count >= 0 && offset >= 0 && (offset + count) <= int(m_size));
|
||||
QCLVectorBase::read(data, count * sizeof(T), offset * sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE void QCLVector<T>::write
|
||||
(const QVector<T> &data, int offset)
|
||||
{
|
||||
write(data.constData(), data.size(), offset);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE QCLContext *QCLVector<T>::context() const
|
||||
{
|
||||
return QCLVectorBase::context();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Q_INLINE_TEMPLATE QCLBuffer QCLVector<T>::toBuffer() const
|
||||
{
|
||||
cl_mem id = QCLVectorBase::memoryId();
|
||||
if (id) {
|
||||
clRetainMemObject(id);
|
||||
return QCLBuffer(context(), id);
|
||||
} else {
|
||||
return QCLBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
126
Source/src/CL/qclworksize.h
Normal file
@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtOpenCL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** No Commercial Usage
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCLWORKSIZE_H
|
||||
#define QCLWORKSIZE_H
|
||||
|
||||
#include "qclglobal.h"
|
||||
#include <QtCore/qsize.h>
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(CL)
|
||||
|
||||
class QCLDevice;
|
||||
|
||||
class Q_CL_EXPORT QCLWorkSize
|
||||
{
|
||||
public:
|
||||
QCLWorkSize()
|
||||
: m_dim(1) { m_sizes[0] = 1; m_sizes[1] = 1; m_sizes[2] = 1; }
|
||||
QCLWorkSize(size_t size)
|
||||
: m_dim(1) { m_sizes[0] = size; m_sizes[1] = 1; m_sizes[2] = 1; }
|
||||
QCLWorkSize(size_t width, size_t height)
|
||||
: m_dim(2) { m_sizes[0] = width; m_sizes[1] = height; m_sizes[2] = 1; }
|
||||
QCLWorkSize(const QSize &size)
|
||||
: m_dim(2) { m_sizes[0] = size.width(); m_sizes[1] = size.height(); m_sizes[2] = 1; }
|
||||
QCLWorkSize(size_t width, size_t height, size_t depth)
|
||||
: m_dim(3)
|
||||
{ m_sizes[0] = width; m_sizes[1] = height; m_sizes[2] = depth; }
|
||||
|
||||
size_t dimensions() const { return m_dim; }
|
||||
size_t width() const { return m_sizes[0]; }
|
||||
size_t height() const { return m_sizes[1]; }
|
||||
size_t depth() const { return m_sizes[2]; }
|
||||
|
||||
const size_t *sizes() const { return m_sizes; }
|
||||
|
||||
bool operator==(const QCLWorkSize &other) const;
|
||||
bool operator!=(const QCLWorkSize &other) const;
|
||||
|
||||
QCLWorkSize toLocalWorkSize
|
||||
(const QCLWorkSize &maxWorkItemSize, size_t maxItemsPerGroup) const;
|
||||
QCLWorkSize toLocalWorkSize(const QCLDevice &device) const;
|
||||
|
||||
QCLWorkSize roundTo(const QCLWorkSize &size) const;
|
||||
|
||||
QString toString() const;
|
||||
static QCLWorkSize fromString(const QString &str);
|
||||
|
||||
private:
|
||||
size_t m_dim;
|
||||
size_t m_sizes[3];
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(QCLWorkSize, Q_MOVABLE_TYPE);
|
||||
|
||||
inline bool QCLWorkSize::operator==(const QCLWorkSize &other) const
|
||||
{
|
||||
return m_dim == other.m_dim &&
|
||||
m_sizes[0] == other.m_sizes[0] &&
|
||||
m_sizes[1] == other.m_sizes[1] &&
|
||||
m_sizes[2] == other.m_sizes[2];
|
||||
}
|
||||
|
||||
inline bool QCLWorkSize::operator!=(const QCLWorkSize &other) const
|
||||
{
|
||||
return m_dim != other.m_dim ||
|
||||
m_sizes[0] != other.m_sizes[0] ||
|
||||
m_sizes[1] != other.m_sizes[1] ||
|
||||
m_sizes[2] != other.m_sizes[2];
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
Q_CL_EXPORT QDataStream &operator<<(QDataStream &, const QCLWorkSize &);
|
||||
Q_CL_EXPORT QDataStream &operator>>(QDataStream &, QCLWorkSize &);
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
Q_CL_EXPORT QDebug operator<<(QDebug, const QCLWorkSize &);
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif
|
||||
116
Source/src/DataEngine/cusdr_audioReceiver.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @file audioReceiver.cpp
|
||||
* @brief audio receiver class
|
||||
* @author Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2011 Hermann von Hasseln, DL3HVH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License version 2 as
|
||||
* published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define LOG_AUDIO_RECEIVER
|
||||
|
||||
#include "cusdr_audioReceiver.h"
|
||||
|
||||
|
||||
AudioReceiver::AudioReceiver(THPSDRParameter *ioData)
|
||||
: QObject()
|
||||
, set(Settings::instance())
|
||||
, io(ioData)
|
||||
, m_client(0)
|
||||
{
|
||||
}
|
||||
|
||||
AudioReceiver::~AudioReceiver() {
|
||||
|
||||
}
|
||||
|
||||
void AudioReceiver::displayAudioRcvrSocketError(QAbstractSocket::SocketError error) {
|
||||
|
||||
AUDIO_RECEIVER << "audio client socket error:" << error;
|
||||
}
|
||||
|
||||
void AudioReceiver::initClient() {
|
||||
|
||||
quint16 port = (quint16) (set->getAudioPort() + (io->audio_rx * 2));
|
||||
|
||||
QUdpSocket *socket = new QUdpSocket();
|
||||
socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
|
||||
|
||||
if (socket->bind(port, QUdpSocket::ReuseAddressHint | QUdpSocket::ShareAddress)) {
|
||||
|
||||
CHECKED_CONNECT(
|
||||
socket,
|
||||
SIGNAL(error(QAbstractSocket::SocketError)),
|
||||
this,
|
||||
SLOT(displayAudioRcvrSocketError(QAbstractSocket::SocketError)));
|
||||
|
||||
CHECKED_CONNECT(
|
||||
socket,
|
||||
SIGNAL(readyRead()),
|
||||
this,
|
||||
SLOT(readPendingAudioRcvrData()));
|
||||
|
||||
clientConnections.append(socket);
|
||||
|
||||
AUDIO_RECEIVER << "client socket binding successful.";
|
||||
m_message = tr("[server]: listening for rx %1 audio on port %2.");
|
||||
emit messageEvent(m_message.arg(io->audio_rx).arg(port));
|
||||
|
||||
//m_dataEngine->clientConnected = true;
|
||||
// need to implement connection in dataEngine !!!!
|
||||
emit clientConnectedEvent(true);
|
||||
//rcveIQ_toggle = false;
|
||||
}
|
||||
else {
|
||||
|
||||
m_message = tr("[server]: bind socket failed for socket on port %1.");
|
||||
emit messageEvent(m_message.arg(port));
|
||||
}
|
||||
}
|
||||
|
||||
void AudioReceiver::readPendingAudioRcvrData() {
|
||||
|
||||
QUdpSocket *socket = qobject_cast<QUdpSocket *>(sender());
|
||||
|
||||
while (socket->hasPendingDatagrams()) {
|
||||
|
||||
m_datagram.resize(socket->pendingDatagramSize());
|
||||
|
||||
if (socket->readDatagram(m_datagram.data(), m_datagram.size()) < 0) {
|
||||
|
||||
AUDIO_RECEIVER << "read client" << m_client << "socket failed.";
|
||||
if (io->rcveIQ_toggle) { // toggles the rcveIQ signal
|
||||
|
||||
emit rcveIQEvent(this, 2);
|
||||
io->rcveIQ_toggle = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
io->au_queue.enqueue(m_datagram);
|
||||
|
||||
if (!io->rcveIQ_toggle) { // toggles the rcveIQ signal
|
||||
|
||||
emit rcveIQEvent(this, 1);
|
||||
io->rcveIQ_toggle = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
87
Source/src/DataEngine/cusdr_audioReceiver.h
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @file audioReceiver.h
|
||||
* @brief audio receiver header file
|
||||
* @author Hermann von Hasseln, DL3HVH
|
||||
* @version 0.1
|
||||
* @date 2011-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2011 Hermann von Hasseln, DL3HVH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License version 2 as
|
||||
* published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _CUSDR_AUDIORECEIVER_H
|
||||
#define _CUSDR_AUDIORECEIVER_H
|
||||
|
||||
//#include <QObject>
|
||||
//#include <QMutex>
|
||||
//#include <QByteArray>
|
||||
//#include <QBuffer>
|
||||
//#include <QVector>
|
||||
//#include <QList>
|
||||
//#include <QWaitCondition>
|
||||
//#include <QThread>
|
||||
|
||||
#include "cusdr_settings.h"
|
||||
|
||||
#ifdef LOG_AUDIO_RECEIVER
|
||||
# define AUDIO_RECEIVER qDebug().nospace() << "AudioReceiver::\t"
|
||||
#else
|
||||
# define AUDIO_RECEIVER nullDebug()
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
class AudioReceiver : public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioReceiver(THPSDRParameter *ioData = 0);
|
||||
~AudioReceiver();
|
||||
|
||||
//int id;
|
||||
|
||||
public slots:
|
||||
void initClient();
|
||||
|
||||
private:
|
||||
Settings* set;
|
||||
QMutex m_mutex;
|
||||
|
||||
QList<QUdpSocket *> clientConnections;
|
||||
QString m_message;
|
||||
QByteArray m_datagram;
|
||||
|
||||
THPSDRParameter *io;
|
||||
|
||||
int m_client;
|
||||
|
||||
private slots:
|
||||
void displayAudioRcvrSocketError(QAbstractSocket::SocketError error);
|
||||
void readPendingAudioRcvrData();
|
||||
|
||||
signals:
|
||||
void messageEvent(QString message);
|
||||
void rcveIQEvent(QObject *sender, int value);
|
||||
void outputBufferEvent(unsigned char* outbuffer);
|
||||
void clientConnectedEvent(bool value);
|
||||
void newData();
|
||||
void newAudioData();
|
||||
};
|
||||
|
||||
#endif // _CUSDR_AUDIORECEIVER_H
|
||||