summaryrefslogtreecommitdiffstats
path: root/examples/multimedia
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@digia.com>2012-12-05 13:03:09 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-12-05 18:20:35 +0100
commit6b4994c265889db2058b7d5850b51ddfc5478754 (patch)
tree623e53eb8004b6b8ecdb7e2867ab489dde606fac /examples/multimedia
parent90c8ba233b77ed74012de3b5598a7617672e9d31 (diff)
centralize and fixup example sources install targets
This follows suit with aeb036e in qtbase. Change-Id: Ie8580d0a1f38ab9858b0e44c9f99bdc552a1752a Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com> Reviewed-by: hjk <qthjk@ovi.com>
Diffstat (limited to 'examples/multimedia')
-rw-r--r--examples/multimedia/audiodecoder/audiodecoder.cpp188
-rw-r--r--examples/multimedia/audiodecoder/audiodecoder.h92
-rw-r--r--examples/multimedia/audiodecoder/audiodecoder.pro17
-rw-r--r--examples/multimedia/audiodecoder/main.cpp94
-rw-r--r--examples/multimedia/audiodecoder/wavefilewriter.cpp192
-rw-r--r--examples/multimedia/audiodecoder/wavefilewriter.h70
-rw-r--r--examples/multimedia/audiodevices/audiodevices.cpp311
-rw-r--r--examples/multimedia/audiodevices/audiodevices.h84
-rw-r--r--examples/multimedia/audiodevices/audiodevices.pro16
-rw-r--r--examples/multimedia/audiodevices/audiodevicesbase.ui390
-rw-r--r--examples/multimedia/audiodevices/doc/images/audiodevices.pngbin0 -> 37896 bytes
-rw-r--r--examples/multimedia/audiodevices/doc/src/audiodevices.qdoc43
-rw-r--r--examples/multimedia/audiodevices/main.cpp54
-rw-r--r--examples/multimedia/audioengine/audioengine.pro6
-rw-r--r--examples/multimedia/audioengine/doc/src/audioengine.qdoc39
-rw-r--r--examples/multimedia/audioengine/qml/audioengine.qml193
-rw-r--r--examples/multimedia/audioengine/qml/audioengine.qmlproject16
-rw-r--r--examples/multimedia/audioengine/qml/content/MyAudioEngine.qml131
-rw-r--r--examples/multimedia/audioinput/audioinput.cpp405
-rw-r--r--examples/multimedia/audioinput/audioinput.h138
-rw-r--r--examples/multimedia/audioinput/audioinput.pro12
-rw-r--r--examples/multimedia/audioinput/doc/images/audioinput-example.pngbin0 -> 10383 bytes
-rw-r--r--examples/multimedia/audioinput/doc/src/audioinput.qdoc43
-rw-r--r--examples/multimedia/audioinput/main.cpp54
-rw-r--r--examples/multimedia/audiooutput/audiooutput.cpp334
-rw-r--r--examples/multimedia/audiooutput/audiooutput.h122
-rw-r--r--examples/multimedia/audiooutput/audiooutput.pro12
-rwxr-xr-xexamples/multimedia/audiooutput/doc/images/audiooutput-example.pngbin0 -> 11966 bytes
-rw-r--r--examples/multimedia/audiooutput/doc/src/audiooutput.qdoc43
-rw-r--r--examples/multimedia/audiooutput/main.cpp54
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.cpp319
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.h85
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.pro26
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.ui261
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder_small.ui266
-rw-r--r--examples/multimedia/audiorecorder/doc/images/audiorecorder.pngbin0 -> 28212 bytes
-rw-r--r--examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc104
-rw-r--r--examples/multimedia/audiorecorder/main.cpp53
-rw-r--r--examples/multimedia/audiorecorder/qaudiolevel.cpp68
-rw-r--r--examples/multimedia/audiorecorder/qaudiolevel.h62
-rw-r--r--examples/multimedia/declarative-radio/declarative-radio.pro9
-rw-r--r--examples/multimedia/declarative-radio/declarative-radio.qrc6
-rw-r--r--examples/multimedia/declarative-radio/doc/images/declarative-radio-example.pngbin0 -> 16734 bytes
-rw-r--r--examples/multimedia/declarative-radio/doc/src/declarative-radio.qdoc35
-rw-r--r--examples/multimedia/declarative-radio/main.cpp58
-rw-r--r--examples/multimedia/declarative-radio/view.qml191
-rw-r--r--examples/multimedia/multimedia.pro25
-rw-r--r--examples/multimedia/radio/main.cpp53
-rw-r--r--examples/multimedia/radio/radio.cpp158
-rw-r--r--examples/multimedia/radio/radio.h75
-rw-r--r--examples/multimedia/radio/radio.pro16
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/Array.h97
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/Array.hpp98
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/DynArray.h100
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/DynArray.hpp143
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.dsp273
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.dsw29
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.h142
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.hpp916
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLen.h130
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp322
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h93
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassDirect.h96
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp204
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassInverse.h101
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp229
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTRealSelect.h77
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTRealSelect.hpp62
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h101
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp91
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/OscSinCos.h106
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/OscSinCos.hpp122
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/TestAccuracy.h105
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/TestAccuracy.hpp472
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/TestHelperFixLen.h93
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp93
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/TestHelperNormal.h94
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/TestHelperNormal.hpp99
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/TestSpeed.h95
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/TestSpeed.hpp223
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h95
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp91
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/bwins/fftrealu.def5
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/def.h60
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/eabi/fftrealu.def7
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/fftreal.pas661
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/fftreal.pro44
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp54
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/fftreal_wrapper.h63
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/license.txt459
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/readme.txt242
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.cpp285
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.h124
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.hpp150
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/Int64.h71
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.cpp101
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.h110
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.hpp83
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/def.h65
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/fnc.h67
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/fnc.hpp85
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/test.cpp267
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/test_fnc.h53
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/test_fnc.hpp56
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/test_settings.h45
-rw-r--r--examples/multimedia/spectrum/3rdparty/fftreal/testapp.dpr150
-rw-r--r--examples/multimedia/spectrum/README.txt103
-rw-r--r--examples/multimedia/spectrum/TODO.txt34
-rw-r--r--examples/multimedia/spectrum/app/.gitignore2
-rw-r--r--examples/multimedia/spectrum/app/app.pro85
-rw-r--r--examples/multimedia/spectrum/app/engine.cpp754
-rw-r--r--examples/multimedia/spectrum/app/engine.h315
-rw-r--r--examples/multimedia/spectrum/app/frequencyspectrum.cpp89
-rw-r--r--examples/multimedia/spectrum/app/frequencyspectrum.h98
-rw-r--r--examples/multimedia/spectrum/app/images/record.pngbin0 -> 670 bytes
-rw-r--r--examples/multimedia/spectrum/app/images/settings.pngbin0 -> 3649 bytes
-rw-r--r--examples/multimedia/spectrum/app/levelmeter.cpp142
-rw-r--r--examples/multimedia/spectrum/app/levelmeter.h118
-rw-r--r--examples/multimedia/spectrum/app/main.cpp53
-rw-r--r--examples/multimedia/spectrum/app/mainwidget.cpp447
-rw-r--r--examples/multimedia/spectrum/app/mainwidget.h147
-rw-r--r--examples/multimedia/spectrum/app/progressbar.cpp140
-rw-r--r--examples/multimedia/spectrum/app/progressbar.h75
-rw-r--r--examples/multimedia/spectrum/app/settingsdialog.cpp148
-rw-r--r--examples/multimedia/spectrum/app/settingsdialog.h89
-rw-r--r--examples/multimedia/spectrum/app/spectrograph.cpp241
-rw-r--r--examples/multimedia/spectrum/app/spectrograph.h98
-rw-r--r--examples/multimedia/spectrum/app/spectrum.h146
-rw-r--r--examples/multimedia/spectrum/app/spectrum.qrc7
-rw-r--r--examples/multimedia/spectrum/app/spectrumanalyser.cpp276
-rw-r--r--examples/multimedia/spectrum/app/spectrumanalyser.h196
-rw-r--r--examples/multimedia/spectrum/app/tonegenerator.cpp90
-rw-r--r--examples/multimedia/spectrum/app/tonegenerator.h58
-rw-r--r--examples/multimedia/spectrum/app/tonegeneratordialog.cpp144
-rw-r--r--examples/multimedia/spectrum/app/tonegeneratordialog.h84
-rw-r--r--examples/multimedia/spectrum/app/utils.cpp139
-rw-r--r--examples/multimedia/spectrum/app/utils.h112
-rw-r--r--examples/multimedia/spectrum/app/waveform.cpp437
-rw-r--r--examples/multimedia/spectrum/app/waveform.h202
-rw-r--r--examples/multimedia/spectrum/app/wavfile.cpp151
-rw-r--r--examples/multimedia/spectrum/app/wavfile.h66
-rw-r--r--examples/multimedia/spectrum/doc/images/spectrum-demo.pngbin0 -> 10500 bytes
-rw-r--r--examples/multimedia/spectrum/doc/src/spectrum.qdoc64
-rw-r--r--examples/multimedia/spectrum/spectrum.pri49
-rw-r--r--examples/multimedia/spectrum/spectrum.pro13
-rw-r--r--examples/multimedia/video/doc/images/qmlvideo-menu.pngbin0 -> 64550 bytes
-rw-r--r--examples/multimedia/video/doc/images/qmlvideo-overlay.pngbin0 -> 65432 bytes
-rw-r--r--examples/multimedia/video/doc/images/qmlvideofx-camera-glow.pngbin0 -> 250540 bytes
-rw-r--r--examples/multimedia/video/doc/images/qmlvideofx-camera-magnify.pngbin0 -> 204923 bytes
-rw-r--r--examples/multimedia/video/doc/images/qmlvideofx-effects-menu.pngbin0 -> 171257 bytes
-rw-r--r--examples/multimedia/video/doc/images/qmlvideofx-source-menu.pngbin0 -> 257292 bytes
-rw-r--r--examples/multimedia/video/doc/images/qmlvideofx-video-edgedetection.pngbin0 -> 279883 bytes
-rw-r--r--examples/multimedia/video/doc/images/qmlvideofx-video-pagecurl.pngbin0 -> 220606 bytes
-rw-r--r--examples/multimedia/video/doc/images/video-qml-paint-rate.pngbin0 -> 6350 bytes
-rw-r--r--examples/multimedia/video/doc/src/qmlvideo.qdoc148
-rw-r--r--examples/multimedia/video/doc/src/qmlvideofx.qdoc223
-rw-r--r--examples/multimedia/video/doc/src/video-qml-paint-rate.qdocinc43
-rw-r--r--examples/multimedia/video/qmlvideo/images/close.pngbin0 -> 1799 bytes
-rw-r--r--examples/multimedia/video/qmlvideo/images/folder.pngbin0 -> 1841 bytes
-rw-r--r--examples/multimedia/video/qmlvideo/images/leaves.jpgbin0 -> 257378 bytes
-rw-r--r--examples/multimedia/video/qmlvideo/images/progress_handle.svg35
-rw-r--r--examples/multimedia/video/qmlvideo/images/progress_handle_pressed.svg35
-rw-r--r--examples/multimedia/video/qmlvideo/images/titlebar.pngbin0 -> 1436 bytes
-rw-r--r--examples/multimedia/video/qmlvideo/images/titlebar.sci5
-rw-r--r--examples/multimedia/video/qmlvideo/images/up.pngbin0 -> 662 bytes
-rw-r--r--examples/multimedia/video/qmlvideo/main.cpp141
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/Button.qml80
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraBasic.qml47
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraDrag.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraDummy.qml69
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraFullScreen.qml47
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraFullScreenInverted.qml47
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraItem.qml68
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraMove.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraOverlay.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraResize.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraRotate.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraSpin.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/Content.qml164
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml49
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/ErrorDialog.qml107
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/FileBrowser.qml383
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/Scene.qml71
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml87
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneDrag.qml72
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreen.qml104
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreenInverted.qml109
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMove.qml87
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMulti.qml204
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneOverlay.qml121
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneResize.qml79
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneRotate.qml100
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSelectionPanel.qml113
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSpin.qml72
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/SeekControl.qml143
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoBasic.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoDrag.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoDummy.qml75
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFillMode.qml86
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFullScreen.qml47
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFullScreenInverted.qml47
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoItem.qml77
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMetadata.qml122
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMove.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoOverlay.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoPlaybackRate.qml106
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoResize.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoRotate.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSeek.qml72
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSpin.qml46
-rw-r--r--examples/multimedia/video/qmlvideo/qml/qmlvideo/main.qml244
-rw-r--r--examples/multimedia/video/qmlvideo/qmlapplicationviewer/qmlapplicationviewer.cpp129
-rw-r--r--examples/multimedia/video/qmlvideo/qmlapplicationviewer/qmlapplicationviewer.h70
-rw-r--r--examples/multimedia/video/qmlvideo/qmlapplicationviewer/qmlapplicationviewer.pri5
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo.pngbin0 -> 3400 bytes
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo.pro18
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo.qrc12
-rw-r--r--examples/multimedia/video/qmlvideo/qmlvideo.svg93
-rw-r--r--examples/multimedia/video/qmlvideo/trace.h95
-rw-r--r--examples/multimedia/video/qmlvideofx/filereader.cpp80
-rw-r--r--examples/multimedia/video/qmlvideofx/filereader.h50
-rw-r--r--examples/multimedia/video/qmlvideofx/images/close.pngbin0 -> 1799 bytes
-rw-r--r--examples/multimedia/video/qmlvideofx/images/folder.pngbin0 -> 1841 bytes
-rw-r--r--examples/multimedia/video/qmlvideofx/images/qt-logo.pngbin0 -> 13923 bytes
-rw-r--r--examples/multimedia/video/qmlvideofx/images/titlebar.pngbin0 -> 1436 bytes
-rw-r--r--examples/multimedia/video/qmlvideofx/images/titlebar.sci5
-rw-r--r--examples/multimedia/video/qmlvideofx/images/up.pngbin0 -> 662 bytes
-rw-r--r--examples/multimedia/video/qmlvideofx/main.cpp151
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Button.qml80
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml163
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentCamera.qml51
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentImage.qml47
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentVideo.qml58
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml50
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Divider.qml73
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Effect.qml75
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBillboard.qml59
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBlackAndWhite.qml56
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectEmboss.qml46
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGaussianBlur.qml85
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGlow.qml46
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectIsolate.qml61
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml93
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml57
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPassThrough.qml46
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml56
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPosterize.qml58
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml64
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionPanel.qml154
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSepia.qml46
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSharpen.qml56
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectShockwave.qml80
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection1.qml59
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection2.qml56
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectTiltShift.qml46
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectToon.qml63
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectVignette.qml46
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectWarhol.qml46
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectWobble.qml61
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml384
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileOpen.qml94
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/HintedMouseArea.qml113
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ParameterPanel.qml109
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Slider.qml129
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-largescreen.qml186
-rw-r--r--examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-smallscreen.qml408
-rw-r--r--examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.cpp129
-rw-r--r--examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.h70
-rw-r--r--examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.pri7
-rw-r--r--examples/multimedia/video/qmlvideofx/qmlvideofx.pngbin0 -> 3400 bytes
-rw-r--r--examples/multimedia/video/qmlvideofx/qmlvideofx.pro23
-rw-r--r--examples/multimedia/video/qmlvideofx/qmlvideofx.qrc10
-rw-r--r--examples/multimedia/video/qmlvideofx/qmlvideofx.svg93
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/billboard.fsh74
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/blackandwhite.fsh62
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/emboss.fsh71
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/gaussianblur_h.fsh67
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/gaussianblur_v.fsh68
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/glow.fsh72
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/isolate.fsh88
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/magnify.fsh68
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/pagecurl.fsh183
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/pixelate.fsh64
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/posterize.fsh68
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/ripple.fsh78
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/selectionpanel.fsh41
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/sepia.fsh59
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/sharpen.fsh75
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/shockwave.fsh73
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/sobeledgedetection1.fsh83
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/sobeledgedetection2.fsh77
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/tiltshift.fsh75
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/toon.fsh92
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/vignette.fsh64
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/warhol.fsh66
-rw-r--r--examples/multimedia/video/qmlvideofx/shaders/wobble.fsh62
-rw-r--r--examples/multimedia/video/qmlvideofx/trace.h96
-rw-r--r--examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp250
-rw-r--r--examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.h101
-rw-r--r--examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.pri5
-rw-r--r--examples/multimedia/video/snippets/frequencymonitor/frequencymonitordeclarative.cpp48
-rw-r--r--examples/multimedia/video/snippets/frequencymonitor/frequencymonitordeclarative.pri3
-rw-r--r--examples/multimedia/video/snippets/frequencymonitor/qml/frequencymonitor/FrequencyItem.qml105
-rw-r--r--examples/multimedia/video/snippets/performancemonitor/performancemonitor.cpp69
-rw-r--r--examples/multimedia/video/snippets/performancemonitor/performancemonitor.h65
-rw-r--r--examples/multimedia/video/snippets/performancemonitor/performancemonitor.pri5
-rw-r--r--examples/multimedia/video/snippets/performancemonitor/performancemonitordeclarative.cpp51
-rw-r--r--examples/multimedia/video/snippets/performancemonitor/performancemonitordeclarative.h51
-rw-r--r--examples/multimedia/video/snippets/performancemonitor/performancemonitordeclarative.pri5
-rw-r--r--examples/multimedia/video/snippets/performancemonitor/qml/performancemonitor/PerformanceItem.qml141
-rw-r--r--examples/multimedia/video/video.pro4
311 files changed, 30490 insertions, 0 deletions
diff --git a/examples/multimedia/audiodecoder/audiodecoder.cpp b/examples/multimedia/audiodecoder/audiodecoder.cpp
new file mode 100644
index 000000000..1505a881e
--- /dev/null
+++ b/examples/multimedia/audiodecoder/audiodecoder.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "audiodecoder.h"
+#include <stdio.h>
+
+AudioDecoder::AudioDecoder(bool isPlayback, bool isDelete)
+ : m_cout(stdout, QIODevice::WriteOnly)
+{
+ m_isPlayback = isPlayback;
+ m_isDelete = isDelete;
+
+ // Make sure the data we receive is in correct PCM format.
+ // Our wav file writer only supports SignedInt sample type.
+ QAudioFormat format;
+ format.setChannelCount(2);
+ format.setSampleSize(16);
+ format.setSampleRate(48000);
+ format.setCodec("audio/pcm");
+ format.setSampleType(QAudioFormat::SignedInt);
+ m_decoder.setAudioFormat(format);
+
+ connect(&m_decoder, SIGNAL(bufferReady()), this, SLOT(bufferReady()));
+ connect(&m_decoder, SIGNAL(error(QAudioDecoder::Error)), this, SLOT(error(QAudioDecoder::Error)));
+ connect(&m_decoder, SIGNAL(stateChanged(QAudioDecoder::State)), this, SLOT(stateChanged(QAudioDecoder::State)));
+ connect(&m_decoder, SIGNAL(finished()), this, SLOT(finished()));
+ connect(&m_decoder, SIGNAL(positionChanged(qint64)), this, SLOT(updateProgress()));
+ connect(&m_decoder, SIGNAL(durationChanged(qint64)), this, SLOT(updateProgress()));
+
+ connect(&m_soundEffect, SIGNAL(statusChanged()), this, SLOT(playbackStatusChanged()));
+ connect(&m_soundEffect, SIGNAL(playingChanged()), this, SLOT(playingChanged()));
+
+ m_progress = -1.0;
+}
+
+void AudioDecoder::setSourceFilename(const QString &fileName)
+{
+ m_decoder.setSourceFilename(fileName);
+}
+
+void AudioDecoder::start()
+{
+ m_decoder.start();
+}
+
+void AudioDecoder::stop()
+{
+ m_decoder.stop();
+}
+
+void AudioDecoder::setTargetFilename(const QString &fileName)
+{
+ m_targetFilename = fileName;
+}
+
+void AudioDecoder::bufferReady()
+{
+ // read a buffer from audio decoder
+ QAudioBuffer buffer = m_decoder.read();
+ if (!buffer.isValid())
+ return;
+
+ if (!m_fileWriter.isOpen() && !m_fileWriter.open(m_targetFilename, buffer.format())) {
+ m_decoder.stop();
+ return;
+ }
+
+ m_fileWriter.write(buffer);
+}
+
+void AudioDecoder::error(QAudioDecoder::Error error)
+{
+ switch (error) {
+ case QAudioDecoder::NoError:
+ return;
+ case QAudioDecoder::ResourceError:
+ m_cout << "Resource error" << endl;
+ break;
+ case QAudioDecoder::FormatError:
+ m_cout << "Format error" << endl;
+ break;
+ case QAudioDecoder::AccessDeniedError:
+ m_cout << "Access denied error" << endl;
+ break;
+ case QAudioDecoder::ServiceMissingError:
+ m_cout << "Service missing error" << endl;
+ break;
+ }
+
+ emit done();
+}
+
+void AudioDecoder::stateChanged(QAudioDecoder::State newState)
+{
+ switch (newState) {
+ case QAudioDecoder::DecodingState:
+ m_cout << "Decoding..." << endl;
+ break;
+ case QAudioDecoder::StoppedState:
+ m_cout << "Decoding stopped" << endl;
+ break;
+ }
+}
+
+void AudioDecoder::finished()
+{
+ if (!m_fileWriter.close())
+ m_cout << "Failed to finilize output file" << endl;
+
+ m_cout << "Decoding finished" << endl;
+
+ if (m_isPlayback) {
+ m_cout << "Starting playback" << endl;
+ m_soundEffect.setSource(QUrl::fromLocalFile(m_targetFilename));
+ m_soundEffect.play();
+ } else {
+ emit done();
+ }
+}
+
+void AudioDecoder::playbackStatusChanged()
+{
+ if (m_soundEffect.status() == QSoundEffect::Error) {
+ m_cout << "Playback error" << endl;
+ emit done();
+ }
+}
+
+void AudioDecoder::playingChanged()
+{
+ if (!m_soundEffect.isPlaying()) {
+ m_cout << "Playback finished" << endl;
+ if (m_isDelete)
+ QFile::remove(m_targetFilename);
+ emit done();
+ }
+}
+
+void AudioDecoder::updateProgress()
+{
+ qint64 position = m_decoder.position();
+ qint64 duration = m_decoder.duration();
+ qreal progress = m_progress;
+ if (position >= 0 && duration > 0)
+ progress = position / (qreal)duration;
+
+ if (progress > m_progress + 0.1) {
+ m_cout << "Decoding progress: " << (int)(progress * 100.0) << "%" << endl;
+ m_progress = progress;
+ }
+}
diff --git a/examples/multimedia/audiodecoder/audiodecoder.h b/examples/multimedia/audiodecoder/audiodecoder.h
new file mode 100644
index 000000000..210142de1
--- /dev/null
+++ b/examples/multimedia/audiodecoder/audiodecoder.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 AUDIODECODER_H
+#define AUDIODECODER_H
+
+#include "wavefilewriter.h"
+
+#include <QAudioDecoder>
+#include <QSoundEffect>
+#include <QTextStream>
+
+class AudioDecoder : public QObject
+{
+ Q_OBJECT
+
+public:
+ AudioDecoder(bool isPlayback, bool isDelete);
+ ~AudioDecoder() { }
+
+ void setSourceFilename(const QString &fileName);
+ void start();
+ void stop();
+
+ void setTargetFilename(const QString &fileName);
+
+signals:
+ void done();
+
+public slots:
+ void bufferReady();
+ void error(QAudioDecoder::Error error);
+ void stateChanged(QAudioDecoder::State newState);
+ void finished();
+
+ void playbackStatusChanged();
+ void playingChanged();
+
+private slots:
+ void updateProgress();
+
+private:
+ bool m_isPlayback;
+ bool m_isDelete;
+ QAudioDecoder m_decoder;
+ QTextStream m_cout;
+
+ QString m_targetFilename;
+ WaveFileWriter m_fileWriter;
+ QSoundEffect m_soundEffect;
+
+ qreal m_progress;
+};
+
+#endif // AUDIODECODER_H
diff --git a/examples/multimedia/audiodecoder/audiodecoder.pro b/examples/multimedia/audiodecoder/audiodecoder.pro
new file mode 100644
index 000000000..0a09c3cf3
--- /dev/null
+++ b/examples/multimedia/audiodecoder/audiodecoder.pro
@@ -0,0 +1,17 @@
+TEMPLATE = app
+TARGET = audiodecoder
+
+CONFIG += qt warn_on
+
+HEADERS = \
+ audiodecoder.h \
+ wavefilewriter.h
+SOURCES = main.cpp \
+ audiodecoder.cpp \
+ wavefilewriter.cpp
+
+QT += multimedia
+CONFIG += console
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audiodecoder
+INSTALLS += target
diff --git a/examples/multimedia/audiodecoder/main.cpp b/examples/multimedia/audiodecoder/main.cpp
new file mode 100644
index 000000000..fabdae9f6
--- /dev/null
+++ b/examples/multimedia/audiodecoder/main.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "audiodecoder.h"
+
+#include <QCoreApplication>
+#include <QDir>
+#include <QFileInfo>
+#include <QTextStream>
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ QTextStream cout(stdout, QIODevice::WriteOnly);
+ if (app.arguments().size() < 2) {
+ cout << "Usage: audiodecoder [-p] [-pd] SOURCEFILE [TARGETFILE]" << endl;
+ cout << "Set -p option if you want to play output file." << endl;
+ cout << "Set -pd option if you want to play output file and delete it after successful playback." << endl;
+ cout << "Default TARGETFILE name is \"out.wav\" in the same directory as the source file." << endl;
+ return 0;
+ }
+
+ bool isPlayback = false;
+ bool isDelete = false;
+
+ if (app.arguments().at(1) == "-p")
+ isPlayback = true;
+ else if (app.arguments().at(1) == "-pd") {
+ isPlayback = true;
+ isDelete = true;
+ }
+
+ QFileInfo sourceFile;
+ QFileInfo targetFile;
+
+ int sourceFileIndex = (isPlayback || isDelete) ? 2 : 1;
+ if (app.arguments().size() <= sourceFileIndex) {
+ cout << "Error: source filename is not specified." << endl;
+ return 0;
+ }
+ sourceFile.setFile(app.arguments().at(sourceFileIndex));
+ if (app.arguments().size() > sourceFileIndex + 1)
+ targetFile.setFile(app.arguments().at(sourceFileIndex + 1));
+ else
+ targetFile.setFile(sourceFile.dir().absoluteFilePath("out.wav"));
+
+ AudioDecoder decoder(isPlayback, isDelete);
+ QObject::connect(&decoder, SIGNAL(done()), &app, SLOT(quit()));
+ decoder.setSourceFilename(sourceFile.absoluteFilePath());
+ decoder.setTargetFilename(targetFile.absoluteFilePath());
+ decoder.start();
+
+ return app.exec();
+}
diff --git a/examples/multimedia/audiodecoder/wavefilewriter.cpp b/examples/multimedia/audiodecoder/wavefilewriter.cpp
new file mode 100644
index 000000000..e13476ddd
--- /dev/null
+++ b/examples/multimedia/audiodecoder/wavefilewriter.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "wavefilewriter.h"
+
+struct Q_PACKED chunk
+{
+ char id[4];
+ quint32 size;
+};
+
+struct Q_PACKED RIFFHeader
+{
+ chunk descriptor; // "RIFF"
+ char type[4]; // "WAVE"
+};
+
+struct Q_PACKED WAVEHeader
+{
+ chunk descriptor;
+ quint16 audioFormat;
+ quint16 numChannels;
+ quint32 sampleRate;
+ quint32 byteRate;
+ quint16 blockAlign;
+ quint16 bitsPerSample;
+};
+
+struct Q_PACKED DATAHeader
+{
+ chunk descriptor;
+};
+
+struct Q_PACKED CombinedHeader
+{
+ RIFFHeader riff;
+ WAVEHeader wave;
+ DATAHeader data;
+};
+static const int HeaderLength = sizeof(CombinedHeader);
+
+
+WaveFileWriter::WaveFileWriter(QObject *parent)
+ : QObject(parent)
+ , m_dataLength(0)
+{
+}
+
+WaveFileWriter::~WaveFileWriter()
+{
+ close();
+}
+
+bool WaveFileWriter::open(const QString& fileName, const QAudioFormat& format)
+{
+ if (file.isOpen())
+ return false; // file already open
+
+ if (format.codec() != "audio/pcm" || format.sampleType() != QAudioFormat::SignedInt)
+ return false; // data format is not supported
+
+ file.setFileName(fileName);
+ if (!file.open(QIODevice::WriteOnly))
+ return false; // unable to open file for writing
+
+ if (!writeHeader(format))
+ return false;
+
+ m_format = format;
+ return true;
+}
+
+bool WaveFileWriter::write(const QAudioBuffer &buffer)
+{
+ if (buffer.format() != m_format)
+ return false; // buffer format has changed
+
+ qint64 written = file.write((const char *)buffer.constData(), buffer.byteCount());
+ m_dataLength += written;
+ return written == buffer.byteCount();
+}
+
+bool WaveFileWriter::close()
+{
+ bool result = false;
+ if (file.isOpen()) {
+ Q_ASSERT(m_dataLength < INT_MAX);
+ result = writeDataLength();
+
+ m_dataLength = 0;
+ file.close();
+ }
+ return result;
+}
+
+bool WaveFileWriter::writeHeader(const QAudioFormat &format)
+{
+ // check if format is supported
+ if (format.byteOrder() == QAudioFormat::BigEndian || format.sampleType() != QAudioFormat::SignedInt)
+ return false;
+
+ CombinedHeader header;
+ memset(&header, 0, HeaderLength);
+
+#ifndef Q_LITTLE_ENDIAN
+ // only implemented for LITTLE ENDIAN
+ return false;
+#else
+ // RIFF header
+ memcpy(header.riff.descriptor.id, "RIFF", 4);
+ header.riff.descriptor.size = 0; // this will be updated with correct duration:
+ // m_dataLength + HeaderLength - 8
+ // WAVE header
+ memcpy(header.riff.type, "WAVE", 4);
+ memcpy(header.wave.descriptor.id, "fmt ", 4);
+ header.wave.descriptor.size = quint32(16);
+ header.wave.audioFormat = quint16(1);
+ header.wave.numChannels = quint16(format.channelCount());
+ header.wave.sampleRate = quint32(format.sampleRate());
+ header.wave.byteRate = quint32(format.sampleRate() * format.channelCount() * format.sampleSize() / 8);
+ header.wave.blockAlign = quint16(format.channelCount() * format.sampleSize() / 8);
+ header.wave.bitsPerSample = quint16(format.sampleSize());
+
+ // DATA header
+ memcpy(header.data.descriptor.id,"data", 4);
+ header.data.descriptor.size = 0; // this will be updated with correct data length: m_dataLength
+
+ return (file.write(reinterpret_cast<const char *>(&header), HeaderLength) == HeaderLength);
+#endif
+}
+
+bool WaveFileWriter::writeDataLength()
+{
+#ifndef Q_LITTLE_ENDIAN
+ // only implemented for LITTLE ENDIAN
+ return false;
+#endif
+
+ if (file.isSequential())
+ return false;
+
+ // seek to RIFF header size, see header.riff.descriptor.size above
+ if (!file.seek(4))
+ return false;
+
+ quint32 length = m_dataLength + HeaderLength - 8;
+ if (file.write(reinterpret_cast<const char *>(&length), 4) != 4)
+ return false;
+
+ // seek to DATA header size, see header.data.descriptor.size above
+ if (!file.seek(40))
+ return false;
+
+ return file.write(reinterpret_cast<const char *>(&m_dataLength), 4) == 4;
+}
diff --git a/examples/multimedia/audiodecoder/wavefilewriter.h b/examples/multimedia/audiodecoder/wavefilewriter.h
new file mode 100644
index 000000000..180d34ee7
--- /dev/null
+++ b/examples/multimedia/audiodecoder/wavefilewriter.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 WAVEFILEWRITER_H
+#define WAVEFILEWRITER_H
+
+#include <QAudioBuffer>
+#include <QFile>
+#include <QObject>
+
+class WaveFileWriter : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit WaveFileWriter(QObject *parent = 0);
+ ~WaveFileWriter();
+
+ bool open(const QString &fileName, const QAudioFormat &format);
+ bool write(const QAudioBuffer &buffer);
+ bool close();
+ bool isOpen() const { return file.isOpen(); }
+
+private:
+ bool writeHeader(const QAudioFormat &format);
+ bool writeDataLength();
+
+ QFile file;
+ QAudioFormat m_format;
+ qint64 m_dataLength;
+};
+
+#endif // WAVEFILEWRITER_H
diff --git a/examples/multimedia/audiodevices/audiodevices.cpp b/examples/multimedia/audiodevices/audiodevices.cpp
new file mode 100644
index 000000000..2892e981f
--- /dev/null
+++ b/examples/multimedia/audiodevices/audiodevices.cpp
@@ -0,0 +1,311 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "audiodevices.h"
+
+// Utility functions for converting QAudioFormat fields into text
+
+static QString toString(QAudioFormat::SampleType sampleType)
+{
+ QString result("Unknown");
+ switch (sampleType) {
+ case QAudioFormat::SignedInt:
+ result = "SignedInt";
+ break;
+ case QAudioFormat::UnSignedInt:
+ result = "UnSignedInt";
+ break;
+ case QAudioFormat::Float:
+ result = "Float";
+ break;
+ case QAudioFormat::Unknown:
+ result = "Unknown";
+ }
+ return result;
+}
+
+static QString toString(QAudioFormat::Endian endian)
+{
+ QString result("Unknown");
+ switch (endian) {
+ case QAudioFormat::LittleEndian:
+ result = "LittleEndian";
+ break;
+ case QAudioFormat::BigEndian:
+ result = "BigEndian";
+ break;
+ }
+ return result;
+}
+
+
+AudioDevicesBase::AudioDevicesBase(QWidget *parent)
+ : QMainWindow(parent)
+{
+ setupUi(this);
+}
+
+AudioDevicesBase::~AudioDevicesBase() {}
+
+
+AudioTest::AudioTest(QWidget *parent)
+ : AudioDevicesBase(parent)
+{
+ mode = QAudio::AudioOutput;
+
+ connect(testButton, SIGNAL(clicked()), SLOT(test()));
+ connect(modeBox, SIGNAL(activated(int)), SLOT(modeChanged(int)));
+ connect(deviceBox, SIGNAL(activated(int)), SLOT(deviceChanged(int)));
+ connect(sampleRateBox, SIGNAL(activated(int)), SLOT(sampleRateChanged(int)));
+ connect(channelsBox, SIGNAL(activated(int)), SLOT(channelChanged(int)));
+ connect(codecsBox, SIGNAL(activated(int)), SLOT(codecChanged(int)));
+ connect(sampleSizesBox, SIGNAL(activated(int)), SLOT(sampleSizeChanged(int)));
+ connect(sampleTypesBox, SIGNAL(activated(int)), SLOT(sampleTypeChanged(int)));
+ connect(endianBox, SIGNAL(activated(int)), SLOT(endianChanged(int)));
+ connect(populateTableButton, SIGNAL(clicked()), SLOT(populateTable()));
+
+ modeBox->setCurrentIndex(0);
+ modeChanged(0);
+ deviceBox->setCurrentIndex(0);
+ deviceChanged(0);
+}
+
+AudioTest::~AudioTest()
+{
+}
+
+void AudioTest::test()
+{
+ // tries to set all the settings picked.
+ testResult->clear();
+
+ if (!deviceInfo.isNull()) {
+ if (deviceInfo.isFormatSupported(settings)) {
+ testResult->setText(tr("Success"));
+ nearestSampleRate->setText("");
+ nearestChannel->setText("");
+ nearestCodec->setText("");
+ nearestSampleSize->setText("");
+ nearestSampleType->setText("");
+ nearestEndian->setText("");
+ } else {
+ QAudioFormat nearest = deviceInfo.nearestFormat(settings);
+ testResult->setText(tr("Failed"));
+ nearestSampleRate->setText(QString("%1").arg(nearest.sampleRate()));
+ nearestChannel->setText(QString("%1").arg(nearest.channelCount()));
+ nearestCodec->setText(nearest.codec());
+ nearestSampleSize->setText(QString("%1").arg(nearest.sampleSize()));
+ nearestSampleType->setText(toString(nearest.sampleType()));
+ nearestEndian->setText(toString(nearest.byteOrder()));
+ }
+ }
+ else
+ testResult->setText(tr("No Device"));
+}
+
+void AudioTest::modeChanged(int idx)
+{
+ testResult->clear();
+
+ // mode has changed
+ if (idx == 0)
+ mode = QAudio::AudioInput;
+ else
+ mode = QAudio::AudioOutput;
+
+ deviceBox->clear();
+ foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(mode))
+ deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo));
+
+ deviceBox->setCurrentIndex(0);
+ deviceChanged(0);
+}
+
+void AudioTest::deviceChanged(int idx)
+{
+ testResult->clear();
+
+ if (deviceBox->count() == 0)
+ return;
+
+ // device has changed
+ deviceInfo = deviceBox->itemData(idx).value<QAudioDeviceInfo>();
+
+ sampleRateBox->clear();
+ QList<int> sampleRatez = deviceInfo.supportedSampleRates();
+ for (int i = 0; i < sampleRatez.size(); ++i)
+ sampleRateBox->addItem(QString("%1").arg(sampleRatez.at(i)));
+ if (sampleRatez.size())
+ settings.setSampleRate(sampleRatez.at(0));
+
+ channelsBox->clear();
+ QList<int> chz = deviceInfo.supportedChannelCounts();
+ for (int i = 0; i < chz.size(); ++i)
+ channelsBox->addItem(QString("%1").arg(chz.at(i)));
+ if (chz.size())
+ settings.setChannelCount(chz.at(0));
+
+ codecsBox->clear();
+ QStringList codecs = deviceInfo.supportedCodecs();
+ for (int i = 0; i < codecs.size(); ++i)
+ codecsBox->addItem(QString("%1").arg(codecs.at(i)));
+ if (codecs.size())
+ settings.setCodec(codecs.at(0));
+ // Add false to create failed condition!
+ codecsBox->addItem("audio/test");
+
+ sampleSizesBox->clear();
+ QList<int> sampleSizez = deviceInfo.supportedSampleSizes();
+ for (int i = 0; i < sampleSizez.size(); ++i)
+ sampleSizesBox->addItem(QString("%1").arg(sampleSizez.at(i)));
+ if (sampleSizez.size())
+ settings.setSampleSize(sampleSizez.at(0));
+
+ sampleTypesBox->clear();
+ QList<QAudioFormat::SampleType> sampleTypez = deviceInfo.supportedSampleTypes();
+
+ for (int i = 0; i < sampleTypez.size(); ++i)
+ sampleTypesBox->addItem(toString(sampleTypez.at(i)));
+ if (sampleTypez.size())
+ settings.setSampleType(sampleTypez.at(0));
+
+ endianBox->clear();
+ QList<QAudioFormat::Endian> endianz = deviceInfo.supportedByteOrders();
+ for (int i = 0; i < endianz.size(); ++i)
+ endianBox->addItem(toString(endianz.at(i)));
+ if (endianz.size())
+ settings.setByteOrder(endianz.at(0));
+
+ allFormatsTable->clearContents();
+}
+
+void AudioTest::populateTable()
+{
+ int row = 0;
+
+ QAudioFormat format;
+ foreach (QString codec, deviceInfo.supportedCodecs()) {
+ format.setCodec(codec);
+ foreach (int sampleRate, deviceInfo.supportedSampleRates()) {
+ format.setSampleRate(sampleRate);
+ foreach (int channels, deviceInfo.supportedChannelCounts()) {
+ format.setChannelCount(channels);
+ foreach (QAudioFormat::SampleType sampleType, deviceInfo.supportedSampleTypes()) {
+ format.setSampleType(sampleType);
+ foreach (int sampleSize, deviceInfo.supportedSampleSizes()) {
+ format.setSampleSize(sampleSize);
+ foreach (QAudioFormat::Endian endian, deviceInfo.supportedByteOrders()) {
+ format.setByteOrder(endian);
+ if (deviceInfo.isFormatSupported(format)) {
+ allFormatsTable->setRowCount(row + 1);
+
+ QTableWidgetItem *codecItem = new QTableWidgetItem(format.codec());
+ allFormatsTable->setItem(row, 0, codecItem);
+
+ QTableWidgetItem *sampleRateItem = new QTableWidgetItem(QString("%1").arg(format.sampleRate()));
+ allFormatsTable->setItem(row, 1, sampleRateItem);
+
+ QTableWidgetItem *channelsItem = new QTableWidgetItem(QString("%1").arg(format.channelCount()));
+ allFormatsTable->setItem(row, 2, channelsItem);
+
+ QTableWidgetItem *sampleTypeItem = new QTableWidgetItem(toString(format.sampleType()));
+ allFormatsTable->setItem(row, 3, sampleTypeItem);
+
+ QTableWidgetItem *sampleSizeItem = new QTableWidgetItem(QString("%1").arg(format.sampleSize()));
+ allFormatsTable->setItem(row, 4, sampleSizeItem);
+
+ QTableWidgetItem *byteOrderItem = new QTableWidgetItem(toString(format.byteOrder()));
+ allFormatsTable->setItem(row, 5, byteOrderItem);
+
+ ++row;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void AudioTest::sampleRateChanged(int idx)
+{
+ // sample rate has changed
+ settings.setSampleRate(sampleRateBox->itemText(idx).toInt());
+}
+
+void AudioTest::channelChanged(int idx)
+{
+ settings.setChannelCount(channelsBox->itemText(idx).toInt());
+}
+
+void AudioTest::codecChanged(int idx)
+{
+ settings.setCodec(codecsBox->itemText(idx));
+}
+
+void AudioTest::sampleSizeChanged(int idx)
+{
+ settings.setSampleSize(sampleSizesBox->itemText(idx).toInt());
+}
+
+void AudioTest::sampleTypeChanged(int idx)
+{
+ switch (sampleTypesBox->itemText(idx).toInt()) {
+ case QAudioFormat::SignedInt:
+ settings.setSampleType(QAudioFormat::SignedInt);
+ break;
+ case QAudioFormat::UnSignedInt:
+ settings.setSampleType(QAudioFormat::UnSignedInt);
+ break;
+ case QAudioFormat::Float:
+ settings.setSampleType(QAudioFormat::Float);
+ }
+}
+
+void AudioTest::endianChanged(int idx)
+{
+ switch (endianBox->itemText(idx).toInt()) {
+ case QAudioFormat::LittleEndian:
+ settings.setByteOrder(QAudioFormat::LittleEndian);
+ break;
+ case QAudioFormat::BigEndian:
+ settings.setByteOrder(QAudioFormat::BigEndian);
+ }
+}
diff --git a/examples/multimedia/audiodevices/audiodevices.h b/examples/multimedia/audiodevices/audiodevices.h
new file mode 100644
index 000000000..d1a1cd2cd
--- /dev/null
+++ b/examples/multimedia/audiodevices/audiodevices.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 AUDIODEVICES_H
+#define AUDIODEVICES_H
+
+#include <QAudioDeviceInfo>
+#include <QMainWindow>
+#include <QObject>
+
+#include "ui_audiodevicesbase.h"
+
+class AudioDevicesBase : public QMainWindow, public Ui::AudioDevicesBase
+{
+public:
+ AudioDevicesBase(QWidget *parent = 0);
+ virtual ~AudioDevicesBase();
+};
+
+class AudioTest : public AudioDevicesBase
+{
+ Q_OBJECT
+
+public:
+ AudioTest(QWidget *parent = 0);
+ virtual ~AudioTest();
+
+ QAudioDeviceInfo deviceInfo;
+ QAudioFormat settings;
+ QAudio::Mode mode;
+
+private slots:
+ void modeChanged(int idx);
+ void deviceChanged(int idx);
+ void sampleRateChanged(int idx);
+ void channelChanged(int idx);
+ void codecChanged(int idx);
+ void sampleSizeChanged(int idx);
+ void sampleTypeChanged(int idx);
+ void endianChanged(int idx);
+ void test();
+ void populateTable();
+
+};
+
+#endif
+
diff --git a/examples/multimedia/audiodevices/audiodevices.pro b/examples/multimedia/audiodevices/audiodevices.pro
new file mode 100644
index 000000000..71701543e
--- /dev/null
+++ b/examples/multimedia/audiodevices/audiodevices.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = audiodevices
+
+QT += multimedia
+
+HEADERS = audiodevices.h
+
+SOURCES = audiodevices.cpp \
+ main.cpp
+
+FORMS += audiodevicesbase.ui
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audiodevices
+INSTALLS += target
+
+QT+=widgets
diff --git a/examples/multimedia/audiodevices/audiodevicesbase.ui b/examples/multimedia/audiodevices/audiodevicesbase.ui
new file mode 100644
index 000000000..5a4ef2da3
--- /dev/null
+++ b/examples/multimedia/audiodevices/audiodevicesbase.ui
@@ -0,0 +1,390 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AudioDevicesBase</class>
+ <widget class="QMainWindow" name="AudioDevicesBase">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>679</width>
+ <height>598</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Audio Devices</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>659</width>
+ <height>558</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="modeLabel">
+ <property name="text">
+ <string>Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="deviceLabel">
+ <property name="text">
+ <string>Device</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QComboBox" name="modeBox">
+ <item>
+ <property name="text">
+ <string>Input</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Output</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="deviceBox"/>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="testFormatTab">
+ <attribute name="title">
+ <string>Test format</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="1">
+ <widget class="QLabel" name="actualLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Actual Settings&lt;/i&gt;</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="nearestLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text">
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Nearest Settings&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="sampleRateBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QLineEdit" name="nearestSampleRate">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QComboBox" name="channelsBox"/>
+ </item>
+ <item row="5" column="2">
+ <widget class="QLineEdit" name="nearestChannel">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="1">
+ <widget class="QComboBox" name="sampleSizesBox"/>
+ </item>
+ <item row="9" column="2">
+ <widget class="QLineEdit" name="nearestSampleSize">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="14" column="1">
+ <widget class="QComboBox" name="endianBox"/>
+ </item>
+ <item row="14" column="2">
+ <widget class="QLineEdit" name="nearestEndian">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="15" column="1">
+ <widget class="QPushButton" name="testButton">
+ <property name="text">
+ <string>Test</string>
+ </property>
+ </widget>
+ </item>
+ <item row="15" column="2">
+ <widget class="QLabel" name="testResult">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="actualFreqLabel">
+ <property name="text">
+ <string>Frequency (Hz)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="actualChannelLabel">
+ <property name="text">
+ <string>Channels</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QLabel" name="actualSampleSizeLabel">
+ <property name="text">
+ <string>Sample size (bits)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="14" column="0">
+ <widget class="QLabel" name="actualEndianLabel">
+ <property name="text">
+ <string>Endianess</string>
+ </property>
+ </widget>
+ </item>
+ <item row="16" column="0" colspan="3">
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Note: an invalid codec 'audio/test' exists in order to allow an invalid format to be constructed, and therefore to trigger a 'nearest format' calculation.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="actualCodecLabel">
+ <property name="text">
+ <string>Codec</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QLineEdit" name="nearestCodec">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="codecsBox"/>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="actualSampleTypeLabel">
+ <property name="text">
+ <string>SampleType</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QComboBox" name="sampleTypesBox"/>
+ </item>
+ <item row="6" column="2">
+ <widget class="QLineEdit" name="nearestSampleType">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>All formats</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QPushButton" name="populateTableButton">
+ <property name="text">
+ <string>Populate table</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTableWidget" name="allFormatsTable">
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="dragDropOverwriteMode">
+ <bool>false</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::NoSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectItems</enum>
+ </property>
+ <property name="textElideMode">
+ <enum>Qt::ElideNone</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <property name="cornerButtonEnabled">
+ <bool>false</bool>
+ </property>
+ <attribute name="horizontalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="verticalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Codec</string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignHCenter|AlignVCenter|AlignCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Frequency (Hz)</string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignHCenter|AlignVCenter|AlignCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Channels</string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignHCenter|AlignVCenter|AlignCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Sample type</string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignHCenter|AlignVCenter|AlignCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Sample size (bits)</string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignHCenter|AlignVCenter|AlignCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Endianness</string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignHCenter|AlignVCenter|AlignCenter</set>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/multimedia/audiodevices/doc/images/audiodevices.png b/examples/multimedia/audiodevices/doc/images/audiodevices.png
new file mode 100644
index 000000000..419b40f48
--- /dev/null
+++ b/examples/multimedia/audiodevices/doc/images/audiodevices.png
Binary files differ
diff --git a/examples/multimedia/audiodevices/doc/src/audiodevices.qdoc b/examples/multimedia/audiodevices/doc/src/audiodevices.qdoc
new file mode 100644
index 000000000..d2522f3ae
--- /dev/null
+++ b/examples/multimedia/audiodevices/doc/src/audiodevices.qdoc
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example audiodevices
+ \title Audio Devices Example
+ \ingroup audio_examples
+ \brief The Audio Devices example shows the application of the audio devices APIs
+
+
+ This example shows how to create a simple application to list and test
+ the configuration for the various audio devices available on the device
+ or machine. This is done using the QtMobility Multimedia API.
+
+ \image audiodevices.png
+
+*/
+
+
diff --git a/examples/multimedia/audiodevices/main.cpp b/examples/multimedia/audiodevices/main.cpp
new file mode 100644
index 000000000..525a8cca7
--- /dev/null
+++ b/examples/multimedia/audiodevices/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QtWidgets>
+
+#include "audiodevices.h"
+
+int main(int argv, char **args)
+{
+ QApplication app(argv, args);
+ app.setApplicationName("Audio Device Test");
+
+ AudioTest audio;
+ audio.show();
+
+ return app.exec();
+}
diff --git a/examples/multimedia/audioengine/audioengine.pro b/examples/multimedia/audioengine/audioengine.pro
new file mode 100644
index 000000000..84bc492bc
--- /dev/null
+++ b/examples/multimedia/audioengine/audioengine.pro
@@ -0,0 +1,6 @@
+TEMPLATE = subdirs
+
+# These examples contain no C++ and can simply be copied
+SUBDIRS =
+EXAMPLE_FILES = qml
+
diff --git a/examples/multimedia/audioengine/doc/src/audioengine.qdoc b/examples/multimedia/audioengine/doc/src/audioengine.qdoc
new file mode 100644
index 000000000..bea4d4b57
--- /dev/null
+++ b/examples/multimedia/audioengine/doc/src/audioengine.qdoc
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example audioengine
+ \title AudioEngine Example
+ \ingroup audioengine_examples
+ \brief The Audio Engine example demonstrates 3D sound control using
+ the QtAudioEngine API.
+
+ \image audioengine.png
+
+*/
+
+
diff --git a/examples/multimedia/audioengine/qml/audioengine.qml b/examples/multimedia/audioengine/qml/audioengine.qml
new file mode 100644
index 000000000..3e6fac03b
--- /dev/null
+++ b/examples/multimedia/audioengine/qml/audioengine.qml
@@ -0,0 +1,193 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+ ** Contact: http://www.qt-project.org/legal
+ **
+ ** 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 Digia Plc 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$
+ **
+ ****************************************************************************/
+
+import QtAudioEngine 1.0
+import QtQuick 2.0
+import "content"
+
+Rectangle {
+ color:"white"
+ id: root
+ width: 300
+ height: 500
+ property int radius : 100
+ property real twoPi : Math.PI + Math.PI
+
+ MyAudioEngine {
+ id:audioEngine
+ listener.position : Qt.vector3d(observer.x, observer.y, 0);
+ }
+
+ Item {
+ id: circle
+ x: root.width / 2
+ y: root.height / 2
+ property real percent: 0
+ SequentialAnimation on percent {
+ id: circleAnim1
+ loops: Animation.Infinite
+ running: true
+ NumberAnimation {
+ duration: 8000
+ from: 0
+ to: 1
+ }
+
+ }
+ }
+
+ Item {
+ id: holder
+ x: circle.x - Math.sin(circle.percent * root.twoPi) * root.radius - 50
+ y: circle.y + Math.cos(circle.percent * root.twoPi) * root.radius + 50
+ }
+
+ Rectangle {
+ color:"green"
+ id: observer
+ width: 16
+ height: 16
+ x: circle.x - width / 2
+ y: circle.y - height / 2
+ }
+ Rectangle {
+ color:"red"
+ id: starship
+ width: 32
+ height: 32
+ x: holder.x - width / 2
+ y: holder.y - height / 2
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ audioEngine.sounds["effects"].play(Qt.vector3d(holder.x, holder.y, 0));
+ }
+ }
+
+ SoundInstance {
+ id: shipSound
+ engine:audioEngine
+ sound:"shipengine"
+ position: Qt.vector3d(holder.x, holder.y, 0)
+ direction: {
+ var a = (starship.rotation / 360) * root.twoPi;
+ return Qt.vector3d(Math.sin(a), -Math.cos(a), 0);
+ }
+ velocity: {
+ var speed = root.twoPi * root.radius / 4;
+ return shipSound.direction * speed;
+ }
+
+ Component.onCompleted: shipSound.play()
+ }
+
+ //Category Volume Control
+ Rectangle {
+ property variant volumeCtrl: audioEngine.categories["sfx"];
+ id: volumeBar
+ x: 10
+ y: 10
+ width: 280
+ height: 22
+ color: "darkgray"
+ Rectangle {
+ id: volumeTracker
+ x: 0
+ y: 0
+ width: volumeBar.volumeCtrl.volume * parent.width;
+ height: parent.height
+ color: "lightgreen"
+ }
+ Text {
+ text: " volume:" + volumeBar.volumeCtrl.volume * 100 +"%";
+ font.pointSize: 16;
+ font.italic: true;
+ color: "black"
+ anchors.fill: parent
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ property bool m:false
+ onPressed: {
+ m = true;
+ updateVolume(mouse);
+ }
+ onReleased: {
+ m = false;
+ }
+
+ onPositionChanged: {
+ if (m) {
+ updateVolume(mouse);
+ }
+ }
+ function updateVolume(mouse) {
+ volumeBar.volumeCtrl.volume = Math.min(1, Math.max(0, mouse.x / (volumeBar.width - 1)));
+ }
+ }
+ }
+
+ //Information display
+ Item {
+ x:10
+ y:32
+ Text {
+ text: " [live instances] = " + audioEngine.liveInstances;
+ font.pointSize: 14;
+ font.italic: true;
+ color: "black"
+ anchors.fill: parent
+ }
+ }
+
+ Item {
+ x:10
+ y:60
+ Text {
+ text: " [loading]=" + (audioEngine.loading ? "true" : "false");
+ font.pointSize: 16;
+ font.italic: true;
+ color: "black"
+ anchors.fill: parent
+ }
+ }
+}
diff --git a/examples/multimedia/audioengine/qml/audioengine.qmlproject b/examples/multimedia/audioengine/qml/audioengine.qmlproject
new file mode 100644
index 000000000..15b002b1a
--- /dev/null
+++ b/examples/multimedia/audioengine/qml/audioengine.qmlproject
@@ -0,0 +1,16 @@
+import QmlProject 1.1
+
+Project {
+ mainFile: "audioengine.qml"
+
+ /* Include .qml, .js, and image files from current directory and subdirectories */
+ QmlFiles {
+ directory: "."
+ }
+ JavaScriptFiles {
+ directory: "."
+ }
+ ImageFiles {
+ directory: "."
+ }
+}
diff --git a/examples/multimedia/audioengine/qml/content/MyAudioEngine.qml b/examples/multimedia/audioengine/qml/content/MyAudioEngine.qml
new file mode 100644
index 000000000..229279b88
--- /dev/null
+++ b/examples/multimedia/audioengine/qml/content/MyAudioEngine.qml
@@ -0,0 +1,131 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+ ** Contact: http://www.qt-project.org/legal
+ **
+ ** 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 Digia Plc 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$
+ **
+ ****************************************************************************/
+
+import QtAudioEngine 1.0
+import QtQuick 2.0
+
+AudioEngine {
+
+ AudioCategory {
+ name:"sfx"
+ volume: 1
+ }
+
+ AudioCategory {
+ name:"music"
+ volume: 1
+ }
+
+
+ AttenuationModelInverse {
+ name:"default"
+ start: 20
+ end: 1000
+ rolloff: 1
+ }
+
+ AttenuationModelLinear {
+ name:"shipengine"
+ start: 20
+ end: 180
+ }
+
+ AudioSample {
+ name:"fire"
+ source: "fire-03-loop.wav"
+ preloaded:true
+ }
+
+ AudioSample {
+ name:"explosion"
+ source: "explosion-02.wav"
+ }
+ AudioSample {
+ name:"lava"
+ source: "lava-bubbling-01.wav"
+ }
+ AudioSample {
+ name:"water"
+ source: "running-water-01.wav"
+ }
+ Sound {
+ name:"shipengine"
+ attenuationModel:"shipengine"
+ category:"sfx"
+ PlayVariation {
+ looping:true
+ sample:"fire"
+ maxGain:0.9
+ minGain:0.8
+ }
+ }
+
+ Sound {
+ name:"effects"
+ category:"sfx"
+ PlayVariation {
+ sample:"lava"
+ maxGain:1.5
+ minGain:1.2
+ maxPitch:2.0
+ minPitch:0.5
+ }
+ PlayVariation {
+ sample:"explosion"
+ maxGain:1.1
+ minGain:0.7
+ maxPitch:1.5
+ minPitch:0.5
+ }
+ PlayVariation {
+ sample:"water"
+ maxGain:1.5
+ minGain:1.2
+ }
+ }
+
+ dopplerFactor: 1
+ speedOfSound: 343.33
+
+ listener.up:"0,0,1"
+ listener.position:"0,0,0"
+ listener.velocity:"0,0,0"
+ listener.direction:"0,1,0"
+}
diff --git a/examples/multimedia/audioinput/audioinput.cpp b/examples/multimedia/audioinput/audioinput.cpp
new file mode 100644
index 000000000..5aeb1a7a8
--- /dev/null
+++ b/examples/multimedia/audioinput/audioinput.cpp
@@ -0,0 +1,405 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <stdlib.h>
+#include <math.h>
+
+#include <QDateTime>
+#include <QDebug>
+#include <QPainter>
+#include <QVBoxLayout>
+#include <QAudioDeviceInfo>
+#include <QAudioInput>
+#include <qendian.h>
+
+#include "audioinput.h"
+
+#define PUSH_MODE_LABEL "Enable push mode"
+#define PULL_MODE_LABEL "Enable pull mode"
+#define SUSPEND_LABEL "Suspend recording"
+#define RESUME_LABEL "Resume recording"
+
+const int BufferSize = 4096;
+
+AudioInfo::AudioInfo(const QAudioFormat &format, QObject *parent)
+ : QIODevice(parent)
+ , m_format(format)
+ , m_maxAmplitude(0)
+ , m_level(0.0)
+
+{
+ switch (m_format.sampleSize()) {
+ case 8:
+ switch (m_format.sampleType()) {
+ case QAudioFormat::UnSignedInt:
+ m_maxAmplitude = 255;
+ break;
+ case QAudioFormat::SignedInt:
+ m_maxAmplitude = 127;
+ break;
+ default:
+ break;
+ }
+ break;
+ case 16:
+ switch (m_format.sampleType()) {
+ case QAudioFormat::UnSignedInt:
+ m_maxAmplitude = 65535;
+ break;
+ case QAudioFormat::SignedInt:
+ m_maxAmplitude = 32767;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case 32:
+ switch (m_format.sampleType()) {
+ case QAudioFormat::UnSignedInt:
+ m_maxAmplitude = 0xffffffff;
+ break;
+ case QAudioFormat::SignedInt:
+ m_maxAmplitude = 0x7fffffff;
+ break;
+ case QAudioFormat::Float:
+ m_maxAmplitude = 0x7fffffff; // Kind of
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+AudioInfo::~AudioInfo()
+{
+}
+
+void AudioInfo::start()
+{
+ open(QIODevice::WriteOnly);
+}
+
+void AudioInfo::stop()
+{
+ close();
+}
+
+qint64 AudioInfo::readData(char *data, qint64 maxlen)
+{
+ Q_UNUSED(data)
+ Q_UNUSED(maxlen)
+
+ return 0;
+}
+
+qint64 AudioInfo::writeData(const char *data, qint64 len)
+{
+ if (m_maxAmplitude) {
+ Q_ASSERT(m_format.sampleSize() % 8 == 0);
+ const int channelBytes = m_format.sampleSize() / 8;
+ const int sampleBytes = m_format.channelCount() * channelBytes;
+ Q_ASSERT(len % sampleBytes == 0);
+ const int numSamples = len / sampleBytes;
+
+ quint32 maxValue = 0;
+ const unsigned char *ptr = reinterpret_cast<const unsigned char *>(data);
+
+ for (int i = 0; i < numSamples; ++i) {
+ for (int j = 0; j < m_format.channelCount(); ++j) {
+ quint32 value = 0;
+
+ if (m_format.sampleSize() == 8 && m_format.sampleType() == QAudioFormat::UnSignedInt) {
+ value = *reinterpret_cast<const quint8*>(ptr);
+ } else if (m_format.sampleSize() == 8 && m_format.sampleType() == QAudioFormat::SignedInt) {
+ value = qAbs(*reinterpret_cast<const qint8*>(ptr));
+ } else if (m_format.sampleSize() == 16 && m_format.sampleType() == QAudioFormat::UnSignedInt) {
+ if (m_format.byteOrder() == QAudioFormat::LittleEndian)
+ value = qFromLittleEndian<quint16>(ptr);
+ else
+ value = qFromBigEndian<quint16>(ptr);
+ } else if (m_format.sampleSize() == 16 && m_format.sampleType() == QAudioFormat::SignedInt) {
+ if (m_format.byteOrder() == QAudioFormat::LittleEndian)
+ value = qAbs(qFromLittleEndian<qint16>(ptr));
+ else
+ value = qAbs(qFromBigEndian<qint16>(ptr));
+ } else if (m_format.sampleSize() == 32 && m_format.sampleType() == QAudioFormat::UnSignedInt) {
+ if (m_format.byteOrder() == QAudioFormat::LittleEndian)
+ value = qFromLittleEndian<quint32>(ptr);
+ else
+ value = qFromBigEndian<quint32>(ptr);
+ } else if (m_format.sampleSize() == 32 && m_format.sampleType() == QAudioFormat::SignedInt) {
+ if (m_format.byteOrder() == QAudioFormat::LittleEndian)
+ value = qAbs(qFromLittleEndian<qint32>(ptr));
+ else
+ value = qAbs(qFromBigEndian<qint32>(ptr));
+ } else if (m_format.sampleSize() == 32 && m_format.sampleType() == QAudioFormat::Float) {
+ value = qAbs(*reinterpret_cast<const float*>(ptr) * 0x7fffffff); // assumes 0-1.0
+ }
+
+ maxValue = qMax(value, maxValue);
+ ptr += channelBytes;
+ }
+ }
+
+ maxValue = qMin(maxValue, m_maxAmplitude);
+ m_level = qreal(maxValue) / m_maxAmplitude;
+ }
+
+ emit update();
+ return len;
+}
+
+RenderArea::RenderArea(QWidget *parent)
+ : QWidget(parent)
+{
+ setBackgroundRole(QPalette::Base);
+ setAutoFillBackground(true);
+
+ m_level = 0;
+ setMinimumHeight(30);
+ setMinimumWidth(200);
+}
+
+void RenderArea::paintEvent(QPaintEvent * /* event */)
+{
+ QPainter painter(this);
+
+ painter.setPen(Qt::black);
+ painter.drawRect(QRect(painter.viewport().left()+10,
+ painter.viewport().top()+10,
+ painter.viewport().right()-20,
+ painter.viewport().bottom()-20));
+ if (m_level == 0.0)
+ return;
+
+ int pos = ((painter.viewport().right()-20)-(painter.viewport().left()+11))*m_level;
+ painter.fillRect(painter.viewport().left()+11,
+ painter.viewport().top()+10,
+ pos,
+ painter.viewport().height()-21,
+ Qt::red);
+}
+
+void RenderArea::setLevel(qreal value)
+{
+ m_level = value;
+ update();
+}
+
+
+InputTest::InputTest()
+ : m_canvas(0)
+ , m_modeButton(0)
+ , m_suspendResumeButton(0)
+ , m_deviceBox(0)
+ , m_device(QAudioDeviceInfo::defaultInputDevice())
+ , m_audioInfo(0)
+ , m_audioInput(0)
+ , m_input(0)
+ , m_pullMode(false)
+ , m_buffer(BufferSize, 0)
+{
+ initializeWindow();
+ initializeAudio();
+}
+
+InputTest::~InputTest() {}
+
+void InputTest::initializeWindow()
+{
+ QScopedPointer<QWidget> window(new QWidget);
+ QScopedPointer<QVBoxLayout> layout(new QVBoxLayout);
+
+ m_canvas = new RenderArea(this);
+ layout->addWidget(m_canvas);
+
+ m_deviceBox = new QComboBox(this);
+ QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
+ for(int i = 0; i < devices.size(); ++i)
+ m_deviceBox->addItem(devices.at(i).deviceName(), qVariantFromValue(devices.at(i)));
+
+ connect(m_deviceBox, SIGNAL(activated(int)), SLOT(deviceChanged(int)));
+ layout->addWidget(m_deviceBox);
+
+ m_volumeSlider = new QSlider(Qt::Horizontal, this);
+ m_volumeSlider->setRange(0, 100);
+ m_volumeSlider->setValue(100);
+ connect(m_volumeSlider, SIGNAL(valueChanged(int)), SLOT(sliderChanged(int)));
+ layout->addWidget(m_volumeSlider);
+
+ m_modeButton = new QPushButton(this);
+ m_modeButton->setText(tr(PUSH_MODE_LABEL));
+ connect(m_modeButton, SIGNAL(clicked()), SLOT(toggleMode()));
+ layout->addWidget(m_modeButton);
+
+ m_suspendResumeButton = new QPushButton(this);
+ m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
+ connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspend()));
+ layout->addWidget(m_suspendResumeButton);
+
+ window->setLayout(layout.data());
+ layout.take(); // ownership transferred
+
+ setCentralWidget(window.data());
+ QWidget *const windowPtr = window.take(); // ownership transferred
+ windowPtr->show();
+}
+
+void InputTest::initializeAudio()
+{
+ m_pullMode = true;
+
+ m_format.setSampleRate(8000);
+ m_format.setChannelCount(1);
+ m_format.setSampleSize(16);
+ m_format.setSampleType(QAudioFormat::SignedInt);
+ m_format.setByteOrder(QAudioFormat::LittleEndian);
+ m_format.setCodec("audio/pcm");
+
+ QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice());
+ if (!info.isFormatSupported(m_format)) {
+ qWarning() << "Default format not supported - trying to use nearest";
+ m_format = info.nearestFormat(m_format);
+ }
+
+ m_audioInfo = new AudioInfo(m_format, this);
+ connect(m_audioInfo, SIGNAL(update()), SLOT(refreshDisplay()));
+
+ createAudioInput();
+}
+
+void InputTest::createAudioInput()
+{
+ m_audioInput = new QAudioInput(m_device, m_format, this);
+ connect(m_audioInput, SIGNAL(notify()), SLOT(notified()));
+ connect(m_audioInput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
+ m_volumeSlider->setValue(m_audioInput->volume() * 100);
+ m_audioInfo->start();
+ m_audioInput->start(m_audioInfo);
+}
+
+void InputTest::notified()
+{
+ qWarning() << "bytesReady = " << m_audioInput->bytesReady()
+ << ", " << "elapsedUSecs = " <<m_audioInput->elapsedUSecs()
+ << ", " << "processedUSecs = "<<m_audioInput->processedUSecs();
+}
+
+void InputTest::readMore()
+{
+ if (!m_audioInput)
+ return;
+ qint64 len = m_audioInput->bytesReady();
+ if (len > BufferSize)
+ len = BufferSize;
+ qint64 l = m_input->read(m_buffer.data(), len);
+ if (l > 0)
+ m_audioInfo->write(m_buffer.constData(), l);
+}
+
+void InputTest::toggleMode()
+{
+ // Change bewteen pull and push modes
+ m_audioInput->stop();
+
+ if (m_pullMode) {
+ m_modeButton->setText(tr(PULL_MODE_LABEL));
+ m_input = m_audioInput->start();
+ connect(m_input, SIGNAL(readyRead()), SLOT(readMore()));
+ m_pullMode = false;
+ } else {
+ m_modeButton->setText(tr(PUSH_MODE_LABEL));
+ m_pullMode = true;
+ m_audioInput->start(m_audioInfo);
+ }
+
+ m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
+}
+
+void InputTest::toggleSuspend()
+{
+ // toggle suspend/resume
+ if (m_audioInput->state() == QAudio::SuspendedState) {
+ qWarning() << "status: Suspended, resume()";
+ m_audioInput->resume();
+ m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
+ } else if (m_audioInput->state() == QAudio::ActiveState) {
+ qWarning() << "status: Active, suspend()";
+ m_audioInput->suspend();
+ m_suspendResumeButton->setText(tr(RESUME_LABEL));
+ } else if (m_audioInput->state() == QAudio::StoppedState) {
+ qWarning() << "status: Stopped, resume()";
+ m_audioInput->resume();
+ m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
+ } else if (m_audioInput->state() == QAudio::IdleState) {
+ qWarning() << "status: IdleState";
+ }
+}
+
+void InputTest::stateChanged(QAudio::State state)
+{
+ qWarning() << "state = " << state;
+}
+
+void InputTest::refreshDisplay()
+{
+ m_canvas->setLevel(m_audioInfo->level());
+}
+
+void InputTest::deviceChanged(int index)
+{
+ m_audioInfo->stop();
+ m_audioInput->stop();
+ m_audioInput->disconnect(this);
+ delete m_audioInput;
+
+ m_device = m_deviceBox->itemData(index).value<QAudioDeviceInfo>();
+ createAudioInput();
+}
+
+void InputTest::sliderChanged(int value)
+{
+ if (m_audioInput)
+ m_audioInput->setVolume(qreal(value) / 100);
+}
diff --git a/examples/multimedia/audioinput/audioinput.h b/examples/multimedia/audioinput/audioinput.h
new file mode 100644
index 000000000..83bf66f0d
--- /dev/null
+++ b/examples/multimedia/audioinput/audioinput.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 AUDIOINPUT_H
+#define AUDIOINPUT_H
+
+#include <QAudioInput>
+#include <QByteArray>
+#include <QComboBox>
+#include <QMainWindow>
+#include <QObject>
+#include <QPixmap>
+#include <QPushButton>
+#include <QSlider>
+#include <QWidget>
+
+class AudioInfo : public QIODevice
+{
+ Q_OBJECT
+
+public:
+ AudioInfo(const QAudioFormat &format, QObject *parent);
+ ~AudioInfo();
+
+ void start();
+ void stop();
+
+ qreal level() const { return m_level; }
+
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+
+private:
+ const QAudioFormat m_format;
+ quint32 m_maxAmplitude;
+ qreal m_level; // 0.0 <= m_level <= 1.0
+
+signals:
+ void update();
+};
+
+
+class RenderArea : public QWidget
+{
+ Q_OBJECT
+
+public:
+ RenderArea(QWidget *parent = 0);
+
+ void setLevel(qreal value);
+
+protected:
+ void paintEvent(QPaintEvent *event);
+
+private:
+ qreal m_level;
+ QPixmap m_pixmap;
+};
+
+
+class InputTest : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ InputTest();
+ ~InputTest();
+
+private:
+ void initializeWindow();
+ void initializeAudio();
+ void createAudioInput();
+
+private slots:
+ void refreshDisplay();
+ void notified();
+ void readMore();
+ void toggleMode();
+ void toggleSuspend();
+ void stateChanged(QAudio::State state);
+ void deviceChanged(int index);
+ void sliderChanged(int value);
+
+private:
+ // Owned by layout
+ RenderArea *m_canvas;
+ QPushButton *m_modeButton;
+ QPushButton *m_suspendResumeButton;
+ QComboBox *m_deviceBox;
+ QSlider *m_volumeSlider;
+
+ QAudioDeviceInfo m_device;
+ AudioInfo *m_audioInfo;
+ QAudioFormat m_format;
+ QAudioInput *m_audioInput;
+ QIODevice *m_input;
+ bool m_pullMode;
+ QByteArray m_buffer;
+};
+
+#endif // AUDIOINPUT_H
diff --git a/examples/multimedia/audioinput/audioinput.pro b/examples/multimedia/audioinput/audioinput.pro
new file mode 100644
index 000000000..b0dc57c27
--- /dev/null
+++ b/examples/multimedia/audioinput/audioinput.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+TARGET = audioinput
+
+QT += multimedia widgets
+
+HEADERS = audioinput.h
+
+SOURCES = audioinput.cpp \
+ main.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audioinput
+INSTALLS += target
diff --git a/examples/multimedia/audioinput/doc/images/audioinput-example.png b/examples/multimedia/audioinput/doc/images/audioinput-example.png
new file mode 100644
index 000000000..fb703e68c
--- /dev/null
+++ b/examples/multimedia/audioinput/doc/images/audioinput-example.png
Binary files differ
diff --git a/examples/multimedia/audioinput/doc/src/audioinput.qdoc b/examples/multimedia/audioinput/doc/src/audioinput.qdoc
new file mode 100644
index 000000000..4fc7e6e64
--- /dev/null
+++ b/examples/multimedia/audioinput/doc/src/audioinput.qdoc
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example audioinput
+ \title Audio Input Example
+ \ingroup audio_examples
+ \brief The Audio Input Example shows the use of the QAudioInput class.
+ The example demonstrates the basic use cases of the QAudioInput class.
+
+ \image audioinput-example.png
+
+ Qt provides the QAudioInput class to enable audio functionality within
+ a standard application user interface.
+
+ This example calculates the maximum linear value of the input audio from the microphone and displays the output.
+*/
+
+
diff --git a/examples/multimedia/audioinput/main.cpp b/examples/multimedia/audioinput/main.cpp
new file mode 100644
index 000000000..d5dececf1
--- /dev/null
+++ b/examples/multimedia/audioinput/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QtWidgets>
+
+#include "audioinput.h"
+
+int main(int argv, char **args)
+{
+ QApplication app(argv, args);
+ app.setApplicationName("Audio Input Test");
+
+ InputTest input;
+ input.show();
+
+ return app.exec();
+}
diff --git a/examples/multimedia/audiooutput/audiooutput.cpp b/examples/multimedia/audiooutput/audiooutput.cpp
new file mode 100644
index 000000000..4328e4e99
--- /dev/null
+++ b/examples/multimedia/audiooutput/audiooutput.cpp
@@ -0,0 +1,334 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QAudioDeviceInfo>
+#include <QAudioOutput>
+#include <QDebug>
+#include <QVBoxLayout>
+#include <qmath.h>
+#include <qendian.h>
+
+#include "audiooutput.h"
+
+#define PUSH_MODE_LABEL "Enable push mode"
+#define PULL_MODE_LABEL "Enable pull mode"
+#define SUSPEND_LABEL "Suspend playback"
+#define RESUME_LABEL "Resume playback"
+#define VOLUME_LABEL "Volume:"
+
+const int DurationSeconds = 1;
+const int ToneSampleRateHz = 600;
+const int DataSampleRateHz = 44100;
+const int BufferSize = 32768;
+
+
+Generator::Generator(const QAudioFormat &format,
+ qint64 durationUs,
+ int sampleRate,
+ QObject *parent)
+ : QIODevice(parent)
+ , m_pos(0)
+{
+ generateData(format, durationUs, sampleRate);
+}
+
+Generator::~Generator()
+{
+
+}
+
+void Generator::start()
+{
+ open(QIODevice::ReadOnly);
+}
+
+void Generator::stop()
+{
+ m_pos = 0;
+ close();
+}
+
+void Generator::generateData(const QAudioFormat &format, qint64 durationUs, int sampleRate)
+{
+ const int channelBytes = format.sampleSize() / 8;
+ const int sampleBytes = format.channelCount() * channelBytes;
+
+ qint64 length = (format.sampleRate() * format.channelCount() * (format.sampleSize() / 8))
+ * durationUs / 100000;
+
+ Q_ASSERT(length % sampleBytes == 0);
+ Q_UNUSED(sampleBytes) // suppress warning in release builds
+
+ m_buffer.resize(length);
+ unsigned char *ptr = reinterpret_cast<unsigned char *>(m_buffer.data());
+ int sampleIndex = 0;
+
+ while (length) {
+ const qreal x = qSin(2 * M_PI * sampleRate * qreal(sampleIndex % format.sampleRate()) / format.sampleRate());
+ for (int i=0; i<format.channelCount(); ++i) {
+ if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::UnSignedInt) {
+ const quint8 value = static_cast<quint8>((1.0 + x) / 2 * 255);
+ *reinterpret_cast<quint8*>(ptr) = value;
+ } else if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::SignedInt) {
+ const qint8 value = static_cast<qint8>(x * 127);
+ *reinterpret_cast<quint8*>(ptr) = value;
+ } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::UnSignedInt) {
+ quint16 value = static_cast<quint16>((1.0 + x) / 2 * 65535);
+ if (format.byteOrder() == QAudioFormat::LittleEndian)
+ qToLittleEndian<quint16>(value, ptr);
+ else
+ qToBigEndian<quint16>(value, ptr);
+ } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::SignedInt) {
+ qint16 value = static_cast<qint16>(x * 32767);
+ if (format.byteOrder() == QAudioFormat::LittleEndian)
+ qToLittleEndian<qint16>(value, ptr);
+ else
+ qToBigEndian<qint16>(value, ptr);
+ }
+
+ ptr += channelBytes;
+ length -= channelBytes;
+ }
+ ++sampleIndex;
+ }
+}
+
+qint64 Generator::readData(char *data, qint64 len)
+{
+ qint64 total = 0;
+ while (len - total > 0) {
+ const qint64 chunk = qMin((m_buffer.size() - m_pos), len - total);
+ memcpy(data + total, m_buffer.constData() + m_pos, chunk);
+ m_pos = (m_pos + chunk) % m_buffer.size();
+ total += chunk;
+ }
+ return total;
+}
+
+qint64 Generator::writeData(const char *data, qint64 len)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(len);
+
+ return 0;
+}
+
+qint64 Generator::bytesAvailable() const
+{
+ return m_buffer.size() + QIODevice::bytesAvailable();
+}
+
+AudioTest::AudioTest()
+ : m_pullTimer(new QTimer(this))
+ , m_modeButton(0)
+ , m_suspendResumeButton(0)
+ , m_deviceBox(0)
+ , m_device(QAudioDeviceInfo::defaultOutputDevice())
+ , m_generator(0)
+ , m_audioOutput(0)
+ , m_output(0)
+ , m_buffer(BufferSize, 0)
+{
+ initializeWindow();
+ initializeAudio();
+}
+
+void AudioTest::initializeWindow()
+{
+ QScopedPointer<QWidget> window(new QWidget);
+ QScopedPointer<QVBoxLayout> layout(new QVBoxLayout);
+
+ m_deviceBox = new QComboBox(this);
+ foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput))
+ m_deviceBox->addItem(deviceInfo.deviceName(), qVariantFromValue(deviceInfo));
+ connect(m_deviceBox,SIGNAL(activated(int)),SLOT(deviceChanged(int)));
+ layout->addWidget(m_deviceBox);
+
+ m_modeButton = new QPushButton(this);
+ m_modeButton->setText(tr(PUSH_MODE_LABEL));
+ connect(m_modeButton, SIGNAL(clicked()), SLOT(toggleMode()));
+ layout->addWidget(m_modeButton);
+
+ m_suspendResumeButton = new QPushButton(this);
+ m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
+ connect(m_suspendResumeButton, SIGNAL(clicked()), SLOT(toggleSuspendResume()));
+ layout->addWidget(m_suspendResumeButton);
+
+ QHBoxLayout *volumeBox = new QHBoxLayout;
+ m_volumeLabel = new QLabel;
+ m_volumeLabel->setText(tr(VOLUME_LABEL));
+ m_volumeSlider = new QSlider(Qt::Horizontal);
+ m_volumeSlider->setMinimum(0);
+ m_volumeSlider->setMaximum(100);
+ m_volumeSlider->setSingleStep(10);
+ connect(m_volumeSlider, SIGNAL(valueChanged(int)), this, SLOT(volumeChanged(int)));
+ volumeBox->addWidget(m_volumeLabel);
+ volumeBox->addWidget(m_volumeSlider);
+ layout->addLayout(volumeBox);
+
+ window->setLayout(layout.data());
+ layout.take(); // ownership transferred
+
+ setCentralWidget(window.data());
+ QWidget *const windowPtr = window.take(); // ownership transferred
+ windowPtr->show();
+}
+
+void AudioTest::initializeAudio()
+{
+ connect(m_pullTimer, SIGNAL(timeout()), SLOT(pullTimerExpired()));
+
+ m_pullMode = true;
+
+ m_format.setSampleRate(DataSampleRateHz);
+ m_format.setChannelCount(1);
+ m_format.setSampleSize(16);
+ m_format.setCodec("audio/pcm");
+ m_format.setByteOrder(QAudioFormat::LittleEndian);
+ m_format.setSampleType(QAudioFormat::SignedInt);
+
+ QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
+ if (!info.isFormatSupported(m_format)) {
+ qWarning() << "Default format not supported - trying to use nearest";
+ m_format = info.nearestFormat(m_format);
+ }
+
+ m_generator = new Generator(m_format, DurationSeconds*1000000, ToneSampleRateHz, this);
+
+ createAudioOutput();
+}
+
+void AudioTest::createAudioOutput()
+{
+ delete m_audioOutput;
+ m_audioOutput = 0;
+ m_audioOutput = new QAudioOutput(m_device, m_format, this);
+ connect(m_audioOutput, SIGNAL(notify()), SLOT(notified()));
+ connect(m_audioOutput, SIGNAL(stateChanged(QAudio::State)), SLOT(stateChanged(QAudio::State)));
+ m_generator->start();
+ m_audioOutput->start(m_generator);
+ m_volumeSlider->setValue(int(m_audioOutput->volume()*100.0f));
+}
+
+AudioTest::~AudioTest()
+{
+
+}
+
+void AudioTest::deviceChanged(int index)
+{
+ m_pullTimer->stop();
+ m_generator->stop();
+ m_audioOutput->stop();
+ m_audioOutput->disconnect(this);
+ m_device = m_deviceBox->itemData(index).value<QAudioDeviceInfo>();
+ createAudioOutput();
+}
+
+void AudioTest::volumeChanged(int value)
+{
+ if (m_audioOutput)
+ m_audioOutput->setVolume(qreal(value/100.0f));
+}
+
+void AudioTest::notified()
+{
+ qWarning() << "bytesFree = " << m_audioOutput->bytesFree()
+ << ", " << "elapsedUSecs = " << m_audioOutput->elapsedUSecs()
+ << ", " << "processedUSecs = " << m_audioOutput->processedUSecs();
+}
+
+void AudioTest::pullTimerExpired()
+{
+ if (m_audioOutput && m_audioOutput->state() != QAudio::StoppedState) {
+ int chunks = m_audioOutput->bytesFree()/m_audioOutput->periodSize();
+ while (chunks) {
+ const qint64 len = m_generator->read(m_buffer.data(), m_audioOutput->periodSize());
+ if (len)
+ m_output->write(m_buffer.data(), len);
+ if (len != m_audioOutput->periodSize())
+ break;
+ --chunks;
+ }
+ }
+}
+
+void AudioTest::toggleMode()
+{
+ m_pullTimer->stop();
+ m_audioOutput->stop();
+
+ if (m_pullMode) {
+ m_modeButton->setText(tr(PULL_MODE_LABEL));
+ m_output = m_audioOutput->start();
+ m_pullMode = false;
+ m_pullTimer->start(20);
+ } else {
+ m_modeButton->setText(tr(PUSH_MODE_LABEL));
+ m_pullMode = true;
+ m_audioOutput->start(m_generator);
+ }
+
+ m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
+}
+
+void AudioTest::toggleSuspendResume()
+{
+ if (m_audioOutput->state() == QAudio::SuspendedState) {
+ qWarning() << "status: Suspended, resume()";
+ m_audioOutput->resume();
+ m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
+ } else if (m_audioOutput->state() == QAudio::ActiveState) {
+ qWarning() << "status: Active, suspend()";
+ m_audioOutput->suspend();
+ m_suspendResumeButton->setText(tr(RESUME_LABEL));
+ } else if (m_audioOutput->state() == QAudio::StoppedState) {
+ qWarning() << "status: Stopped, resume()";
+ m_audioOutput->resume();
+ m_suspendResumeButton->setText(tr(SUSPEND_LABEL));
+ } else if (m_audioOutput->state() == QAudio::IdleState) {
+ qWarning() << "status: IdleState";
+ }
+}
+
+void AudioTest::stateChanged(QAudio::State state)
+{
+ qWarning() << "state = " << state;
+}
diff --git a/examples/multimedia/audiooutput/audiooutput.h b/examples/multimedia/audiooutput/audiooutput.h
new file mode 100644
index 000000000..52c29cc79
--- /dev/null
+++ b/examples/multimedia/audiooutput/audiooutput.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 AUDIOOUTPUT_H
+#define AUDIOOUTPUT_H
+
+#include <math.h>
+
+#include <QAudioOutput>
+#include <QByteArray>
+#include <QComboBox>
+#include <QIODevice>
+#include <QLabel>
+#include <QMainWindow>
+#include <QObject>
+#include <QPushButton>
+#include <QSlider>
+#include <QTimer>
+
+class Generator : public QIODevice
+{
+ Q_OBJECT
+
+public:
+ Generator(const QAudioFormat &format, qint64 durationUs, int sampleRate, QObject *parent);
+ ~Generator();
+
+ void start();
+ void stop();
+
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+ qint64 bytesAvailable() const;
+
+private:
+ void generateData(const QAudioFormat &format, qint64 durationUs, int sampleRate);
+
+private:
+ qint64 m_pos;
+ QByteArray m_buffer;
+};
+
+class AudioTest : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ AudioTest();
+ ~AudioTest();
+
+private:
+ void initializeWindow();
+ void initializeAudio();
+ void createAudioOutput();
+
+private:
+ QTimer *m_pullTimer;
+
+ // Owned by layout
+ QPushButton *m_modeButton;
+ QPushButton *m_suspendResumeButton;
+ QComboBox *m_deviceBox;
+ QLabel *m_volumeLabel;
+ QSlider *m_volumeSlider;
+
+ QAudioDeviceInfo m_device;
+ Generator *m_generator;
+ QAudioOutput *m_audioOutput;
+ QIODevice *m_output; // not owned
+ QAudioFormat m_format;
+
+ bool m_pullMode;
+ QByteArray m_buffer;
+
+private slots:
+ void notified();
+ void pullTimerExpired();
+ void toggleMode();
+ void toggleSuspendResume();
+ void stateChanged(QAudio::State state);
+ void deviceChanged(int index);
+ void volumeChanged(int);
+};
+
+#endif // AUDIOOUTPUT_H
diff --git a/examples/multimedia/audiooutput/audiooutput.pro b/examples/multimedia/audiooutput/audiooutput.pro
new file mode 100644
index 000000000..c843f010f
--- /dev/null
+++ b/examples/multimedia/audiooutput/audiooutput.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+TARGET = audiooutput
+
+QT += multimedia widgets
+
+HEADERS = audiooutput.h
+
+SOURCES = audiooutput.cpp \
+ main.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audiooutput
+INSTALLS += target
diff --git a/examples/multimedia/audiooutput/doc/images/audiooutput-example.png b/examples/multimedia/audiooutput/doc/images/audiooutput-example.png
new file mode 100755
index 000000000..5588fbb57
--- /dev/null
+++ b/examples/multimedia/audiooutput/doc/images/audiooutput-example.png
Binary files differ
diff --git a/examples/multimedia/audiooutput/doc/src/audiooutput.qdoc b/examples/multimedia/audiooutput/doc/src/audiooutput.qdoc
new file mode 100644
index 000000000..c29fcd81d
--- /dev/null
+++ b/examples/multimedia/audiooutput/doc/src/audiooutput.qdoc
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example audiooutput
+ \title Audio Output Example
+ \ingroup audio_examples
+ \brief The Audio Output Example show the use of the QAudioOutput API.
+
+ The example demonstrates the basic use cases of the QAudioOutput class.
+
+ \image audiooutput-example.png
+
+ This example provides a tone generator to supply continuous audio playback.
+ The first button allows pause and resume of the playback, and the second
+ button allows toggling between push and pull modes of operation.
+*/
+
+
diff --git a/examples/multimedia/audiooutput/main.cpp b/examples/multimedia/audiooutput/main.cpp
new file mode 100644
index 000000000..097cabb7b
--- /dev/null
+++ b/examples/multimedia/audiooutput/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QApplication>
+
+#include "audiooutput.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ app.setApplicationName("Audio Output Test");
+
+ AudioTest audio;
+ audio.show();
+
+ return app.exec();
+}
diff --git a/examples/multimedia/audiorecorder/audiorecorder.cpp b/examples/multimedia/audiorecorder/audiorecorder.cpp
new file mode 100644
index 000000000..6c65f2e1d
--- /dev/null
+++ b/examples/multimedia/audiorecorder/audiorecorder.cpp
@@ -0,0 +1,319 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QAudioProbe>
+#include <QAudioRecorder>
+#include <QDir>
+#include <QFileDialog>
+#include <QMediaRecorder>
+
+#include "audiorecorder.h"
+
+#if defined(Q_WS_MAEMO_6)
+#include "ui_audiorecorder_small.h"
+#else
+#include "ui_audiorecorder.h"
+#endif
+
+static qreal getPeakValue(const QAudioFormat &format);
+static qreal getBufferLevel(const QAudioBuffer &buffer);
+
+template <class T>
+static qreal getBufferLevel(const T *buffer, int samples);
+
+AudioRecorder::AudioRecorder(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::AudioRecorder),
+ outputLocationSet(false)
+{
+ ui->setupUi(this);
+
+ audioRecorder = new QAudioRecorder(this);
+ probe = new QAudioProbe;
+ connect(probe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(processBuffer(QAudioBuffer)));
+ probe->setSource(audioRecorder);
+
+ //audio devices
+ ui->audioDeviceBox->addItem(tr("Default"), QVariant(QString()));
+ foreach (const QString &device, audioRecorder->audioInputs()) {
+ ui->audioDeviceBox->addItem(device, QVariant(device));
+ }
+
+ //audio codecs
+ ui->audioCodecBox->addItem(tr("Default"), QVariant(QString()));
+ foreach (const QString &codecName, audioRecorder->supportedAudioCodecs()) {
+ ui->audioCodecBox->addItem(codecName, QVariant(codecName));
+ }
+
+ //containers
+ ui->containerBox->addItem(tr("Default"), QVariant(QString()));
+ foreach (const QString &containerName, audioRecorder->supportedContainers()) {
+ ui->containerBox->addItem(containerName, QVariant(containerName));
+ }
+
+ //sample rate:
+ ui->sampleRateBox->addItem(tr("Default"), QVariant(0));
+ foreach (int sampleRate, audioRecorder->supportedAudioSampleRates()) {
+ ui->sampleRateBox->addItem(QString::number(sampleRate), QVariant(
+ sampleRate));
+ }
+
+ ui->qualitySlider->setRange(0, int(QMultimedia::VeryHighQuality));
+ ui->qualitySlider->setValue(int(QMultimedia::NormalQuality));
+
+ //bitrates:
+ ui->bitrateBox->addItem(QString("Default"), QVariant(0));
+ ui->bitrateBox->addItem(QString("32000"), QVariant(32000));
+ ui->bitrateBox->addItem(QString("64000"), QVariant(64000));
+ ui->bitrateBox->addItem(QString("96000"), QVariant(96000));
+ ui->bitrateBox->addItem(QString("128000"), QVariant(128000));
+
+ connect(audioRecorder, SIGNAL(durationChanged(qint64)), this,
+ SLOT(updateProgress(qint64)));
+ connect(audioRecorder, SIGNAL(stateChanged(QMediaRecorder::State)), this,
+ SLOT(updateState(QMediaRecorder::State)));
+ connect(audioRecorder, SIGNAL(error(QMediaRecorder::Error)), this,
+ SLOT(displayErrorMessage()));
+}
+
+AudioRecorder::~AudioRecorder()
+{
+ delete audioRecorder;
+ delete probe;
+}
+
+void AudioRecorder::updateProgress(qint64 duration)
+{
+ if (audioRecorder->error() != QMediaRecorder::NoError || duration < 2000)
+ return;
+
+ ui->statusbar->showMessage(tr("Recorded %1 sec").arg(duration / 1000));
+}
+
+void AudioRecorder::updateState(QMediaRecorder::State state)
+{
+ QString statusMessage;
+
+ switch (state) {
+ case QMediaRecorder::RecordingState:
+ ui->recordButton->setText(tr("Stop"));
+ ui->pauseButton->setText(tr("Pause"));
+ if (audioRecorder->outputLocation().isEmpty())
+ statusMessage = tr("Recording");
+ else
+ statusMessage = tr("Recording to %1").arg(
+ audioRecorder->outputLocation().toString());
+ break;
+ case QMediaRecorder::PausedState:
+ ui->recordButton->setText(tr("Stop"));
+ ui->pauseButton->setText(tr("Resume"));
+ statusMessage = tr("Paused");
+ break;
+ case QMediaRecorder::StoppedState:
+ ui->recordButton->setText(tr("Record"));
+ ui->pauseButton->setText(tr("Pause"));
+ statusMessage = tr("Stopped");
+ }
+
+ ui->pauseButton->setEnabled(state != QMediaRecorder::StoppedState);
+
+ if (audioRecorder->error() == QMediaRecorder::NoError)
+ ui->statusbar->showMessage(statusMessage);
+}
+
+static QVariant boxValue(const QComboBox *box)
+{
+ int idx = box->currentIndex();
+ if (idx == -1)
+ return QVariant();
+
+ return box->itemData(idx);
+}
+
+void AudioRecorder::toggleRecord()
+{
+ if (audioRecorder->state() == QMediaRecorder::StoppedState) {
+ audioRecorder->setAudioInput(boxValue(ui->audioDeviceBox).toString());
+
+ if (!outputLocationSet)
+ audioRecorder->setOutputLocation(generateAudioFilePath());
+
+ QAudioEncoderSettings settings;
+ settings.setCodec(boxValue(ui->audioCodecBox).toString());
+ settings.setSampleRate(boxValue(ui->sampleRateBox).toInt());
+ settings.setBitRate(boxValue(ui->bitrateBox).toInt());
+ settings.setQuality(QMultimedia::EncodingQuality(ui->qualitySlider->value()));
+ settings.setEncodingMode(ui->constantQualityRadioButton->isChecked() ?
+ QMultimedia::ConstantQualityEncoding :
+ QMultimedia::ConstantBitRateEncoding);
+
+ QString container = boxValue(ui->containerBox).toString();
+
+ audioRecorder->setEncodingSettings(settings, QVideoEncoderSettings(), container);
+ audioRecorder->record();
+ }
+ else {
+ audioRecorder->stop();
+ }
+}
+
+void AudioRecorder::togglePause()
+{
+ if (audioRecorder->state() != QMediaRecorder::PausedState)
+ audioRecorder->pause();
+ else
+ audioRecorder->record();
+}
+
+void AudioRecorder::setOutputLocation()
+{
+ QString fileName = QFileDialog::getSaveFileName();
+ audioRecorder->setOutputLocation(QUrl(fileName));
+ outputLocationSet = true;
+}
+
+void AudioRecorder::displayErrorMessage()
+{
+ ui->statusbar->showMessage(audioRecorder->errorString());
+}
+
+QUrl AudioRecorder::generateAudioFilePath()
+{
+ QDir outputDir(QDir::rootPath());
+
+ int lastImage = 0;
+ int fileCount = 0;
+ foreach (const QString &fileName, outputDir.entryList(QStringList(QString("testclip_*")))) {
+ int imgNumber = fileName.mid(5, fileName.size() - 9).toInt();
+ lastImage = qMax(lastImage, imgNumber);
+ if (outputDir.exists(fileName))
+ fileCount += 1;
+ }
+ lastImage += fileCount;
+ QUrl location(QDir::toNativeSeparators(outputDir.canonicalPath()
+ + QString("/testclip_%1").arg(lastImage + 1, 4, 10, QLatin1Char('0'))));
+ return location;
+}
+
+// This function returns the maximum possible sample value for a given audio format
+qreal getPeakValue(const QAudioFormat& format)
+{
+ // Note: Only the most common sample formats are supported
+ if (!format.isValid())
+ return 0.0;
+
+ if (format.codec() != "audio/pcm")
+ return 0.0;
+
+ switch (format.sampleType()) {
+ case QAudioFormat::Unknown:
+ break;
+ case QAudioFormat::Float:
+ if (format.sampleSize() != 32) // other sample formats are not supported
+ return 0.0;
+ return 1.00003;
+ case QAudioFormat::SignedInt:
+ if (format.sampleSize() == 32)
+ return 2147483648.0;
+ if (format.sampleSize() == 16)
+ return 32768.0;
+ if (format.sampleSize() == 8)
+ return 128.0;
+ break;
+ case QAudioFormat::UnSignedInt:
+ // Unsigned formats are not supported in this example
+ break;
+ }
+
+ return 0.0;
+}
+
+qreal getBufferLevel(const QAudioBuffer& buffer)
+{
+ if (!buffer.format().isValid() || buffer.format().byteOrder() != QAudioFormat::LittleEndian)
+ return 0.0;
+
+ if (buffer.format().codec() != "audio/pcm")
+ return 0.0;
+
+ qreal peak_value = getPeakValue(buffer.format());
+ if (qFuzzyCompare(peak_value, 0.0))
+ return 0.0;
+
+ switch (buffer.format().sampleType()) {
+ case QAudioFormat::Unknown:
+ case QAudioFormat::UnSignedInt:
+ break;
+ case QAudioFormat::Float:
+ if (buffer.format().sampleSize() == 32)
+ return getBufferLevel(buffer.constData<float>(), buffer.sampleCount()) / peak_value;
+ break;
+ case QAudioFormat::SignedInt:
+ if (buffer.format().sampleSize() == 32)
+ return getBufferLevel(buffer.constData<long int>(), buffer.sampleCount()) / peak_value;
+ if (buffer.format().sampleSize() == 16)
+ return getBufferLevel(buffer.constData<short int>(), buffer.sampleCount()) / peak_value;
+ if (buffer.format().sampleSize() == 8)
+ return getBufferLevel(buffer.constData<signed char>(), buffer.sampleCount()) / peak_value;
+ break;
+ }
+
+ return 0.0;
+}
+
+template <class T>
+qreal getBufferLevel(const T *buffer, int samples)
+{
+ qreal max_value = 0.0;
+
+ for (int i = 0; i < samples; ++i) {
+ qreal value = qAbs(qreal(buffer[i]));
+ if (value > max_value)
+ max_value = value;
+ }
+
+ return max_value;
+}
+
+void AudioRecorder::processBuffer(const QAudioBuffer& buffer)
+{
+ qreal level = getBufferLevel(buffer);
+ ui->audioLevel->setLevel(level);
+}
diff --git a/examples/multimedia/audiorecorder/audiorecorder.h b/examples/multimedia/audiorecorder/audiorecorder.h
new file mode 100644
index 000000000..a58daf5f7
--- /dev/null
+++ b/examples/multimedia/audiorecorder/audiorecorder.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 AUDIORECORDER_H
+#define AUDIORECORDER_H
+
+#include <QMainWindow>
+#include <QMediaRecorder>
+#include <QUrl>
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class AudioRecorder; }
+class QAudioRecorder;
+class QAudioProbe;
+class QAudioBuffer;
+QT_END_NAMESPACE
+
+class AudioRecorder : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ AudioRecorder(QWidget *parent = 0);
+ ~AudioRecorder();
+
+public slots:
+ void processBuffer(const QAudioBuffer&);
+
+private slots:
+ void setOutputLocation();
+ void togglePause();
+ void toggleRecord();
+
+ void updateState(QMediaRecorder::State);
+ void updateProgress(qint64 pos);
+ void displayErrorMessage();
+ QUrl generateAudioFilePath();
+
+private:
+ Ui::AudioRecorder *ui;
+
+ QAudioRecorder *audioRecorder;
+ QAudioProbe *probe;
+ bool outputLocationSet;
+
+};
+
+#endif // AUDIORECORDER_H
diff --git a/examples/multimedia/audiorecorder/audiorecorder.pro b/examples/multimedia/audiorecorder/audiorecorder.pro
new file mode 100644
index 000000000..6fdc4b13d
--- /dev/null
+++ b/examples/multimedia/audiorecorder/audiorecorder.pro
@@ -0,0 +1,26 @@
+TEMPLATE = app
+TARGET = audiorecorder
+
+QT += multimedia
+
+win32:INCLUDEPATH += $$PWD
+
+HEADERS = \
+ audiorecorder.h \
+ qaudiolevel.h
+
+SOURCES = \
+ main.cpp \
+ audiorecorder.cpp \
+ qaudiolevel.cpp
+
+maemo*: {
+ FORMS += audiorecorder_small.ui
+}else {
+ FORMS += audiorecorder.ui
+}
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/audiorecorder
+INSTALLS += target
+
+QT+=widgets
diff --git a/examples/multimedia/audiorecorder/audiorecorder.ui b/examples/multimedia/audiorecorder/audiorecorder.ui
new file mode 100644
index 000000000..ff6c2d935
--- /dev/null
+++ b/examples/multimedia/audiorecorder/audiorecorder.ui
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AudioRecorder</class>
+ <widget class="QMainWindow" name="AudioRecorder">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>297</width>
+ <height>374</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0" colspan="3">
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Input Device:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="audioDeviceBox"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Audio Codec:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="audioCodecBox"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>File Container:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="containerBox"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Sample rate:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="sampleRateBox"/>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" colspan="3">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Encoding Mode:</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QRadioButton" name="constantQualityRadioButton">
+ <property name="text">
+ <string>Constant Quality:</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSlider" name="qualitySlider">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QRadioButton" name="constantBitrateRadioButton">
+ <property name="text">
+ <string>Constant Bitrate:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="bitrateBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QPushButton" name="outputButton">
+ <property name="text">
+ <string>Output...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QPushButton" name="recordButton">
+ <property name="text">
+ <string>Record</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QPushButton" name="pauseButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Pause</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="levelLabel">
+ <property name="text">
+ <string>Audio Level:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="-1">
+ <widget class="QAudioLevel" name="audioLevel">
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>constantQualityRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>qualitySlider</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>113</x>
+ <y>197</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>115</x>
+ <y>223</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>constantBitrateRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>bitrateBox</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>173</x>
+ <y>259</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>190</x>
+ <y>291</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>outputButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AudioRecorder</receiver>
+ <slot>setOutputLocation()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>46</x>
+ <y>340</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>6</x>
+ <y>302</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>recordButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AudioRecorder</receiver>
+ <slot>toggleRecord()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>191</x>
+ <y>340</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>113</x>
+ <y>317</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>pauseButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AudioRecorder</receiver>
+ <slot>togglePause()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>252</x>
+ <y>334</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>258</x>
+ <y>346</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+ <slots>
+ <slot>setOutputLocation()</slot>
+ <slot>toggleRecord()</slot>
+ <slot>togglePause()</slot>
+ </slots>
+</ui>
diff --git a/examples/multimedia/audiorecorder/audiorecorder_small.ui b/examples/multimedia/audiorecorder/audiorecorder_small.ui
new file mode 100644
index 000000000..9d23c4267
--- /dev/null
+++ b/examples/multimedia/audiorecorder/audiorecorder_small.ui
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AudioRecorder</class>
+ <widget class="QMainWindow" name="AudioRecorder">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>420</width>
+ <height>346</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="0" column="0" colspan="3">
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="focusPolicy">
+ <enum>Qt::ClickFocus</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>398</width>
+ <height>275</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <widget class="QWidget" name="widget" native="true">
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Input Device:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="audioDeviceBox"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Audio Codec:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="audioCodecBox"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>File Container:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="containerBox"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Sample rate:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="sampleRateBox"/>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="constantQualityRadioButton">
+ <property name="text">
+ <string>Quality:</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QRadioButton" name="constantBitrateRadioButton">
+ <property name="text">
+ <string>Bitrate:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QSlider" name="qualitySlider">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="bitrateBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>29</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QPushButton" name="outputButton">
+ <property name="text">
+ <string>Output...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="recordButton">
+ <property name="text">
+ <string>Record</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="pauseButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Pause</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>constantQualityRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>qualitySlider</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>113</x>
+ <y>197</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>115</x>
+ <y>223</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>constantBitrateRadioButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>bitrateBox</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>173</x>
+ <y>259</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>190</x>
+ <y>291</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>outputButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AudioRecorder</receiver>
+ <slot>setOutputLocation()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>46</x>
+ <y>340</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>6</x>
+ <y>302</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>recordButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AudioRecorder</receiver>
+ <slot>toggleRecord()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>191</x>
+ <y>340</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>113</x>
+ <y>317</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>pauseButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AudioRecorder</receiver>
+ <slot>togglePause()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>252</x>
+ <y>334</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>258</x>
+ <y>346</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+ <slots>
+ <slot>setOutputLocation()</slot>
+ <slot>toggleRecord()</slot>
+ <slot>togglePause()</slot>
+ </slots>
+</ui>
diff --git a/examples/multimedia/audiorecorder/doc/images/audiorecorder.png b/examples/multimedia/audiorecorder/doc/images/audiorecorder.png
new file mode 100644
index 000000000..6643bf320
--- /dev/null
+++ b/examples/multimedia/audiorecorder/doc/images/audiorecorder.png
Binary files differ
diff --git a/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc b/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc
new file mode 100644
index 000000000..3dea92cac
--- /dev/null
+++ b/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example audiorecorder
+ \title Audio Recorder Example
+ \ingroup audio_examples
+ \brief The Audio Recorder Example shows how to create a simple audio recorder.
+
+ It demonstrates the discovery of the supported devices and codecs and the use
+ of recording functions in the QAudioRecorder class.
+
+ We display a window for the user to select the appropriate audio input,
+ codec, container, and sample rate. Allow a setting of either quality or
+ bitrate. Finally, the output file can be selected and recording can be
+ started.
+
+ The lists are setup using the \l{QAudioRecorder::audioInputs()}{audioInputs()},
+ \l{QAudioRecorder::supportedAudioCodecs()}{supportedAudioCodecs()},
+ \l{QAudioRecorder::supportedContainers()}{supportedContainers()},
+ \l{QAudioRecorder::supportedContainers()}{supportedContainers()}, and
+ \l{QAudioRecorder::supportedAudioSampleRates()}{supportedAudioSampleRates()}
+ methods. The quality slider is setup from 0 (zero) to
+ \l{QMultimedia::VeryHighQuality} with a default value of
+ \l{QMultimedia::NormalQuality}, while the bitrates are hardcoded
+ into the list.
+
+ \image audiorecorder.png
+
+ To record audio we simply create a QAudioRecorder object.
+
+ \code
+ audioRecorder = new QAudioRecorder(this);
+ \endcode
+
+ And setup the lists as described above. The text on the record and pause
+ buttons are toggled depending on the \l{QMediaRecorder::State}{state} of
+ the \c audioRecorder object. This means that if the state is
+ \l{QMediaRecorder::StoppedState} then the button text will be "Record" and
+ "Pause". In \l{QMediaRecorder::RecordingState} the record button will have
+ the text "Stop", and in \l{QMediaRecorder::PausedState} the pause button
+ will have the text "Resume".
+
+ Pressing the buttons will also result in a toggle based on the state. If
+ recording is stopped, then pressing the record button will setup the
+ \l{QAudioEncoderSettings} based on the values of the selection lists,
+ will set the encoding settings and container on the \c audioRecorder
+ object, and start recording using the
+ \l{QMediaRecorder::record()}{record()} method.
+
+ \code
+ QAudioEncoderSettings settings;
+ settings.setCodec(boxValue(ui->audioCodecBox).toString());
+ settings.setSampleRate(boxValue(ui->sampleRateBox).toInt());
+ settings.setBitRate(boxValue(ui->bitrateBox).toInt());
+ settings.setQuality(QMultimedia::EncodingQuality(ui->qualitySlider->value()));
+ settings.setEncodingMode(ui->constantQualityRadioButton->isChecked() ?
+ QMultimedia::ConstantQualityEncoding :
+ QMultimedia::ConstantBitRateEncoding);
+
+ QString container = boxValue(ui->containerBox).toString();
+
+ audioRecorder->setEncodingSettings(settings, QVideoEncoderSettings(), container);
+ audioRecorder->record();
+ \endcode
+
+ While recording, the status bar of the application is updated with duration information
+ from the \l{QMediaRecorder::durationChanged()}{durationChanged} signal from the
+ \c audioRecorder object.
+
+ \code
+ ui->statusbar->showMessage(tr("Recorded %1 sec").arg(duration / 1000));
+ \endcode
+
+
+
+
+*/
+
+
diff --git a/examples/multimedia/audiorecorder/main.cpp b/examples/multimedia/audiorecorder/main.cpp
new file mode 100644
index 000000000..532cfc86b
--- /dev/null
+++ b/examples/multimedia/audiorecorder/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "audiorecorder.h"
+
+#include <QtWidgets>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ AudioRecorder recorder;
+ recorder.show();
+
+ return app.exec();
+}
diff --git a/examples/multimedia/audiorecorder/qaudiolevel.cpp b/examples/multimedia/audiorecorder/qaudiolevel.cpp
new file mode 100644
index 000000000..1ae034628
--- /dev/null
+++ b/examples/multimedia/audiorecorder/qaudiolevel.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "qaudiolevel.h"
+#include <QPainter>
+
+QAudioLevel::QAudioLevel(QWidget *parent)
+ : QWidget(parent)
+ , m_level(0.0)
+{
+}
+
+void QAudioLevel::setLevel(qreal level)
+{
+ if (m_level != level) {
+ m_level = level;
+ update();
+ }
+}
+
+void QAudioLevel::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+
+ QPainter painter(this);
+ // draw level
+ qreal widthLevel = m_level * width();
+ painter.fillRect(0, 0, widthLevel, height(), Qt::red);
+ // clear the rest of the control
+ painter.fillRect(widthLevel, 0, width(), height(), Qt::black);
+}
diff --git a/examples/multimedia/audiorecorder/qaudiolevel.h b/examples/multimedia/audiorecorder/qaudiolevel.h
new file mode 100644
index 000000000..7a9dd07ce
--- /dev/null
+++ b/examples/multimedia/audiorecorder/qaudiolevel.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 QAUDIOLEVEL_H
+#define QAUDIOLEVEL_H
+
+#include <QWidget>
+
+class QAudioLevel : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit QAudioLevel(QWidget *parent = 0);
+
+ // Using [0; 1.0] range
+ void setLevel(qreal level);
+
+protected:
+ void paintEvent(QPaintEvent *event);
+
+private:
+ qreal m_level;
+};
+
+#endif // QAUDIOLEVEL_H
diff --git a/examples/multimedia/declarative-radio/declarative-radio.pro b/examples/multimedia/declarative-radio/declarative-radio.pro
new file mode 100644
index 000000000..68942fa3f
--- /dev/null
+++ b/examples/multimedia/declarative-radio/declarative-radio.pro
@@ -0,0 +1,9 @@
+QT += qml quick multimedia
+
+SOURCES += main.cpp
+RESOURCES += declarative-radio.qrc
+
+EXAMPLE_FILES += view.qml
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/declarative-radio
+INSTALLS += target
diff --git a/examples/multimedia/declarative-radio/declarative-radio.qrc b/examples/multimedia/declarative-radio/declarative-radio.qrc
new file mode 100644
index 000000000..ed01a64f6
--- /dev/null
+++ b/examples/multimedia/declarative-radio/declarative-radio.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+<file>view.qml</file>
+</qresource>
+</RCC>
+
diff --git a/examples/multimedia/declarative-radio/doc/images/declarative-radio-example.png b/examples/multimedia/declarative-radio/doc/images/declarative-radio-example.png
new file mode 100644
index 000000000..6c0393499
--- /dev/null
+++ b/examples/multimedia/declarative-radio/doc/images/declarative-radio-example.png
Binary files differ
diff --git a/examples/multimedia/declarative-radio/doc/src/declarative-radio.qdoc b/examples/multimedia/declarative-radio/doc/src/declarative-radio.qdoc
new file mode 100644
index 000000000..8b52e6c71
--- /dev/null
+++ b/examples/multimedia/declarative-radio/doc/src/declarative-radio.qdoc
@@ -0,0 +1,35 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example declarative-radio
+ \title Declarative Radio Example
+
+
+*/
+
+
diff --git a/examples/multimedia/declarative-radio/main.cpp b/examples/multimedia/declarative-radio/main.cpp
new file mode 100644
index 000000000..09f0e8e88
--- /dev/null
+++ b/examples/multimedia/declarative-radio/main.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+ ** Contact: http://www.qt-project.org/legal
+ **
+ ** This file is part of the demonstration applications 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 Digia Plc 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 <QGuiApplication>
+
+#include <qqml.h>
+#include <QtQuick/qquickview.h>
+
+
+int main(int argc, char ** argv)
+{
+ QGuiApplication app(argc, argv);
+
+ QQuickView view;
+
+ view.setSource(QUrl("qrc:view.qml"));
+ view.show();
+
+ return app.exec();
+}
+
diff --git a/examples/multimedia/declarative-radio/view.qml b/examples/multimedia/declarative-radio/view.qml
new file mode 100644
index 000000000..6c59ba66e
--- /dev/null
+++ b/examples/multimedia/declarative-radio/view.qml
@@ -0,0 +1,191 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+ ** Contact: http://www.qt-project.org/legal
+ **
+ ** 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 Digia Plc 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$
+ **
+ ****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+Rectangle {
+ width: 400; height: 300;
+
+ Radio {
+ id: radio
+ band: Radio.FM
+ }
+
+ Column {
+ anchors.fill: parent
+ anchors.margins: 5
+ spacing: 5
+
+ Row {
+
+ Text {
+ id: freq
+
+ width: 150
+ height: 200
+
+ verticalAlignment: Text.AlignVCenter
+ text: "" + radio.frequency / 1000 + " kHz"
+ }
+ Text {
+ id: sig
+
+ width: 200
+ height: 200
+
+ verticalAlignment: Text.AlignVCenter
+ text: (radio.availability == Radio.Available ? "No Signal " : "No Radio Found")
+ }
+ }
+
+ Row {
+ spacing: 5
+
+ Rectangle {
+ width: 350
+ height: 10
+
+ color: "black"
+
+ Rectangle {
+ width: 5
+ height: 10
+ color: "red"
+
+ y: 0
+ x: (parent.width - 5) * ((radio.frequency - radio.minimumFrequency) / (radio.maximumFrequency -
+ radio.minimumFrequency))
+
+ }
+ }
+ }
+
+
+ Row {
+ spacing: 5
+
+ Rectangle {
+ id: scanDownButton
+ border.color: "black"
+ border.width: 1
+ radius: 2
+
+ width: 90
+ height: 40
+
+ Text {
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ text: "Scan Down"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: radio.scanDown();
+ }
+ }
+ Rectangle {
+ id: freqDownButton
+ border.color: "black"
+ border.width: 1
+ radius: 2
+
+ width: 90
+ height: 40
+
+ Text {
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ text: "Freq Down"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: radio.tuneDown();
+ }
+ }
+ Rectangle {
+ id: freqUpButton
+ border.color: "black"
+ border.width: 1
+ radius: 2
+
+ width: 90
+ height: 40
+
+ Text {
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ text: "Freq Up"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: radio.tuneUp();
+ }
+ }
+ Rectangle {
+ id: scanUpButton
+ border.color: "black"
+ border.width: 1
+ radius: 2
+
+ width: 90
+ height: 40
+
+ Text {
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ text: "Scan Up"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: radio.scanUp();
+ }
+ }
+ }
+ }
+}
diff --git a/examples/multimedia/multimedia.pro b/examples/multimedia/multimedia.pro
new file mode 100644
index 000000000..020ddaa9b
--- /dev/null
+++ b/examples/multimedia/multimedia.pro
@@ -0,0 +1,25 @@
+TEMPLATE = subdirs
+
+SUBDIRS += audiodecoder
+
+# These examples all need widgets for now (using creator templates that use widgets)
+!isEmpty(QT.widgets.name) {
+ SUBDIRS += \
+ radio \
+ spectrum \
+ audiorecorder \
+ audiodevices \
+ audioinput \
+ audiooutput \
+
+ QT += widgets
+}
+
+!isEmpty(QT.gui.name):!isEmpty(QT.qml.name) {
+ SUBDIRS += \
+ declarative-radio \
+ video
+}
+
+config_openal: SUBDIRS += audioengine
+
diff --git a/examples/multimedia/radio/main.cpp b/examples/multimedia/radio/main.cpp
new file mode 100644
index 000000000..ff4cef64e
--- /dev/null
+++ b/examples/multimedia/radio/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "radio.h"
+
+#include <QtWidgets>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ Radio radio;
+ radio.show();
+
+ return app.exec();
+};
diff --git a/examples/multimedia/radio/radio.cpp b/examples/multimedia/radio/radio.cpp
new file mode 100644
index 000000000..24edccf08
--- /dev/null
+++ b/examples/multimedia/radio/radio.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "radio.h"
+
+Radio::Radio()
+{
+ radio = new QRadioTuner;
+ connect(radio, SIGNAL(error(QRadioTuner::Error)), this, SLOT(error(QRadioTuner::Error)));
+
+ if (radio->isBandSupported(QRadioTuner::FM))
+ radio->setBand(QRadioTuner::FM);
+
+ QWidget *window = new QWidget;
+ QVBoxLayout *layout = new QVBoxLayout;
+ QHBoxLayout *buttonBar = new QHBoxLayout;
+ QHBoxLayout *topBar = new QHBoxLayout;
+
+ layout->addLayout(topBar);
+
+ freq = new QLabel;
+ freq->setText(QString("%1 kHz").arg(radio->frequency()/1000));
+ topBar->addWidget(freq);
+ connect(radio, SIGNAL(frequencyChanged(int)), SLOT(freqChanged(int)));
+
+ signal = new QLabel;
+ if (radio->isAvailable())
+ signal->setText(tr("No Signal"));
+ else
+ signal->setText(tr("No radio found"));
+ topBar->addWidget(signal);
+ connect(radio, SIGNAL(signalStrengthChanged(int)), SLOT(signalChanged(int)));
+
+ volumeSlider = new QSlider(Qt::Vertical,this);
+ volumeSlider->setRange(0, 100);
+ volumeSlider->setValue(50);
+ connect(volumeSlider, SIGNAL(valueChanged(int)), SLOT(updateVolume(int)));
+ topBar->addWidget(volumeSlider);
+
+ layout->addLayout(buttonBar);
+
+ searchLeft = new QPushButton;
+ searchLeft->setText(tr("scan Down"));
+ connect(searchLeft, SIGNAL(clicked()), SLOT(searchDown()));
+ buttonBar->addWidget(searchLeft);
+
+ left = new QPushButton;
+ left->setText(tr("Freq Down"));
+ connect(left, SIGNAL(clicked()), SLOT(freqDown()));
+ buttonBar->addWidget(left);
+
+ right = new QPushButton;
+ connect(right, SIGNAL(clicked()), SLOT(freqUp()));
+ right->setText(tr("Freq Up"));
+ buttonBar->addWidget(right);
+
+ searchRight = new QPushButton;
+ searchRight->setText(tr("scan Up"));
+ connect(searchRight, SIGNAL(clicked()), SLOT(searchUp()));
+ buttonBar->addWidget(searchRight);
+
+ window->setLayout(layout);
+ setCentralWidget(window);
+ window->show();
+
+ radio->start();
+}
+
+Radio::~Radio()
+{
+}
+
+void Radio::freqUp()
+{
+ int f = radio->frequency();
+ f += radio->frequencyStep(QRadioTuner::FM);
+ radio->setFrequency(f);
+}
+
+void Radio::freqDown()
+{
+ int f = radio->frequency();
+ f -= radio->frequencyStep(QRadioTuner::FM);
+ radio->setFrequency(f);
+}
+
+void Radio::searchUp()
+{
+ radio->searchForward();
+}
+
+void Radio::searchDown()
+{
+ radio->searchBackward();
+}
+
+void Radio::freqChanged(int)
+{
+ freq->setText(QString("%1 kHz").arg(radio->frequency()/1000));
+}
+
+void Radio::signalChanged(int)
+{
+ if(radio->signalStrength() > 25)
+ signal->setText(tr("Got Signal"));
+ else
+ signal->setText(tr("No Signal"));
+}
+
+void Radio::updateVolume(int v)
+{
+ radio->setVolume(v);
+}
+
+void Radio::error(QRadioTuner::Error error)
+{
+ const QMetaObject *metaObj = radio->metaObject();
+ QMetaEnum errorEnum = metaObj->enumerator(metaObj->indexOfEnumerator("Error"));
+ qWarning().nospace() << "Warning: Example application received error QRadioTuner::" << errorEnum.valueToKey(error);
+}
+
diff --git a/examples/multimedia/radio/radio.h b/examples/multimedia/radio/radio.h
new file mode 100644
index 000000000..f59876633
--- /dev/null
+++ b/examples/multimedia/radio/radio.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 RADIO_H
+#define RADIO_H
+
+#include <QtWidgets>
+#include <QRadioTuner>
+
+class Radio : public QMainWindow
+{
+ Q_OBJECT
+public:
+ Radio();
+ ~Radio();
+
+public slots:
+ void freqUp();
+ void freqDown();
+ void searchUp();
+ void searchDown();
+ void freqChanged(int f);
+ void signalChanged(int s);
+ void updateVolume(int v);
+ void error(QRadioTuner::Error error);
+
+private:
+ QLabel *freq;
+ QLabel *signal;
+ QPushButton *left;
+ QPushButton *right;
+ QPushButton *searchLeft;
+ QPushButton *searchRight;
+ QSlider *volumeSlider;
+ QRadioTuner *radio;
+};
+
+#endif // RADIO_H
diff --git a/examples/multimedia/radio/radio.pro b/examples/multimedia/radio/radio.pro
new file mode 100644
index 000000000..1b1a35b34
--- /dev/null
+++ b/examples/multimedia/radio/radio.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = radio
+
+QT += multimedia
+
+HEADERS = \
+ radio.h
+
+SOURCES = \
+ main.cpp \
+ radio.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/radio
+INSTALLS += target
+
+QT+=widgets
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/Array.h b/examples/multimedia/spectrum/3rdparty/fftreal/Array.h
new file mode 100644
index 000000000..a08e3cf2d
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/Array.h
@@ -0,0 +1,97 @@
+/*****************************************************************************
+
+ Array.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (Array_HEADER_INCLUDED)
+#define Array_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class T, long LEN>
+class Array
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ typedef T DataType;
+
+ Array ();
+
+ inline const DataType &
+ operator [] (long pos) const;
+ inline DataType &
+ operator [] (long pos);
+
+ static inline long
+ size ();
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ DataType _data_arr [LEN];
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ Array (const Array &other);
+ Array & operator = (const Array &other);
+ bool operator == (const Array &other);
+ bool operator != (const Array &other);
+
+}; // class Array
+
+
+
+#include "Array.hpp"
+
+
+
+#endif // Array_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/Array.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/Array.hpp
new file mode 100644
index 000000000..8300077e4
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/Array.hpp
@@ -0,0 +1,98 @@
+/*****************************************************************************
+
+ Array.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (Array_CURRENT_CODEHEADER)
+ #error Recursive inclusion of Array code header.
+#endif
+#define Array_CURRENT_CODEHEADER
+
+#if ! defined (Array_CODEHEADER_INCLUDED)
+#define Array_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include <cassert>
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class T, long LEN>
+Array <T, LEN>::Array ()
+{
+ // Nothing
+}
+
+
+
+template <class T, long LEN>
+const typename Array <T, LEN>::DataType & Array <T, LEN>::operator [] (long pos) const
+{
+ assert (pos >= 0);
+ assert (pos < LEN);
+
+ return (_data_arr [pos]);
+}
+
+
+
+template <class T, long LEN>
+typename Array <T, LEN>::DataType & Array <T, LEN>::operator [] (long pos)
+{
+ assert (pos >= 0);
+ assert (pos < LEN);
+
+ return (_data_arr [pos]);
+}
+
+
+
+template <class T, long LEN>
+long Array <T, LEN>::size ()
+{
+ return (LEN);
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+#endif // Array_CODEHEADER_INCLUDED
+
+#undef Array_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/DynArray.h b/examples/multimedia/spectrum/3rdparty/fftreal/DynArray.h
new file mode 100644
index 000000000..8041a0c15
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/DynArray.h
@@ -0,0 +1,100 @@
+/*****************************************************************************
+
+ DynArray.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (DynArray_HEADER_INCLUDED)
+#define DynArray_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class T>
+class DynArray
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ typedef T DataType;
+
+ DynArray ();
+ explicit DynArray (long size);
+ ~DynArray ();
+
+ inline long size () const;
+ inline void resize (long size);
+
+ inline const DataType &
+ operator [] (long pos) const;
+ inline DataType &
+ operator [] (long pos);
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ DataType * _data_ptr;
+ long _len;
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ DynArray (const DynArray &other);
+ DynArray & operator = (const DynArray &other);
+ bool operator == (const DynArray &other);
+ bool operator != (const DynArray &other);
+
+}; // class DynArray
+
+
+
+#include "DynArray.hpp"
+
+
+
+#endif // DynArray_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/DynArray.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/DynArray.hpp
new file mode 100644
index 000000000..e62b10f88
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/DynArray.hpp
@@ -0,0 +1,143 @@
+/*****************************************************************************
+
+ DynArray.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (DynArray_CURRENT_CODEHEADER)
+ #error Recursive inclusion of DynArray code header.
+#endif
+#define DynArray_CURRENT_CODEHEADER
+
+#if ! defined (DynArray_CODEHEADER_INCLUDED)
+#define DynArray_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include <cassert>
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class T>
+DynArray <T>::DynArray ()
+: _data_ptr (0)
+, _len (0)
+{
+ // Nothing
+}
+
+
+
+template <class T>
+DynArray <T>::DynArray (long size)
+: _data_ptr (0)
+, _len (0)
+{
+ assert (size >= 0);
+ if (size > 0)
+ {
+ _data_ptr = new DataType [size];
+ _len = size;
+ }
+}
+
+
+
+template <class T>
+DynArray <T>::~DynArray ()
+{
+ delete [] _data_ptr;
+ _data_ptr = 0;
+ _len = 0;
+}
+
+
+
+template <class T>
+long DynArray <T>::size () const
+{
+ return (_len);
+}
+
+
+
+template <class T>
+void DynArray <T>::resize (long size)
+{
+ assert (size >= 0);
+ if (size > 0)
+ {
+ DataType * old_data_ptr = _data_ptr;
+ DataType * tmp_data_ptr = new DataType [size];
+
+ _data_ptr = tmp_data_ptr;
+ _len = size;
+
+ delete [] old_data_ptr;
+ }
+}
+
+
+
+template <class T>
+const typename DynArray <T>::DataType & DynArray <T>::operator [] (long pos) const
+{
+ assert (pos >= 0);
+ assert (pos < _len);
+
+ return (_data_ptr [pos]);
+}
+
+
+
+template <class T>
+typename DynArray <T>::DataType & DynArray <T>::operator [] (long pos)
+{
+ assert (pos >= 0);
+ assert (pos < _len);
+
+ return (_data_ptr [pos]);
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+#endif // DynArray_CODEHEADER_INCLUDED
+
+#undef DynArray_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.dsp b/examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.dsp
new file mode 100644
index 000000000..fe970db08
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.dsp
@@ -0,0 +1,273 @@
+# Microsoft Developer Studio Project File - Name="FFTReal" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=FFTReal - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "FFTReal.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "FFTReal.mak" CFG="FFTReal - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "FFTReal - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "FFTReal - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "FFTReal - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GR /GX /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x40c /d "NDEBUG"
+# ADD RSC /l 0x40c /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "FFTReal - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /G6 /MTd /W3 /Gm /GR /GX /Zi /Od /Gf /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0x40c /d "_DEBUG"
+# ADD RSC /l 0x40c /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "FFTReal - Win32 Release"
+# Name "FFTReal - Win32 Debug"
+# Begin Group "Library"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Array.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Array.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\def.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\DynArray.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\DynArray.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTReal.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTReal.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTRealFixLen.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTRealFixLen.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTRealFixLenParam.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTRealPassDirect.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTRealPassDirect.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTRealPassInverse.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTRealPassInverse.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTRealSelect.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTRealSelect.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTRealUseTrigo.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FFTRealUseTrigo.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\OscSinCos.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\OscSinCos.hpp
+# End Source File
+# End Group
+# Begin Group "Test"
+
+# PROP Default_Filter ""
+# Begin Group "stopwatch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\stopwatch\ClockCycleCounter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\stopwatch\ClockCycleCounter.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\stopwatch\ClockCycleCounter.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\stopwatch\def.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\stopwatch\fnc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\stopwatch\fnc.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\stopwatch\Int64.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\stopwatch\StopWatch.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\stopwatch\StopWatch.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\stopwatch\StopWatch.hpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\test.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\test_fnc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\test_fnc.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\test_settings.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TestAccuracy.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TestAccuracy.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TestHelperFixLen.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TestHelperFixLen.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TestHelperNormal.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TestHelperNormal.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TestSpeed.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TestSpeed.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TestWhiteNoiseGen.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TestWhiteNoiseGen.hpp
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.dsw b/examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.dsw
new file mode 100644
index 000000000..076b0aeb8
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "FFTReal"=.\FFTReal.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.h b/examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.h
new file mode 100644
index 000000000..9fb272503
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.h
@@ -0,0 +1,142 @@
+/*****************************************************************************
+
+ FFTReal.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (FFTReal_HEADER_INCLUDED)
+#define FFTReal_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "def.h"
+#include "DynArray.h"
+#include "OscSinCos.h"
+
+
+
+template <class DT>
+class FFTReal
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ enum { MAX_BIT_DEPTH = 30 }; // So length can be represented as long int
+
+ typedef DT DataType;
+
+ explicit FFTReal (long length);
+ virtual ~FFTReal () {}
+
+ long get_length () const;
+ void do_fft (DataType f [], const DataType x []) const;
+ void do_ifft (const DataType f [], DataType x []) const;
+ void rescale (DataType x []) const;
+ DataType * use_buffer () const;
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ // Over this bit depth, we use direct calculation for sin/cos
+ enum { TRIGO_BD_LIMIT = 12 };
+
+ typedef OscSinCos <DataType> OscType;
+
+ void init_br_lut ();
+ void init_trigo_lut ();
+ void init_trigo_osc ();
+
+ FORCEINLINE const long *
+ get_br_ptr () const;
+ FORCEINLINE const DataType *
+ get_trigo_ptr (int level) const;
+ FORCEINLINE long
+ get_trigo_level_index (int level) const;
+
+ inline void compute_fft_general (DataType f [], const DataType x []) const;
+ inline void compute_direct_pass_1_2 (DataType df [], const DataType x []) const;
+ inline void compute_direct_pass_3 (DataType df [], const DataType sf []) const;
+ inline void compute_direct_pass_n (DataType df [], const DataType sf [], int pass) const;
+ inline void compute_direct_pass_n_lut (DataType df [], const DataType sf [], int pass) const;
+ inline void compute_direct_pass_n_osc (DataType df [], const DataType sf [], int pass) const;
+
+ inline void compute_ifft_general (const DataType f [], DataType x []) const;
+ inline void compute_inverse_pass_n (DataType df [], const DataType sf [], int pass) const;
+ inline void compute_inverse_pass_n_osc (DataType df [], const DataType sf [], int pass) const;
+ inline void compute_inverse_pass_n_lut (DataType df [], const DataType sf [], int pass) const;
+ inline void compute_inverse_pass_3 (DataType df [], const DataType sf []) const;
+ inline void compute_inverse_pass_1_2 (DataType x [], const DataType sf []) const;
+
+ const long _length;
+ const int _nbr_bits;
+ DynArray <long>
+ _br_lut;
+ DynArray <DataType>
+ _trigo_lut;
+ mutable DynArray <DataType>
+ _buffer;
+ mutable DynArray <OscType>
+ _trigo_osc;
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ FFTReal ();
+ FFTReal (const FFTReal &other);
+ FFTReal & operator = (const FFTReal &other);
+ bool operator == (const FFTReal &other);
+ bool operator != (const FFTReal &other);
+
+}; // class FFTReal
+
+
+
+#include "FFTReal.hpp"
+
+
+
+#endif // FFTReal_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.hpp
new file mode 100644
index 000000000..335d771dc
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTReal.hpp
@@ -0,0 +1,916 @@
+/*****************************************************************************
+
+ FFTReal.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (FFTReal_CURRENT_CODEHEADER)
+ #error Recursive inclusion of FFTReal code header.
+#endif
+#define FFTReal_CURRENT_CODEHEADER
+
+#if ! defined (FFTReal_CODEHEADER_INCLUDED)
+#define FFTReal_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include <cassert>
+#include <cmath>
+
+
+
+static inline bool FFTReal_is_pow2 (long x)
+{
+ assert (x > 0);
+
+ return ((x & -x) == x);
+}
+
+
+
+static inline int FFTReal_get_next_pow2 (long x)
+{
+ --x;
+
+ int p = 0;
+ while ((x & ~0xFFFFL) != 0)
+ {
+ p += 16;
+ x >>= 16;
+ }
+ while ((x & ~0xFL) != 0)
+ {
+ p += 4;
+ x >>= 4;
+ }
+ while (x > 0)
+ {
+ ++p;
+ x >>= 1;
+ }
+
+ return (p);
+}
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*
+==============================================================================
+Name: ctor
+Input parameters:
+ - length: length of the array on which we want to do a FFT. Range: power of
+ 2 only, > 0.
+Throws: std::bad_alloc
+==============================================================================
+*/
+
+template <class DT>
+FFTReal <DT>::FFTReal (long length)
+: _length (length)
+, _nbr_bits (FFTReal_get_next_pow2 (length))
+, _br_lut ()
+, _trigo_lut ()
+, _buffer (length)
+, _trigo_osc ()
+{
+ assert (FFTReal_is_pow2 (length));
+ assert (_nbr_bits <= MAX_BIT_DEPTH);
+
+ init_br_lut ();
+ init_trigo_lut ();
+ init_trigo_osc ();
+}
+
+
+
+/*
+==============================================================================
+Name: get_length
+Description:
+ Returns the number of points processed by this FFT object.
+Returns: The number of points, power of 2, > 0.
+Throws: Nothing
+==============================================================================
+*/
+
+template <class DT>
+long FFTReal <DT>::get_length () const
+{
+ return (_length);
+}
+
+
+
+/*
+==============================================================================
+Name: do_fft
+Description:
+ Compute the FFT of the array.
+Input parameters:
+ - x: pointer on the source array (time).
+Output parameters:
+ - f: pointer on the destination array (frequencies).
+ f [0...length(x)/2] = real values,
+ f [length(x)/2+1...length(x)-1] = negative imaginary values of
+ coefficents 1...length(x)/2-1.
+Throws: Nothing
+==============================================================================
+*/
+
+template <class DT>
+void FFTReal <DT>::do_fft (DataType f [], const DataType x []) const
+{
+ assert (f != 0);
+ assert (f != use_buffer ());
+ assert (x != 0);
+ assert (x != use_buffer ());
+ assert (x != f);
+
+ // General case
+ if (_nbr_bits > 2)
+ {
+ compute_fft_general (f, x);
+ }
+
+ // 4-point FFT
+ else if (_nbr_bits == 2)
+ {
+ f [1] = x [0] - x [2];
+ f [3] = x [1] - x [3];
+
+ const DataType b_0 = x [0] + x [2];
+ const DataType b_2 = x [1] + x [3];
+
+ f [0] = b_0 + b_2;
+ f [2] = b_0 - b_2;
+ }
+
+ // 2-point FFT
+ else if (_nbr_bits == 1)
+ {
+ f [0] = x [0] + x [1];
+ f [1] = x [0] - x [1];
+ }
+
+ // 1-point FFT
+ else
+ {
+ f [0] = x [0];
+ }
+}
+
+
+
+/*
+==============================================================================
+Name: do_ifft
+Description:
+ Compute the inverse FFT of the array. Note that data must be post-scaled:
+ IFFT (FFT (x)) = x * length (x).
+Input parameters:
+ - f: pointer on the source array (frequencies).
+ f [0...length(x)/2] = real values
+ f [length(x)/2+1...length(x)-1] = negative imaginary values of
+ coefficents 1...length(x)/2-1.
+Output parameters:
+ - x: pointer on the destination array (time).
+Throws: Nothing
+==============================================================================
+*/
+
+template <class DT>
+void FFTReal <DT>::do_ifft (const DataType f [], DataType x []) const
+{
+ assert (f != 0);
+ assert (f != use_buffer ());
+ assert (x != 0);
+ assert (x != use_buffer ());
+ assert (x != f);
+
+ // General case
+ if (_nbr_bits > 2)
+ {
+ compute_ifft_general (f, x);
+ }
+
+ // 4-point IFFT
+ else if (_nbr_bits == 2)
+ {
+ const DataType b_0 = f [0] + f [2];
+ const DataType b_2 = f [0] - f [2];
+
+ x [0] = b_0 + f [1] * 2;
+ x [2] = b_0 - f [1] * 2;
+ x [1] = b_2 + f [3] * 2;
+ x [3] = b_2 - f [3] * 2;
+ }
+
+ // 2-point IFFT
+ else if (_nbr_bits == 1)
+ {
+ x [0] = f [0] + f [1];
+ x [1] = f [0] - f [1];
+ }
+
+ // 1-point IFFT
+ else
+ {
+ x [0] = f [0];
+ }
+}
+
+
+
+/*
+==============================================================================
+Name: rescale
+Description:
+ Scale an array by divide each element by its length. This function should
+ be called after FFT + IFFT.
+Input parameters:
+ - x: pointer on array to rescale (time or frequency).
+Throws: Nothing
+==============================================================================
+*/
+
+template <class DT>
+void FFTReal <DT>::rescale (DataType x []) const
+{
+ const DataType mul = DataType (1.0 / _length);
+
+ if (_length < 4)
+ {
+ long i = _length - 1;
+ do
+ {
+ x [i] *= mul;
+ --i;
+ }
+ while (i >= 0);
+ }
+
+ else
+ {
+ assert ((_length & 3) == 0);
+
+ // Could be optimized with SIMD instruction sets (needs alignment check)
+ long i = _length - 4;
+ do
+ {
+ x [i + 0] *= mul;
+ x [i + 1] *= mul;
+ x [i + 2] *= mul;
+ x [i + 3] *= mul;
+ i -= 4;
+ }
+ while (i >= 0);
+ }
+}
+
+
+
+/*
+==============================================================================
+Name: use_buffer
+Description:
+ Access the internal buffer, whose length is the FFT one.
+ Buffer content will be erased at each do_fft() / do_ifft() call!
+ This buffer cannot be used as:
+ - source for FFT or IFFT done with this object
+ - destination for FFT or IFFT done with this object
+Returns:
+ Buffer start address
+Throws: Nothing
+==============================================================================
+*/
+
+template <class DT>
+typename FFTReal <DT>::DataType * FFTReal <DT>::use_buffer () const
+{
+ return (&_buffer [0]);
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class DT>
+void FFTReal <DT>::init_br_lut ()
+{
+ const long length = 1L << _nbr_bits;
+ _br_lut.resize (length);
+
+ _br_lut [0] = 0;
+ long br_index = 0;
+ for (long cnt = 1; cnt < length; ++cnt)
+ {
+ // ++br_index (bit reversed)
+ long bit = length >> 1;
+ while (((br_index ^= bit) & bit) == 0)
+ {
+ bit >>= 1;
+ }
+
+ _br_lut [cnt] = br_index;
+ }
+}
+
+
+
+template <class DT>
+void FFTReal <DT>::init_trigo_lut ()
+{
+ using namespace std;
+
+ if (_nbr_bits > 3)
+ {
+ const long total_len = (1L << (_nbr_bits - 1)) - 4;
+ _trigo_lut.resize (total_len);
+
+ for (int level = 3; level < _nbr_bits; ++level)
+ {
+ const long level_len = 1L << (level - 1);
+ DataType * const level_ptr =
+ &_trigo_lut [get_trigo_level_index (level)];
+ const double mul = PI / (level_len << 1);
+
+ for (long i = 0; i < level_len; ++ i)
+ {
+ level_ptr [i] = static_cast <DataType> (cos (i * mul));
+ }
+ }
+ }
+}
+
+
+
+template <class DT>
+void FFTReal <DT>::init_trigo_osc ()
+{
+ const int nbr_osc = _nbr_bits - TRIGO_BD_LIMIT;
+ if (nbr_osc > 0)
+ {
+ _trigo_osc.resize (nbr_osc);
+
+ for (int osc_cnt = 0; osc_cnt < nbr_osc; ++osc_cnt)
+ {
+ OscType & osc = _trigo_osc [osc_cnt];
+
+ const long len = 1L << (TRIGO_BD_LIMIT + osc_cnt);
+ const double mul = (0.5 * PI) / len;
+ osc.set_step (mul);
+ }
+ }
+}
+
+
+
+template <class DT>
+const long * FFTReal <DT>::get_br_ptr () const
+{
+ return (&_br_lut [0]);
+}
+
+
+
+template <class DT>
+const typename FFTReal <DT>::DataType * FFTReal <DT>::get_trigo_ptr (int level) const
+{
+ assert (level >= 3);
+
+ return (&_trigo_lut [get_trigo_level_index (level)]);
+}
+
+
+
+template <class DT>
+long FFTReal <DT>::get_trigo_level_index (int level) const
+{
+ assert (level >= 3);
+
+ return ((1L << (level - 1)) - 4);
+}
+
+
+
+// Transform in several passes
+template <class DT>
+void FFTReal <DT>::compute_fft_general (DataType f [], const DataType x []) const
+{
+ assert (f != 0);
+ assert (f != use_buffer ());
+ assert (x != 0);
+ assert (x != use_buffer ());
+ assert (x != f);
+
+ DataType * sf;
+ DataType * df;
+
+ if ((_nbr_bits & 1) != 0)
+ {
+ df = use_buffer ();
+ sf = f;
+ }
+ else
+ {
+ df = f;
+ sf = use_buffer ();
+ }
+
+ compute_direct_pass_1_2 (df, x);
+ compute_direct_pass_3 (sf, df);
+
+ for (int pass = 3; pass < _nbr_bits; ++ pass)
+ {
+ compute_direct_pass_n (df, sf, pass);
+
+ DataType * const temp_ptr = df;
+ df = sf;
+ sf = temp_ptr;
+ }
+}
+
+
+
+template <class DT>
+void FFTReal <DT>::compute_direct_pass_1_2 (DataType df [], const DataType x []) const
+{
+ assert (df != 0);
+ assert (x != 0);
+ assert (df != x);
+
+ const long * const bit_rev_lut_ptr = get_br_ptr ();
+ long coef_index = 0;
+ do
+ {
+ const long rev_index_0 = bit_rev_lut_ptr [coef_index];
+ const long rev_index_1 = bit_rev_lut_ptr [coef_index + 1];
+ const long rev_index_2 = bit_rev_lut_ptr [coef_index + 2];
+ const long rev_index_3 = bit_rev_lut_ptr [coef_index + 3];
+
+ DataType * const df2 = df + coef_index;
+ df2 [1] = x [rev_index_0] - x [rev_index_1];
+ df2 [3] = x [rev_index_2] - x [rev_index_3];
+
+ const DataType sf_0 = x [rev_index_0] + x [rev_index_1];
+ const DataType sf_2 = x [rev_index_2] + x [rev_index_3];
+
+ df2 [0] = sf_0 + sf_2;
+ df2 [2] = sf_0 - sf_2;
+
+ coef_index += 4;
+ }
+ while (coef_index < _length);
+}
+
+
+
+template <class DT>
+void FFTReal <DT>::compute_direct_pass_3 (DataType df [], const DataType sf []) const
+{
+ assert (df != 0);
+ assert (sf != 0);
+ assert (df != sf);
+
+ const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
+ long coef_index = 0;
+ do
+ {
+ DataType v;
+
+ df [coef_index] = sf [coef_index] + sf [coef_index + 4];
+ df [coef_index + 4] = sf [coef_index] - sf [coef_index + 4];
+ df [coef_index + 2] = sf [coef_index + 2];
+ df [coef_index + 6] = sf [coef_index + 6];
+
+ v = (sf [coef_index + 5] - sf [coef_index + 7]) * sqrt2_2;
+ df [coef_index + 1] = sf [coef_index + 1] + v;
+ df [coef_index + 3] = sf [coef_index + 1] - v;
+
+ v = (sf [coef_index + 5] + sf [coef_index + 7]) * sqrt2_2;
+ df [coef_index + 5] = v + sf [coef_index + 3];
+ df [coef_index + 7] = v - sf [coef_index + 3];
+
+ coef_index += 8;
+ }
+ while (coef_index < _length);
+}
+
+
+
+template <class DT>
+void FFTReal <DT>::compute_direct_pass_n (DataType df [], const DataType sf [], int pass) const
+{
+ assert (df != 0);
+ assert (sf != 0);
+ assert (df != sf);
+ assert (pass >= 3);
+ assert (pass < _nbr_bits);
+
+ if (pass <= TRIGO_BD_LIMIT)
+ {
+ compute_direct_pass_n_lut (df, sf, pass);
+ }
+ else
+ {
+ compute_direct_pass_n_osc (df, sf, pass);
+ }
+}
+
+
+
+template <class DT>
+void FFTReal <DT>::compute_direct_pass_n_lut (DataType df [], const DataType sf [], int pass) const
+{
+ assert (df != 0);
+ assert (sf != 0);
+ assert (df != sf);
+ assert (pass >= 3);
+ assert (pass < _nbr_bits);
+
+ const long nbr_coef = 1 << pass;
+ const long h_nbr_coef = nbr_coef >> 1;
+ const long d_nbr_coef = nbr_coef << 1;
+ long coef_index = 0;
+ const DataType * const cos_ptr = get_trigo_ptr (pass);
+ do
+ {
+ const DataType * const sf1r = sf + coef_index;
+ const DataType * const sf2r = sf1r + nbr_coef;
+ DataType * const dfr = df + coef_index;
+ DataType * const dfi = dfr + nbr_coef;
+
+ // Extreme coefficients are always real
+ dfr [0] = sf1r [0] + sf2r [0];
+ dfi [0] = sf1r [0] - sf2r [0]; // dfr [nbr_coef] =
+ dfr [h_nbr_coef] = sf1r [h_nbr_coef];
+ dfi [h_nbr_coef] = sf2r [h_nbr_coef];
+
+ // Others are conjugate complex numbers
+ const DataType * const sf1i = sf1r + h_nbr_coef;
+ const DataType * const sf2i = sf1i + nbr_coef;
+ for (long i = 1; i < h_nbr_coef; ++ i)
+ {
+ const DataType c = cos_ptr [i]; // cos (i*PI/nbr_coef);
+ const DataType s = cos_ptr [h_nbr_coef - i]; // sin (i*PI/nbr_coef);
+ DataType v;
+
+ v = sf2r [i] * c - sf2i [i] * s;
+ dfr [i] = sf1r [i] + v;
+ dfi [-i] = sf1r [i] - v; // dfr [nbr_coef - i] =
+
+ v = sf2r [i] * s + sf2i [i] * c;
+ dfi [i] = v + sf1i [i];
+ dfi [nbr_coef - i] = v - sf1i [i];
+ }
+
+ coef_index += d_nbr_coef;
+ }
+ while (coef_index < _length);
+}
+
+
+
+template <class DT>
+void FFTReal <DT>::compute_direct_pass_n_osc (DataType df [], const DataType sf [], int pass) const
+{
+ assert (df != 0);
+ assert (sf != 0);
+ assert (df != sf);
+ assert (pass > TRIGO_BD_LIMIT);
+ assert (pass < _nbr_bits);
+
+ const long nbr_coef = 1 << pass;
+ const long h_nbr_coef = nbr_coef >> 1;
+ const long d_nbr_coef = nbr_coef << 1;
+ long coef_index = 0;
+ OscType & osc = _trigo_osc [pass - (TRIGO_BD_LIMIT + 1)];
+ do
+ {
+ const DataType * const sf1r = sf + coef_index;
+ const DataType * const sf2r = sf1r + nbr_coef;
+ DataType * const dfr = df + coef_index;
+ DataType * const dfi = dfr + nbr_coef;
+
+ osc.clear_buffers ();
+
+ // Extreme coefficients are always real
+ dfr [0] = sf1r [0] + sf2r [0];
+ dfi [0] = sf1r [0] - sf2r [0]; // dfr [nbr_coef] =
+ dfr [h_nbr_coef] = sf1r [h_nbr_coef];
+ dfi [h_nbr_coef] = sf2r [h_nbr_coef];
+
+ // Others are conjugate complex numbers
+ const DataType * const sf1i = sf1r + h_nbr_coef;
+ const DataType * const sf2i = sf1i + nbr_coef;
+ for (long i = 1; i < h_nbr_coef; ++ i)
+ {
+ osc.step ();
+ const DataType c = osc.get_cos ();
+ const DataType s = osc.get_sin ();
+ DataType v;
+
+ v = sf2r [i] * c - sf2i [i] * s;
+ dfr [i] = sf1r [i] + v;
+ dfi [-i] = sf1r [i] - v; // dfr [nbr_coef - i] =
+
+ v = sf2r [i] * s + sf2i [i] * c;
+ dfi [i] = v + sf1i [i];
+ dfi [nbr_coef - i] = v - sf1i [i];
+ }
+
+ coef_index += d_nbr_coef;
+ }
+ while (coef_index < _length);
+}
+
+
+
+// Transform in several pass
+template <class DT>
+void FFTReal <DT>::compute_ifft_general (const DataType f [], DataType x []) const
+{
+ assert (f != 0);
+ assert (f != use_buffer ());
+ assert (x != 0);
+ assert (x != use_buffer ());
+ assert (x != f);
+
+ DataType * sf = const_cast <DataType *> (f);
+ DataType * df;
+ DataType * df_temp;
+
+ if (_nbr_bits & 1)
+ {
+ df = use_buffer ();
+ df_temp = x;
+ }
+ else
+ {
+ df = x;
+ df_temp = use_buffer ();
+ }
+
+ for (int pass = _nbr_bits - 1; pass >= 3; -- pass)
+ {
+ compute_inverse_pass_n (df, sf, pass);
+
+ if (pass < _nbr_bits - 1)
+ {
+ DataType * const temp_ptr = df;
+ df = sf;
+ sf = temp_ptr;
+ }
+ else
+ {
+ sf = df;
+ df = df_temp;
+ }
+ }
+
+ compute_inverse_pass_3 (df, sf);
+ compute_inverse_pass_1_2 (x, df);
+}
+
+
+
+template <class DT>
+void FFTReal <DT>::compute_inverse_pass_n (DataType df [], const DataType sf [], int pass) const
+{
+ assert (df != 0);
+ assert (sf != 0);
+ assert (df != sf);
+ assert (pass >= 3);
+ assert (pass < _nbr_bits);
+
+ if (pass <= TRIGO_BD_LIMIT)
+ {
+ compute_inverse_pass_n_lut (df, sf, pass);
+ }
+ else
+ {
+ compute_inverse_pass_n_osc (df, sf, pass);
+ }
+}
+
+
+
+template <class DT>
+void FFTReal <DT>::compute_inverse_pass_n_lut (DataType df [], const DataType sf [], int pass) const
+{
+ assert (df != 0);
+ assert (sf != 0);
+ assert (df != sf);
+ assert (pass >= 3);
+ assert (pass < _nbr_bits);
+
+ const long nbr_coef = 1 << pass;
+ const long h_nbr_coef = nbr_coef >> 1;
+ const long d_nbr_coef = nbr_coef << 1;
+ long coef_index = 0;
+ const DataType * const cos_ptr = get_trigo_ptr (pass);
+ do
+ {
+ const DataType * const sfr = sf + coef_index;
+ const DataType * const sfi = sfr + nbr_coef;
+ DataType * const df1r = df + coef_index;
+ DataType * const df2r = df1r + nbr_coef;
+
+ // Extreme coefficients are always real
+ df1r [0] = sfr [0] + sfi [0]; // + sfr [nbr_coef]
+ df2r [0] = sfr [0] - sfi [0]; // - sfr [nbr_coef]
+ df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
+ df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
+
+ // Others are conjugate complex numbers
+ DataType * const df1i = df1r + h_nbr_coef;
+ DataType * const df2i = df1i + nbr_coef;
+ for (long i = 1; i < h_nbr_coef; ++ i)
+ {
+ df1r [i] = sfr [i] + sfi [-i]; // + sfr [nbr_coef - i]
+ df1i [i] = sfi [i] - sfi [nbr_coef - i];
+
+ const DataType c = cos_ptr [i]; // cos (i*PI/nbr_coef);
+ const DataType s = cos_ptr [h_nbr_coef - i]; // sin (i*PI/nbr_coef);
+ const DataType vr = sfr [i] - sfi [-i]; // - sfr [nbr_coef - i]
+ const DataType vi = sfi [i] + sfi [nbr_coef - i];
+
+ df2r [i] = vr * c + vi * s;
+ df2i [i] = vi * c - vr * s;
+ }
+
+ coef_index += d_nbr_coef;
+ }
+ while (coef_index < _length);
+}
+
+
+
+template <class DT>
+void FFTReal <DT>::compute_inverse_pass_n_osc (DataType df [], const DataType sf [], int pass) const
+{
+ assert (df != 0);
+ assert (sf != 0);
+ assert (df != sf);
+ assert (pass > TRIGO_BD_LIMIT);
+ assert (pass < _nbr_bits);
+
+ const long nbr_coef = 1 << pass;
+ const long h_nbr_coef = nbr_coef >> 1;
+ const long d_nbr_coef = nbr_coef << 1;
+ long coef_index = 0;
+ OscType & osc = _trigo_osc [pass - (TRIGO_BD_LIMIT + 1)];
+ do
+ {
+ const DataType * const sfr = sf + coef_index;
+ const DataType * const sfi = sfr + nbr_coef;
+ DataType * const df1r = df + coef_index;
+ DataType * const df2r = df1r + nbr_coef;
+
+ osc.clear_buffers ();
+
+ // Extreme coefficients are always real
+ df1r [0] = sfr [0] + sfi [0]; // + sfr [nbr_coef]
+ df2r [0] = sfr [0] - sfi [0]; // - sfr [nbr_coef]
+ df1r [h_nbr_coef] = sfr [h_nbr_coef] * 2;
+ df2r [h_nbr_coef] = sfi [h_nbr_coef] * 2;
+
+ // Others are conjugate complex numbers
+ DataType * const df1i = df1r + h_nbr_coef;
+ DataType * const df2i = df1i + nbr_coef;
+ for (long i = 1; i < h_nbr_coef; ++ i)
+ {
+ df1r [i] = sfr [i] + sfi [-i]; // + sfr [nbr_coef - i]
+ df1i [i] = sfi [i] - sfi [nbr_coef - i];
+
+ osc.step ();
+ const DataType c = osc.get_cos ();
+ const DataType s = osc.get_sin ();
+ const DataType vr = sfr [i] - sfi [-i]; // - sfr [nbr_coef - i]
+ const DataType vi = sfi [i] + sfi [nbr_coef - i];
+
+ df2r [i] = vr * c + vi * s;
+ df2i [i] = vi * c - vr * s;
+ }
+
+ coef_index += d_nbr_coef;
+ }
+ while (coef_index < _length);
+}
+
+
+
+template <class DT>
+void FFTReal <DT>::compute_inverse_pass_3 (DataType df [], const DataType sf []) const
+{
+ assert (df != 0);
+ assert (sf != 0);
+ assert (df != sf);
+
+ const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
+ long coef_index = 0;
+ do
+ {
+ df [coef_index] = sf [coef_index] + sf [coef_index + 4];
+ df [coef_index + 4] = sf [coef_index] - sf [coef_index + 4];
+ df [coef_index + 2] = sf [coef_index + 2] * 2;
+ df [coef_index + 6] = sf [coef_index + 6] * 2;
+
+ df [coef_index + 1] = sf [coef_index + 1] + sf [coef_index + 3];
+ df [coef_index + 3] = sf [coef_index + 5] - sf [coef_index + 7];
+
+ const DataType vr = sf [coef_index + 1] - sf [coef_index + 3];
+ const DataType vi = sf [coef_index + 5] + sf [coef_index + 7];
+
+ df [coef_index + 5] = (vr + vi) * sqrt2_2;
+ df [coef_index + 7] = (vi - vr) * sqrt2_2;
+
+ coef_index += 8;
+ }
+ while (coef_index < _length);
+}
+
+
+
+template <class DT>
+void FFTReal <DT>::compute_inverse_pass_1_2 (DataType x [], const DataType sf []) const
+{
+ assert (x != 0);
+ assert (sf != 0);
+ assert (x != sf);
+
+ const long * bit_rev_lut_ptr = get_br_ptr ();
+ const DataType * sf2 = sf;
+ long coef_index = 0;
+ do
+ {
+ {
+ const DataType b_0 = sf2 [0] + sf2 [2];
+ const DataType b_2 = sf2 [0] - sf2 [2];
+ const DataType b_1 = sf2 [1] * 2;
+ const DataType b_3 = sf2 [3] * 2;
+
+ x [bit_rev_lut_ptr [0]] = b_0 + b_1;
+ x [bit_rev_lut_ptr [1]] = b_0 - b_1;
+ x [bit_rev_lut_ptr [2]] = b_2 + b_3;
+ x [bit_rev_lut_ptr [3]] = b_2 - b_3;
+ }
+ {
+ const DataType b_0 = sf2 [4] + sf2 [6];
+ const DataType b_2 = sf2 [4] - sf2 [6];
+ const DataType b_1 = sf2 [5] * 2;
+ const DataType b_3 = sf2 [7] * 2;
+
+ x [bit_rev_lut_ptr [4]] = b_0 + b_1;
+ x [bit_rev_lut_ptr [5]] = b_0 - b_1;
+ x [bit_rev_lut_ptr [6]] = b_2 + b_3;
+ x [bit_rev_lut_ptr [7]] = b_2 - b_3;
+ }
+
+ sf2 += 8;
+ coef_index += 8;
+ bit_rev_lut_ptr += 8;
+ }
+ while (coef_index < _length);
+}
+
+
+
+#endif // FFTReal_CODEHEADER_INCLUDED
+
+#undef FFTReal_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLen.h b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLen.h
new file mode 100644
index 000000000..0b8026688
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLen.h
@@ -0,0 +1,130 @@
+/*****************************************************************************
+
+ FFTRealFixLen.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (FFTRealFixLen_HEADER_INCLUDED)
+#define FFTRealFixLen_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "Array.h"
+#include "DynArray.h"
+#include "FFTRealFixLenParam.h"
+#include "OscSinCos.h"
+
+
+
+template <int LL2>
+class FFTRealFixLen
+{
+ typedef int CompileTimeCheck1 [(LL2 >= 0) ? 1 : -1];
+ typedef int CompileTimeCheck2 [(LL2 <= 30) ? 1 : -1];
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ typedef FFTRealFixLenParam::DataType DataType;
+ typedef OscSinCos <DataType> OscType;
+
+ enum { FFT_LEN_L2 = LL2 };
+ enum { FFT_LEN = 1 << FFT_LEN_L2 };
+
+ FFTRealFixLen ();
+
+ inline long get_length () const;
+ void do_fft (DataType f [], const DataType x []);
+ void do_ifft (const DataType f [], DataType x []);
+ void rescale (DataType x []) const;
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ enum { TRIGO_BD_LIMIT = FFTRealFixLenParam::TRIGO_BD_LIMIT };
+
+ enum { BR_ARR_SIZE_L2 = ((FFT_LEN_L2 - 3) < 0) ? 0 : (FFT_LEN_L2 - 2) };
+ enum { BR_ARR_SIZE = 1 << BR_ARR_SIZE_L2 };
+
+ enum { TRIGO_BD = ((FFT_LEN_L2 - TRIGO_BD_LIMIT) < 0)
+ ? (int)FFT_LEN_L2
+ : (int)TRIGO_BD_LIMIT };
+ enum { TRIGO_TABLE_ARR_SIZE_L2 = (LL2 < 4) ? 0 : (TRIGO_BD - 2) };
+ enum { TRIGO_TABLE_ARR_SIZE = 1 << TRIGO_TABLE_ARR_SIZE_L2 };
+
+ enum { NBR_TRIGO_OSC = FFT_LEN_L2 - TRIGO_BD };
+ enum { TRIGO_OSC_ARR_SIZE = (NBR_TRIGO_OSC > 0) ? NBR_TRIGO_OSC : 1 };
+
+ void build_br_lut ();
+ void build_trigo_lut ();
+ void build_trigo_osc ();
+
+ DynArray <DataType>
+ _buffer;
+ DynArray <long>
+ _br_data;
+ DynArray <DataType>
+ _trigo_data;
+ Array <OscType, TRIGO_OSC_ARR_SIZE>
+ _trigo_osc;
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ FFTRealFixLen (const FFTRealFixLen &other);
+ FFTRealFixLen& operator = (const FFTRealFixLen &other);
+ bool operator == (const FFTRealFixLen &other);
+ bool operator != (const FFTRealFixLen &other);
+
+}; // class FFTRealFixLen
+
+
+
+#include "FFTRealFixLen.hpp"
+
+
+
+#endif // FFTRealFixLen_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp
new file mode 100644
index 000000000..6defb0095
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp
@@ -0,0 +1,322 @@
+/*****************************************************************************
+
+ FFTRealFixLen.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (FFTRealFixLen_CURRENT_CODEHEADER)
+ #error Recursive inclusion of FFTRealFixLen code header.
+#endif
+#define FFTRealFixLen_CURRENT_CODEHEADER
+
+#if ! defined (FFTRealFixLen_CODEHEADER_INCLUDED)
+#define FFTRealFixLen_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "def.h"
+#include "FFTRealPassDirect.h"
+#include "FFTRealPassInverse.h"
+#include "FFTRealSelect.h"
+
+#include <cassert>
+#include <cmath>
+
+namespace std { }
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <int LL2>
+FFTRealFixLen <LL2>::FFTRealFixLen ()
+: _buffer (FFT_LEN)
+, _br_data (BR_ARR_SIZE)
+, _trigo_data (TRIGO_TABLE_ARR_SIZE)
+, _trigo_osc ()
+{
+ build_br_lut ();
+ build_trigo_lut ();
+ build_trigo_osc ();
+}
+
+
+
+template <int LL2>
+long FFTRealFixLen <LL2>::get_length () const
+{
+ return (FFT_LEN);
+}
+
+
+
+// General case
+template <int LL2>
+void FFTRealFixLen <LL2>::do_fft (DataType f [], const DataType x [])
+{
+ assert (f != 0);
+ assert (x != 0);
+ assert (x != f);
+ assert (FFT_LEN_L2 >= 3);
+
+ // Do the transform in several passes
+ const DataType * cos_ptr = &_trigo_data [0];
+ const long * br_ptr = &_br_data [0];
+
+ FFTRealPassDirect <FFT_LEN_L2 - 1>::process (
+ FFT_LEN,
+ f,
+ &_buffer [0],
+ x,
+ cos_ptr,
+ TRIGO_TABLE_ARR_SIZE,
+ br_ptr,
+ &_trigo_osc [0]
+ );
+}
+
+// 4-point FFT
+template <>
+void FFTRealFixLen <2>::do_fft (DataType f [], const DataType x [])
+{
+ assert (f != 0);
+ assert (x != 0);
+ assert (x != f);
+
+ f [1] = x [0] - x [2];
+ f [3] = x [1] - x [3];
+
+ const DataType b_0 = x [0] + x [2];
+ const DataType b_2 = x [1] + x [3];
+
+ f [0] = b_0 + b_2;
+ f [2] = b_0 - b_2;
+}
+
+// 2-point FFT
+template <>
+void FFTRealFixLen <1>::do_fft (DataType f [], const DataType x [])
+{
+ assert (f != 0);
+ assert (x != 0);
+ assert (x != f);
+
+ f [0] = x [0] + x [1];
+ f [1] = x [0] - x [1];
+}
+
+// 1-point FFT
+template <>
+void FFTRealFixLen <0>::do_fft (DataType f [], const DataType x [])
+{
+ assert (f != 0);
+ assert (x != 0);
+
+ f [0] = x [0];
+}
+
+
+
+// General case
+template <int LL2>
+void FFTRealFixLen <LL2>::do_ifft (const DataType f [], DataType x [])
+{
+ assert (f != 0);
+ assert (x != 0);
+ assert (x != f);
+ assert (FFT_LEN_L2 >= 3);
+
+ // Do the transform in several passes
+ DataType * s_ptr =
+ FFTRealSelect <FFT_LEN_L2 & 1>::sel_bin (&_buffer [0], x);
+ DataType * d_ptr =
+ FFTRealSelect <FFT_LEN_L2 & 1>::sel_bin (x, &_buffer [0]);
+ const DataType * cos_ptr = &_trigo_data [0];
+ const long * br_ptr = &_br_data [0];
+
+ FFTRealPassInverse <FFT_LEN_L2 - 1>::process (
+ FFT_LEN,
+ d_ptr,
+ s_ptr,
+ f,
+ cos_ptr,
+ TRIGO_TABLE_ARR_SIZE,
+ br_ptr,
+ &_trigo_osc [0]
+ );
+}
+
+// 4-point IFFT
+template <>
+void FFTRealFixLen <2>::do_ifft (const DataType f [], DataType x [])
+{
+ assert (f != 0);
+ assert (x != 0);
+ assert (x != f);
+
+ const DataType b_0 = f [0] + f [2];
+ const DataType b_2 = f [0] - f [2];
+
+ x [0] = b_0 + f [1] * 2;
+ x [2] = b_0 - f [1] * 2;
+ x [1] = b_2 + f [3] * 2;
+ x [3] = b_2 - f [3] * 2;
+}
+
+// 2-point IFFT
+template <>
+void FFTRealFixLen <1>::do_ifft (const DataType f [], DataType x [])
+{
+ assert (f != 0);
+ assert (x != 0);
+ assert (x != f);
+
+ x [0] = f [0] + f [1];
+ x [1] = f [0] - f [1];
+}
+
+// 1-point IFFT
+template <>
+void FFTRealFixLen <0>::do_ifft (const DataType f [], DataType x [])
+{
+ assert (f != 0);
+ assert (x != 0);
+ assert (x != f);
+
+ x [0] = f [0];
+}
+
+
+
+
+template <int LL2>
+void FFTRealFixLen <LL2>::rescale (DataType x []) const
+{
+ assert (x != 0);
+
+ const DataType mul = DataType (1.0 / FFT_LEN);
+
+ if (FFT_LEN < 4)
+ {
+ long i = FFT_LEN - 1;
+ do
+ {
+ x [i] *= mul;
+ --i;
+ }
+ while (i >= 0);
+ }
+
+ else
+ {
+ assert ((FFT_LEN & 3) == 0);
+
+ // Could be optimized with SIMD instruction sets (needs alignment check)
+ long i = FFT_LEN - 4;
+ do
+ {
+ x [i + 0] *= mul;
+ x [i + 1] *= mul;
+ x [i + 2] *= mul;
+ x [i + 3] *= mul;
+ i -= 4;
+ }
+ while (i >= 0);
+ }
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <int LL2>
+void FFTRealFixLen <LL2>::build_br_lut ()
+{
+ _br_data [0] = 0;
+ for (long cnt = 1; cnt < BR_ARR_SIZE; ++cnt)
+ {
+ long index = cnt << 2;
+ long br_index = 0;
+
+ int bit_cnt = FFT_LEN_L2;
+ do
+ {
+ br_index <<= 1;
+ br_index += (index & 1);
+ index >>= 1;
+
+ -- bit_cnt;
+ }
+ while (bit_cnt > 0);
+
+ _br_data [cnt] = br_index;
+ }
+}
+
+
+
+template <int LL2>
+void FFTRealFixLen <LL2>::build_trigo_lut ()
+{
+ const double mul = (0.5 * PI) / TRIGO_TABLE_ARR_SIZE;
+ for (long i = 0; i < TRIGO_TABLE_ARR_SIZE; ++ i)
+ {
+ using namespace std;
+
+ _trigo_data [i] = DataType (cos (i * mul));
+ }
+}
+
+
+
+template <int LL2>
+void FFTRealFixLen <LL2>::build_trigo_osc ()
+{
+ for (int i = 0; i < NBR_TRIGO_OSC; ++i)
+ {
+ OscType & osc = _trigo_osc [i];
+
+ const long len = static_cast <long> (TRIGO_TABLE_ARR_SIZE) << (i + 1);
+ const double mul = (0.5 * PI) / len;
+ osc.set_step (mul);
+ }
+}
+
+
+
+#endif // FFTRealFixLen_CODEHEADER_INCLUDED
+
+#undef FFTRealFixLen_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h
new file mode 100644
index 000000000..163c08323
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h
@@ -0,0 +1,93 @@
+/*****************************************************************************
+
+ FFTRealFixLenParam.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (FFTRealFixLenParam_HEADER_INCLUDED)
+#define FFTRealFixLenParam_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+class FFTRealFixLenParam
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ // Over this bit depth, we use direct calculation for sin/cos
+ enum { TRIGO_BD_LIMIT = 12 };
+
+ typedef float DataType;
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+#if 0 // To avoid GCC warning:
+ // All member functions in class 'FFTRealFixLenParam' are private
+ FFTRealFixLenParam ();
+ ~FFTRealFixLenParam ();
+ FFTRealFixLenParam (const FFTRealFixLenParam &other);
+ FFTRealFixLenParam &
+ operator = (const FFTRealFixLenParam &other);
+ bool operator == (const FFTRealFixLenParam &other);
+ bool operator != (const FFTRealFixLenParam &other);
+#endif
+
+}; // class FFTRealFixLenParam
+
+
+
+//#include "FFTRealFixLenParam.hpp"
+
+
+
+#endif // FFTRealFixLenParam_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassDirect.h b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassDirect.h
new file mode 100644
index 000000000..7d19c02e4
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassDirect.h
@@ -0,0 +1,96 @@
+/*****************************************************************************
+
+ FFTRealPassDirect.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (FFTRealPassDirect_HEADER_INCLUDED)
+#define FFTRealPassDirect_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "def.h"
+#include "FFTRealFixLenParam.h"
+#include "OscSinCos.h"
+
+
+
+template <int PASS>
+class FFTRealPassDirect
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ typedef FFTRealFixLenParam::DataType DataType;
+ typedef OscSinCos <DataType> OscType;
+
+ FORCEINLINE static void
+ process (long len, DataType dest_ptr [], DataType src_ptr [], const DataType x_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list []);
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ FFTRealPassDirect ();
+ ~FFTRealPassDirect ();
+ FFTRealPassDirect (const FFTRealPassDirect &other);
+ FFTRealPassDirect &
+ operator = (const FFTRealPassDirect &other);
+ bool operator == (const FFTRealPassDirect &other);
+ bool operator != (const FFTRealPassDirect &other);
+
+}; // class FFTRealPassDirect
+
+
+
+#include "FFTRealPassDirect.hpp"
+
+
+
+#endif // FFTRealPassDirect_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp
new file mode 100644
index 000000000..db9d568e6
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp
@@ -0,0 +1,204 @@
+/*****************************************************************************
+
+ FFTRealPassDirect.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (FFTRealPassDirect_CURRENT_CODEHEADER)
+ #error Recursive inclusion of FFTRealPassDirect code header.
+#endif
+#define FFTRealPassDirect_CURRENT_CODEHEADER
+
+#if ! defined (FFTRealPassDirect_CODEHEADER_INCLUDED)
+#define FFTRealPassDirect_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "FFTRealUseTrigo.h"
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <>
+void FFTRealPassDirect <1>::process (long len, DataType dest_ptr [], DataType src_ptr [], const DataType x_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
+{
+ // First and second pass at once
+ const long qlen = len >> 2;
+
+ long coef_index = 0;
+ do
+ {
+ // To do: unroll the loop (2x).
+ const long ri_0 = br_ptr [coef_index >> 2];
+ const long ri_1 = ri_0 + 2 * qlen; // bit_rev_lut_ptr [coef_index + 1];
+ const long ri_2 = ri_0 + 1 * qlen; // bit_rev_lut_ptr [coef_index + 2];
+ const long ri_3 = ri_0 + 3 * qlen; // bit_rev_lut_ptr [coef_index + 3];
+
+ DataType * const df2 = dest_ptr + coef_index;
+ df2 [1] = x_ptr [ri_0] - x_ptr [ri_1];
+ df2 [3] = x_ptr [ri_2] - x_ptr [ri_3];
+
+ const DataType sf_0 = x_ptr [ri_0] + x_ptr [ri_1];
+ const DataType sf_2 = x_ptr [ri_2] + x_ptr [ri_3];
+
+ df2 [0] = sf_0 + sf_2;
+ df2 [2] = sf_0 - sf_2;
+
+ coef_index += 4;
+ }
+ while (coef_index < len);
+}
+
+template <>
+void FFTRealPassDirect <2>::process (long len, DataType dest_ptr [], DataType src_ptr [], const DataType x_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
+{
+ // Executes "previous" passes first. Inverts source and destination buffers
+ FFTRealPassDirect <1>::process (
+ len,
+ src_ptr,
+ dest_ptr,
+ x_ptr,
+ cos_ptr,
+ cos_len,
+ br_ptr,
+ osc_list
+ );
+
+ // Third pass
+ const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
+
+ long coef_index = 0;
+ do
+ {
+ dest_ptr [coef_index ] = src_ptr [coef_index] + src_ptr [coef_index + 4];
+ dest_ptr [coef_index + 4] = src_ptr [coef_index] - src_ptr [coef_index + 4];
+ dest_ptr [coef_index + 2] = src_ptr [coef_index + 2];
+ dest_ptr [coef_index + 6] = src_ptr [coef_index + 6];
+
+ DataType v;
+
+ v = (src_ptr [coef_index + 5] - src_ptr [coef_index + 7]) * sqrt2_2;
+ dest_ptr [coef_index + 1] = src_ptr [coef_index + 1] + v;
+ dest_ptr [coef_index + 3] = src_ptr [coef_index + 1] - v;
+
+ v = (src_ptr [coef_index + 5] + src_ptr [coef_index + 7]) * sqrt2_2;
+ dest_ptr [coef_index + 5] = v + src_ptr [coef_index + 3];
+ dest_ptr [coef_index + 7] = v - src_ptr [coef_index + 3];
+
+ coef_index += 8;
+ }
+ while (coef_index < len);
+}
+
+template <int PASS>
+void FFTRealPassDirect <PASS>::process (long len, DataType dest_ptr [], DataType src_ptr [], const DataType x_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
+{
+ // Executes "previous" passes first. Inverts source and destination buffers
+ FFTRealPassDirect <PASS - 1>::process (
+ len,
+ src_ptr,
+ dest_ptr,
+ x_ptr,
+ cos_ptr,
+ cos_len,
+ br_ptr,
+ osc_list
+ );
+
+ const long dist = 1L << (PASS - 1);
+ const long c1_r = 0;
+ const long c1_i = dist;
+ const long c2_r = dist * 2;
+ const long c2_i = dist * 3;
+ const long cend = dist * 4;
+ const long table_step = cos_len >> (PASS - 1);
+
+ enum { TRIGO_OSC = PASS - FFTRealFixLenParam::TRIGO_BD_LIMIT };
+ enum { TRIGO_DIRECT = (TRIGO_OSC >= 0) ? 1 : 0 };
+
+ long coef_index = 0;
+ do
+ {
+ const DataType * const sf = src_ptr + coef_index;
+ DataType * const df = dest_ptr + coef_index;
+
+ // Extreme coefficients are always real
+ df [c1_r] = sf [c1_r] + sf [c2_r];
+ df [c2_r] = sf [c1_r] - sf [c2_r];
+ df [c1_i] = sf [c1_i];
+ df [c2_i] = sf [c2_i];
+
+ FFTRealUseTrigo <TRIGO_DIRECT>::prepare (osc_list [TRIGO_OSC]);
+
+ // Others are conjugate complex numbers
+ for (long i = 1; i < dist; ++ i)
+ {
+ DataType c;
+ DataType s;
+ FFTRealUseTrigo <TRIGO_DIRECT>::iterate (
+ osc_list [TRIGO_OSC],
+ c,
+ s,
+ cos_ptr,
+ i * table_step,
+ (dist - i) * table_step
+ );
+
+ const DataType sf_r_i = sf [c1_r + i];
+ const DataType sf_i_i = sf [c1_i + i];
+
+ const DataType v1 = sf [c2_r + i] * c - sf [c2_i + i] * s;
+ df [c1_r + i] = sf_r_i + v1;
+ df [c2_r - i] = sf_r_i - v1;
+
+ const DataType v2 = sf [c2_r + i] * s + sf [c2_i + i] * c;
+ df [c2_r + i] = v2 + sf_i_i;
+ df [cend - i] = v2 - sf_i_i;
+ }
+
+ coef_index += cend;
+ }
+ while (coef_index < len);
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+#endif // FFTRealPassDirect_CODEHEADER_INCLUDED
+
+#undef FFTRealPassDirect_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassInverse.h b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassInverse.h
new file mode 100644
index 000000000..2de895273
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassInverse.h
@@ -0,0 +1,101 @@
+/*****************************************************************************
+
+ FFTRealPassInverse.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (FFTRealPassInverse_HEADER_INCLUDED)
+#define FFTRealPassInverse_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "def.h"
+#include "FFTRealFixLenParam.h"
+#include "OscSinCos.h"
+
+
+
+
+template <int PASS>
+class FFTRealPassInverse
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ typedef FFTRealFixLenParam::DataType DataType;
+ typedef OscSinCos <DataType> OscType;
+
+ FORCEINLINE static void
+ process (long len, DataType dest_ptr [], DataType src_ptr [], const DataType f_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list []);
+ FORCEINLINE static void
+ process_rec (long len, DataType dest_ptr [], DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list []);
+ FORCEINLINE static void
+ process_internal (long len, DataType dest_ptr [], const DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list []);
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ FFTRealPassInverse ();
+ ~FFTRealPassInverse ();
+ FFTRealPassInverse (const FFTRealPassInverse &other);
+ FFTRealPassInverse &
+ operator = (const FFTRealPassInverse &other);
+ bool operator == (const FFTRealPassInverse &other);
+ bool operator != (const FFTRealPassInverse &other);
+
+}; // class FFTRealPassInverse
+
+
+
+#include "FFTRealPassInverse.hpp"
+
+
+
+#endif // FFTRealPassInverse_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp
new file mode 100644
index 000000000..573754696
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp
@@ -0,0 +1,229 @@
+/*****************************************************************************
+
+ FFTRealPassInverse.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (FFTRealPassInverse_CURRENT_CODEHEADER)
+ #error Recursive inclusion of FFTRealPassInverse code header.
+#endif
+#define FFTRealPassInverse_CURRENT_CODEHEADER
+
+#if ! defined (FFTRealPassInverse_CODEHEADER_INCLUDED)
+#define FFTRealPassInverse_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "FFTRealUseTrigo.h"
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <int PASS>
+void FFTRealPassInverse <PASS>::process (long len, DataType dest_ptr [], DataType src_ptr [], const DataType f_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
+{
+ process_internal (
+ len,
+ dest_ptr,
+ f_ptr,
+ cos_ptr,
+ cos_len,
+ br_ptr,
+ osc_list
+ );
+ FFTRealPassInverse <PASS - 1>::process_rec (
+ len,
+ src_ptr,
+ dest_ptr,
+ cos_ptr,
+ cos_len,
+ br_ptr,
+ osc_list
+ );
+}
+
+
+
+template <int PASS>
+void FFTRealPassInverse <PASS>::process_rec (long len, DataType dest_ptr [], DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
+{
+ process_internal (
+ len,
+ dest_ptr,
+ src_ptr,
+ cos_ptr,
+ cos_len,
+ br_ptr,
+ osc_list
+ );
+ FFTRealPassInverse <PASS - 1>::process_rec (
+ len,
+ src_ptr,
+ dest_ptr,
+ cos_ptr,
+ cos_len,
+ br_ptr,
+ osc_list
+ );
+}
+
+template <>
+void FFTRealPassInverse <0>::process_rec (long len, DataType dest_ptr [], DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
+{
+ // Stops recursion
+}
+
+
+
+template <int PASS>
+void FFTRealPassInverse <PASS>::process_internal (long len, DataType dest_ptr [], const DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
+{
+ const long dist = 1L << (PASS - 1);
+ const long c1_r = 0;
+ const long c1_i = dist;
+ const long c2_r = dist * 2;
+ const long c2_i = dist * 3;
+ const long cend = dist * 4;
+ const long table_step = cos_len >> (PASS - 1);
+
+ enum { TRIGO_OSC = PASS - FFTRealFixLenParam::TRIGO_BD_LIMIT };
+ enum { TRIGO_DIRECT = (TRIGO_OSC >= 0) ? 1 : 0 };
+
+ long coef_index = 0;
+ do
+ {
+ const DataType * const sf = src_ptr + coef_index;
+ DataType * const df = dest_ptr + coef_index;
+
+ // Extreme coefficients are always real
+ df [c1_r] = sf [c1_r] + sf [c2_r];
+ df [c2_r] = sf [c1_r] - sf [c2_r];
+ df [c1_i] = sf [c1_i] * 2;
+ df [c2_i] = sf [c2_i] * 2;
+
+ FFTRealUseTrigo <TRIGO_DIRECT>::prepare (osc_list [TRIGO_OSC]);
+
+ // Others are conjugate complex numbers
+ for (long i = 1; i < dist; ++ i)
+ {
+ df [c1_r + i] = sf [c1_r + i] + sf [c2_r - i];
+ df [c1_i + i] = sf [c2_r + i] - sf [cend - i];
+
+ DataType c;
+ DataType s;
+ FFTRealUseTrigo <TRIGO_DIRECT>::iterate (
+ osc_list [TRIGO_OSC],
+ c,
+ s,
+ cos_ptr,
+ i * table_step,
+ (dist - i) * table_step
+ );
+
+ const DataType vr = sf [c1_r + i] - sf [c2_r - i];
+ const DataType vi = sf [c2_r + i] + sf [cend - i];
+
+ df [c2_r + i] = vr * c + vi * s;
+ df [c2_i + i] = vi * c - vr * s;
+ }
+
+ coef_index += cend;
+ }
+ while (coef_index < len);
+}
+
+template <>
+void FFTRealPassInverse <2>::process_internal (long len, DataType dest_ptr [], const DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
+{
+ // Antepenultimate pass
+ const DataType sqrt2_2 = DataType (SQRT2 * 0.5);
+
+ long coef_index = 0;
+ do
+ {
+ dest_ptr [coef_index ] = src_ptr [coef_index] + src_ptr [coef_index + 4];
+ dest_ptr [coef_index + 4] = src_ptr [coef_index] - src_ptr [coef_index + 4];
+ dest_ptr [coef_index + 2] = src_ptr [coef_index + 2] * 2;
+ dest_ptr [coef_index + 6] = src_ptr [coef_index + 6] * 2;
+
+ dest_ptr [coef_index + 1] = src_ptr [coef_index + 1] + src_ptr [coef_index + 3];
+ dest_ptr [coef_index + 3] = src_ptr [coef_index + 5] - src_ptr [coef_index + 7];
+
+ const DataType vr = src_ptr [coef_index + 1] - src_ptr [coef_index + 3];
+ const DataType vi = src_ptr [coef_index + 5] + src_ptr [coef_index + 7];
+
+ dest_ptr [coef_index + 5] = (vr + vi) * sqrt2_2;
+ dest_ptr [coef_index + 7] = (vi - vr) * sqrt2_2;
+
+ coef_index += 8;
+ }
+ while (coef_index < len);
+}
+
+template <>
+void FFTRealPassInverse <1>::process_internal (long len, DataType dest_ptr [], const DataType src_ptr [], const DataType cos_ptr [], long cos_len, const long br_ptr [], OscType osc_list [])
+{
+ // Penultimate and last pass at once
+ const long qlen = len >> 2;
+
+ long coef_index = 0;
+ do
+ {
+ const long ri_0 = br_ptr [coef_index >> 2];
+
+ const DataType b_0 = src_ptr [coef_index ] + src_ptr [coef_index + 2];
+ const DataType b_2 = src_ptr [coef_index ] - src_ptr [coef_index + 2];
+ const DataType b_1 = src_ptr [coef_index + 1] * 2;
+ const DataType b_3 = src_ptr [coef_index + 3] * 2;
+
+ dest_ptr [ri_0 ] = b_0 + b_1;
+ dest_ptr [ri_0 + 2 * qlen] = b_0 - b_1;
+ dest_ptr [ri_0 + 1 * qlen] = b_2 + b_3;
+ dest_ptr [ri_0 + 3 * qlen] = b_2 - b_3;
+
+ coef_index += 4;
+ }
+ while (coef_index < len);
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+#endif // FFTRealPassInverse_CODEHEADER_INCLUDED
+
+#undef FFTRealPassInverse_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealSelect.h b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealSelect.h
new file mode 100644
index 000000000..bd722d4d1
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealSelect.h
@@ -0,0 +1,77 @@
+/*****************************************************************************
+
+ FFTRealSelect.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (FFTRealSelect_HEADER_INCLUDED)
+#define FFTRealSelect_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "def.h"
+
+
+
+template <int P>
+class FFTRealSelect
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ FORCEINLINE static float *
+ sel_bin (float *e_ptr, float *o_ptr);
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ FFTRealSelect ();
+ ~FFTRealSelect ();
+ FFTRealSelect (const FFTRealSelect &other);
+ FFTRealSelect& operator = (const FFTRealSelect &other);
+ bool operator == (const FFTRealSelect &other);
+ bool operator != (const FFTRealSelect &other);
+
+}; // class FFTRealSelect
+
+
+
+#include "FFTRealSelect.hpp"
+
+
+
+#endif // FFTRealSelect_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealSelect.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealSelect.hpp
new file mode 100644
index 000000000..9ddf5864c
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealSelect.hpp
@@ -0,0 +1,62 @@
+/*****************************************************************************
+
+ FFTRealSelect.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (FFTRealSelect_CURRENT_CODEHEADER)
+ #error Recursive inclusion of FFTRealSelect code header.
+#endif
+#define FFTRealSelect_CURRENT_CODEHEADER
+
+#if ! defined (FFTRealSelect_CODEHEADER_INCLUDED)
+#define FFTRealSelect_CODEHEADER_INCLUDED
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <int P>
+float * FFTRealSelect <P>::sel_bin (float *e_ptr, float *o_ptr)
+{
+ return (o_ptr);
+}
+
+
+
+template <>
+float * FFTRealSelect <0>::sel_bin (float *e_ptr, float *o_ptr)
+{
+ return (e_ptr);
+}
+
+
+
+#endif // FFTRealSelect_CODEHEADER_INCLUDED
+
+#undef FFTRealSelect_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h
new file mode 100644
index 000000000..c4368ee08
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h
@@ -0,0 +1,101 @@
+/*****************************************************************************
+
+ FFTRealUseTrigo.h
+ Copyright (c) 2005 Laurent de Soras
+
+Template parameters:
+ - ALGO: algorithm choice. 0 = table, other = oscillator
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (FFTRealUseTrigo_HEADER_INCLUDED)
+#define FFTRealUseTrigo_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "def.h"
+#include "FFTRealFixLenParam.h"
+#include "OscSinCos.h"
+
+
+
+template <int ALGO>
+class FFTRealUseTrigo
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ typedef FFTRealFixLenParam::DataType DataType;
+ typedef OscSinCos <DataType> OscType;
+
+ FORCEINLINE static void
+ prepare (OscType &osc);
+ FORCEINLINE static void
+ iterate (OscType &osc, DataType &c, DataType &s, const DataType cos_ptr [], long index_c, long index_s);
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ FFTRealUseTrigo ();
+ ~FFTRealUseTrigo ();
+ FFTRealUseTrigo (const FFTRealUseTrigo &other);
+ FFTRealUseTrigo &
+ operator = (const FFTRealUseTrigo &other);
+ bool operator == (const FFTRealUseTrigo &other);
+ bool operator != (const FFTRealUseTrigo &other);
+
+}; // class FFTRealUseTrigo
+
+
+
+#include "FFTRealUseTrigo.hpp"
+
+
+
+#endif // FFTRealUseTrigo_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp
new file mode 100644
index 000000000..aa968b81a
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp
@@ -0,0 +1,91 @@
+/*****************************************************************************
+
+ FFTRealUseTrigo.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (FFTRealUseTrigo_CURRENT_CODEHEADER)
+ #error Recursive inclusion of FFTRealUseTrigo code header.
+#endif
+#define FFTRealUseTrigo_CURRENT_CODEHEADER
+
+#if ! defined (FFTRealUseTrigo_CODEHEADER_INCLUDED)
+#define FFTRealUseTrigo_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "OscSinCos.h"
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <int ALGO>
+void FFTRealUseTrigo <ALGO>::prepare (OscType &osc)
+{
+ osc.clear_buffers ();
+}
+
+template <>
+void FFTRealUseTrigo <0>::prepare (OscType &osc)
+{
+ // Nothing
+}
+
+
+
+template <int ALGO>
+void FFTRealUseTrigo <ALGO>::iterate (OscType &osc, DataType &c, DataType &s, const DataType cos_ptr [], long index_c, long index_s)
+{
+ osc.step ();
+ c = osc.get_cos ();
+ s = osc.get_sin ();
+}
+
+template <>
+void FFTRealUseTrigo <0>::iterate (OscType &osc, DataType &c, DataType &s, const DataType cos_ptr [], long index_c, long index_s)
+{
+ c = cos_ptr [index_c];
+ s = cos_ptr [index_s];
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+#endif // FFTRealUseTrigo_CODEHEADER_INCLUDED
+
+#undef FFTRealUseTrigo_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/OscSinCos.h b/examples/multimedia/spectrum/3rdparty/fftreal/OscSinCos.h
new file mode 100644
index 000000000..775fc14f3
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/OscSinCos.h
@@ -0,0 +1,106 @@
+/*****************************************************************************
+
+ OscSinCos.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (OscSinCos_HEADER_INCLUDED)
+#define OscSinCos_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "def.h"
+
+
+
+template <class T>
+class OscSinCos
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ typedef T DataType;
+
+ OscSinCos ();
+
+ FORCEINLINE void
+ set_step (double angle_rad);
+
+ FORCEINLINE DataType
+ get_cos () const;
+ FORCEINLINE DataType
+ get_sin () const;
+ FORCEINLINE void
+ step ();
+ FORCEINLINE void
+ clear_buffers ();
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ DataType _pos_cos; // Current phase expressed with sin and cos. [-1 ; 1]
+ DataType _pos_sin; // -
+ DataType _step_cos; // Phase increment per step, [-1 ; 1]
+ DataType _step_sin; // -
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ OscSinCos (const OscSinCos &other);
+ OscSinCos & operator = (const OscSinCos &other);
+ bool operator == (const OscSinCos &other);
+ bool operator != (const OscSinCos &other);
+
+}; // class OscSinCos
+
+
+
+#include "OscSinCos.hpp"
+
+
+
+#endif // OscSinCos_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/OscSinCos.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/OscSinCos.hpp
new file mode 100644
index 000000000..749aef04d
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/OscSinCos.hpp
@@ -0,0 +1,122 @@
+/*****************************************************************************
+
+ OscSinCos.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (OscSinCos_CURRENT_CODEHEADER)
+ #error Recursive inclusion of OscSinCos code header.
+#endif
+#define OscSinCos_CURRENT_CODEHEADER
+
+#if ! defined (OscSinCos_CODEHEADER_INCLUDED)
+#define OscSinCos_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include <cmath>
+
+namespace std { }
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class T>
+OscSinCos <T>::OscSinCos ()
+: _pos_cos (1)
+, _pos_sin (0)
+, _step_cos (1)
+, _step_sin (0)
+{
+ // Nothing
+}
+
+
+
+template <class T>
+void OscSinCos <T>::set_step (double angle_rad)
+{
+ using namespace std;
+
+ _step_cos = static_cast <DataType> (cos (angle_rad));
+ _step_sin = static_cast <DataType> (sin (angle_rad));
+}
+
+
+
+template <class T>
+typename OscSinCos <T>::DataType OscSinCos <T>::get_cos () const
+{
+ return (_pos_cos);
+}
+
+
+
+template <class T>
+typename OscSinCos <T>::DataType OscSinCos <T>::get_sin () const
+{
+ return (_pos_sin);
+}
+
+
+
+template <class T>
+void OscSinCos <T>::step ()
+{
+ const DataType old_cos = _pos_cos;
+ const DataType old_sin = _pos_sin;
+
+ _pos_cos = old_cos * _step_cos - old_sin * _step_sin;
+ _pos_sin = old_cos * _step_sin + old_sin * _step_cos;
+}
+
+
+
+template <class T>
+void OscSinCos <T>::clear_buffers ()
+{
+ _pos_cos = static_cast <DataType> (1);
+ _pos_sin = static_cast <DataType> (0);
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+#endif // OscSinCos_CODEHEADER_INCLUDED
+
+#undef OscSinCos_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/TestAccuracy.h b/examples/multimedia/spectrum/3rdparty/fftreal/TestAccuracy.h
new file mode 100644
index 000000000..4b07a6b60
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/TestAccuracy.h
@@ -0,0 +1,105 @@
+/*****************************************************************************
+
+ TestAccuracy.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (TestAccuracy_HEADER_INCLUDED)
+#define TestAccuracy_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class FO>
+class TestAccuracy
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ typedef typename FO::DataType DataType;
+ typedef long double BigFloat; // To get maximum accuracy during intermediate calculations
+
+ static int perform_test_single_object (FO &fft);
+ static int perform_test_d (FO &fft, const char *class_name_0);
+ static int perform_test_i (FO &fft, const char *class_name_0);
+ static int perform_test_di (FO &fft, const char *class_name_0);
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ enum { NBR_ACC_TESTS = 10 * 1000 * 1000 };
+ enum { MAX_NBR_TESTS = 10000 };
+
+ static void compute_tf (DataType s [], const DataType x [], long length);
+ static void compute_itf (DataType x [], const DataType s [], long length);
+ static int compare_vect_display (const DataType x_ptr [], const DataType y_ptr [], long len, BigFloat &max_err_rel);
+ static BigFloat
+ compute_power (const DataType x_ptr [], long len);
+ static BigFloat
+ compute_power (const DataType x_ptr [], const DataType y_ptr [], long len);
+ static void compare_vect (const DataType x_ptr [], const DataType y_ptr [], BigFloat &power, long &max_err_pos, long len);
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ TestAccuracy ();
+ ~TestAccuracy ();
+ TestAccuracy (const TestAccuracy &other);
+ TestAccuracy & operator = (const TestAccuracy &other);
+ bool operator == (const TestAccuracy &other);
+ bool operator != (const TestAccuracy &other);
+
+}; // class TestAccuracy
+
+
+
+#include "TestAccuracy.hpp"
+
+
+
+#endif // TestAccuracy_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/TestAccuracy.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/TestAccuracy.hpp
new file mode 100644
index 000000000..5c794f747
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/TestAccuracy.hpp
@@ -0,0 +1,472 @@
+/*****************************************************************************
+
+ TestAccuracy.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (TestAccuracy_CURRENT_CODEHEADER)
+ #error Recursive inclusion of TestAccuracy code header.
+#endif
+#define TestAccuracy_CURRENT_CODEHEADER
+
+#if ! defined (TestAccuracy_CODEHEADER_INCLUDED)
+#define TestAccuracy_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "def.h"
+#include "test_fnc.h"
+#include "TestWhiteNoiseGen.h"
+
+#include <typeinfo>
+#include <vector>
+
+#include <cmath>
+#include <cstdio>
+
+
+
+static const double TestAccuracy_LN10 = 2.3025850929940456840179914546844;
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class FO>
+int TestAccuracy <FO>::perform_test_single_object (FO &fft)
+{
+ assert (&fft != 0);
+
+ using namespace std;
+
+ int ret_val = 0;
+
+ const std::type_info & ti = typeid (fft);
+ const char * class_name_0 = ti.name ();
+
+ if (ret_val == 0)
+ {
+ ret_val = perform_test_d (fft, class_name_0);
+ }
+ if (ret_val == 0)
+ {
+ ret_val = perform_test_i (fft, class_name_0);
+ }
+ if (ret_val == 0)
+ {
+ ret_val = perform_test_di (fft, class_name_0);
+ }
+
+ if (ret_val == 0)
+ {
+ printf ("\n");
+ }
+
+ return (ret_val);
+}
+
+
+
+template <class FO>
+int TestAccuracy <FO>::perform_test_d (FO &fft, const char *class_name_0)
+{
+ assert (&fft != 0);
+ assert (class_name_0 != 0);
+
+ using namespace std;
+
+ int ret_val = 0;
+ const long len = fft.get_length ();
+ const long nbr_tests = limit (
+ NBR_ACC_TESTS / len / len,
+ 1L,
+ static_cast <long> (MAX_NBR_TESTS)
+ );
+
+ printf ("Testing %s::do_fft () [%ld samples]... ", class_name_0, len);
+ fflush (stdout);
+ TestWhiteNoiseGen <DataType> noise;
+ std::vector <DataType> x (len);
+ std::vector <DataType> s1 (len);
+ std::vector <DataType> s2 (len);
+ BigFloat err_avg = 0;
+
+ for (long test = 0; test < nbr_tests && ret_val == 0; ++ test)
+ {
+ noise.generate (&x [0], len);
+ fft.do_fft (&s1 [0], &x [0]);
+ compute_tf (&s2 [0], &x [0], len);
+
+ BigFloat max_err;
+ compare_vect_display (&s1 [0], &s2 [0], len, max_err);
+ err_avg += max_err;
+ }
+ err_avg /= NBR_ACC_TESTS;
+
+ printf ("done.\n");
+ printf (
+ "Average maximum error: %.6f %% (%f dB)\n",
+ static_cast <double> (err_avg * 100),
+ static_cast <double> ((20 / TestAccuracy_LN10) * log (err_avg))
+ );
+
+ return (ret_val);
+}
+
+
+
+template <class FO>
+int TestAccuracy <FO>::perform_test_i (FO &fft, const char *class_name_0)
+{
+ assert (&fft != 0);
+ assert (class_name_0 != 0);
+
+ using namespace std;
+
+ int ret_val = 0;
+ const long len = fft.get_length ();
+ const long nbr_tests = limit (
+ NBR_ACC_TESTS / len / len,
+ 10L,
+ static_cast <long> (MAX_NBR_TESTS)
+ );
+
+ printf ("Testing %s::do_ifft () [%ld samples]... ", class_name_0, len);
+ fflush (stdout);
+ TestWhiteNoiseGen <DataType> noise;
+ std::vector <DataType> s (len);
+ std::vector <DataType> x1 (len);
+ std::vector <DataType> x2 (len);
+ BigFloat err_avg = 0;
+
+ for (long test = 0; test < nbr_tests && ret_val == 0; ++ test)
+ {
+ noise.generate (&s [0], len);
+ fft.do_ifft (&s [0], &x1 [0]);
+ compute_itf (&x2 [0], &s [0], len);
+
+ BigFloat max_err;
+ compare_vect_display (&x1 [0], &x2 [0], len, max_err);
+ err_avg += max_err;
+ }
+ err_avg /= NBR_ACC_TESTS;
+
+ printf ("done.\n");
+ printf (
+ "Average maximum error: %.6f %% (%f dB)\n",
+ static_cast <double> (err_avg * 100),
+ static_cast <double> ((20 / TestAccuracy_LN10) * log (err_avg))
+ );
+
+ return (ret_val);
+}
+
+
+
+template <class FO>
+int TestAccuracy <FO>::perform_test_di (FO &fft, const char *class_name_0)
+{
+ assert (&fft != 0);
+ assert (class_name_0 != 0);
+
+ using namespace std;
+
+ int ret_val = 0;
+ const long len = fft.get_length ();
+ const long nbr_tests = limit (
+ NBR_ACC_TESTS / len / len,
+ 1L,
+ static_cast <long> (MAX_NBR_TESTS)
+ );
+
+ printf (
+ "Testing %s::do_fft () / do_ifft () / rescale () [%ld samples]... ",
+ class_name_0,
+ len
+ );
+ fflush (stdout);
+ TestWhiteNoiseGen <DataType> noise;
+ std::vector <DataType> x (len);
+ std::vector <DataType> s (len);
+ std::vector <DataType> y (len);
+ BigFloat err_avg = 0;
+
+ for (long test = 0; test < nbr_tests && ret_val == 0; ++ test)
+ {
+ noise.generate (&x [0], len);
+ fft.do_fft (&s [0], &x [0]);
+ fft.do_ifft (&s [0], &y [0]);
+ fft.rescale (&y [0]);
+
+ BigFloat max_err;
+ compare_vect_display (&x [0], &y [0], len, max_err);
+ err_avg += max_err;
+ }
+ err_avg /= NBR_ACC_TESTS;
+
+ printf ("done.\n");
+ printf (
+ "Average maximum error: %.6f %% (%f dB)\n",
+ static_cast <double> (err_avg * 100),
+ static_cast <double> ((20 / TestAccuracy_LN10) * log (err_avg))
+ );
+
+ return (ret_val);
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+// Positive transform
+template <class FO>
+void TestAccuracy <FO>::compute_tf (DataType s [], const DataType x [], long length)
+{
+ assert (s != 0);
+ assert (x != 0);
+ assert (length >= 2);
+ assert ((length & 1) == 0);
+
+ const long nbr_bins = length >> 1;
+
+ // DC and Nyquist
+ BigFloat dc = 0;
+ BigFloat ny = 0;
+ for (long pos = 0; pos < length; pos += 2)
+ {
+ const BigFloat even = x [pos ];
+ const BigFloat odd = x [pos + 1];
+ dc += even + odd;
+ ny += even - odd;
+ }
+ s [0 ] = static_cast <DataType> (dc);
+ s [nbr_bins] = static_cast <DataType> (ny);
+
+ // Regular bins
+ for (long bin = 1; bin < nbr_bins; ++ bin)
+ {
+ BigFloat sum_r = 0;
+ BigFloat sum_i = 0;
+
+ const BigFloat m = bin * static_cast <BigFloat> (2 * PI) / length;
+
+ for (long pos = 0; pos < length; ++pos)
+ {
+ using namespace std;
+
+ const BigFloat phase = pos * m;
+ const BigFloat e_r = cos (phase);
+ const BigFloat e_i = sin (phase);
+
+ sum_r += x [pos] * e_r;
+ sum_i += x [pos] * e_i;
+ }
+
+ s [ bin] = static_cast <DataType> (sum_r);
+ s [nbr_bins + bin] = static_cast <DataType> (sum_i);
+ }
+}
+
+
+
+// Negative transform
+template <class FO>
+void TestAccuracy <FO>::compute_itf (DataType x [], const DataType s [], long length)
+{
+ assert (s != 0);
+ assert (x != 0);
+ assert (length >= 2);
+ assert ((length & 1) == 0);
+
+ const long nbr_bins = length >> 1;
+
+ // DC and Nyquist
+ BigFloat dc = s [0 ];
+ BigFloat ny = s [nbr_bins];
+
+ // Regular bins
+ for (long pos = 0; pos < length; ++pos)
+ {
+ BigFloat sum = dc + ny * (1 - 2 * (pos & 1));
+
+ const BigFloat m = pos * static_cast <BigFloat> (-2 * PI) / length;
+
+ for (long bin = 1; bin < nbr_bins; ++ bin)
+ {
+ using namespace std;
+
+ const BigFloat phase = bin * m;
+ const BigFloat e_r = cos (phase);
+ const BigFloat e_i = sin (phase);
+
+ sum += 2 * ( e_r * s [bin ]
+ - e_i * s [bin + nbr_bins]);
+ }
+
+ x [pos] = static_cast <DataType> (sum);
+ }
+}
+
+
+
+template <class FO>
+int TestAccuracy <FO>::compare_vect_display (const DataType x_ptr [], const DataType y_ptr [], long len, BigFloat &max_err_rel)
+{
+ assert (x_ptr != 0);
+ assert (y_ptr != 0);
+ assert (len > 0);
+ assert (&max_err_rel != 0);
+
+ using namespace std;
+
+ int ret_val = 0;
+
+ BigFloat power = compute_power (&x_ptr [0], &y_ptr [0], len);
+ BigFloat power_dif;
+ long max_err_pos;
+ compare_vect (&x_ptr [0], &y_ptr [0], power_dif, max_err_pos, len);
+
+ if (power == 0)
+ {
+ power = power_dif;
+ }
+ const BigFloat power_err_rel = power_dif / power;
+
+ BigFloat max_err = 0;
+ max_err_rel = 0;
+ if (max_err_pos >= 0)
+ {
+ max_err = y_ptr [max_err_pos] - x_ptr [max_err_pos];
+ max_err_rel = 2 * fabs (max_err) / ( fabs (y_ptr [max_err_pos])
+ + fabs (x_ptr [max_err_pos]));
+ }
+
+ if (power_err_rel > 0.001)
+ {
+ printf ("Power error : %f (%.6f %%)\n",
+ static_cast <double> (power_err_rel),
+ static_cast <double> (power_err_rel * 100)
+ );
+ if (max_err_pos >= 0)
+ {
+ printf (
+ "Maximum error: %f - %f = %f (%f)\n",
+ static_cast <double> (y_ptr [max_err_pos]),
+ static_cast <double> (x_ptr [max_err_pos]),
+ static_cast <double> (max_err),
+ static_cast <double> (max_err_pos)
+ );
+ }
+ }
+
+ return (ret_val);
+}
+
+
+
+template <class FO>
+typename TestAccuracy <FO>::BigFloat TestAccuracy <FO>::compute_power (const DataType x_ptr [], long len)
+{
+ assert (x_ptr != 0);
+ assert (len > 0);
+
+ BigFloat power = 0;
+ for (long pos = 0; pos < len; ++pos)
+ {
+ const BigFloat val = x_ptr [pos];
+
+ power += val * val;
+ }
+
+ using namespace std;
+
+ power = sqrt (power) / len;
+
+ return (power);
+}
+
+
+
+template <class FO>
+typename TestAccuracy <FO>::BigFloat TestAccuracy <FO>::compute_power (const DataType x_ptr [], const DataType y_ptr [], long len)
+{
+ assert (x_ptr != 0);
+ assert (y_ptr != 0);
+ assert (len > 0);
+
+ return ((compute_power (x_ptr, len) + compute_power (y_ptr, len)) * 0.5);
+}
+
+
+
+template <class FO>
+void TestAccuracy <FO>::compare_vect (const DataType x_ptr [], const DataType y_ptr [], BigFloat &power, long &max_err_pos, long len)
+{
+ assert (x_ptr != 0);
+ assert (y_ptr != 0);
+ assert (len > 0);
+ assert (&power != 0);
+ assert (&max_err_pos != 0);
+
+ power = 0;
+ BigFloat max_dif2 = 0;
+ max_err_pos = -1;
+
+ for (long pos = 0; pos < len; ++pos)
+ {
+ const BigFloat x = x_ptr [pos];
+ const BigFloat y = y_ptr [pos];
+ const BigFloat dif = y - x;
+ const BigFloat dif2 = dif * dif;
+
+ power += dif2;
+ if (dif2 > max_dif2)
+ {
+ max_err_pos = pos;
+ max_dif2 = dif2;
+ }
+ }
+
+ using namespace std;
+
+ power = sqrt (power) / len;
+}
+
+
+
+#endif // TestAccuracy_CODEHEADER_INCLUDED
+
+#undef TestAccuracy_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/TestHelperFixLen.h b/examples/multimedia/spectrum/3rdparty/fftreal/TestHelperFixLen.h
new file mode 100644
index 000000000..ecff96d33
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/TestHelperFixLen.h
@@ -0,0 +1,93 @@
+/*****************************************************************************
+
+ TestHelperFixLen.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (TestHelperFixLen_HEADER_INCLUDED)
+#define TestHelperFixLen_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "FFTRealFixLen.h"
+
+
+
+template <int L>
+class TestHelperFixLen
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ typedef FFTRealFixLen <L> FftType;
+
+ static void perform_test_accuracy (int &ret_val);
+ static void perform_test_speed (int &ret_val);
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ TestHelperFixLen ();
+ ~TestHelperFixLen ();
+ TestHelperFixLen (const TestHelperFixLen &other);
+ TestHelperFixLen &
+ operator = (const TestHelperFixLen &other);
+ bool operator == (const TestHelperFixLen &other);
+ bool operator != (const TestHelperFixLen &other);
+
+}; // class TestHelperFixLen
+
+
+
+#include "TestHelperFixLen.hpp"
+
+
+
+#endif // TestHelperFixLen_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp
new file mode 100644
index 000000000..25048b919
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp
@@ -0,0 +1,93 @@
+/*****************************************************************************
+
+ TestHelperFixLen.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (TestHelperFixLen_CURRENT_CODEHEADER)
+ #error Recursive inclusion of TestHelperFixLen code header.
+#endif
+#define TestHelperFixLen_CURRENT_CODEHEADER
+
+#if ! defined (TestHelperFixLen_CODEHEADER_INCLUDED)
+#define TestHelperFixLen_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "test_settings.h"
+
+#include "TestAccuracy.h"
+#if defined (test_settings_SPEED_TEST_ENABLED)
+ #include "TestSpeed.h"
+#endif
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <int L>
+void TestHelperFixLen <L>::perform_test_accuracy (int &ret_val)
+{
+ if (ret_val == 0)
+ {
+ FftType fft;
+ ret_val = TestAccuracy <FftType>::perform_test_single_object (fft);
+ }
+}
+
+
+
+template <int L>
+void TestHelperFixLen <L>::perform_test_speed (int &ret_val)
+{
+#if defined (test_settings_SPEED_TEST_ENABLED)
+
+ if (ret_val == 0)
+ {
+ FftType fft;
+ ret_val = TestSpeed <FftType>::perform_test_single_object (fft);
+ }
+
+#endif
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+#endif // TestHelperFixLen_CODEHEADER_INCLUDED
+
+#undef TestHelperFixLen_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/TestHelperNormal.h b/examples/multimedia/spectrum/3rdparty/fftreal/TestHelperNormal.h
new file mode 100644
index 000000000..a7bff5c2e
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/TestHelperNormal.h
@@ -0,0 +1,94 @@
+/*****************************************************************************
+
+ TestHelperNormal.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (TestHelperNormal_HEADER_INCLUDED)
+#define TestHelperNormal_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "FFTReal.h"
+
+
+
+template <class DT>
+class TestHelperNormal
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ typedef DT DataType;
+ typedef FFTReal <DataType> FftType;
+
+ static void perform_test_accuracy (int &ret_val);
+ static void perform_test_speed (int &ret_val);
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ TestHelperNormal ();
+ ~TestHelperNormal ();
+ TestHelperNormal (const TestHelperNormal &other);
+ TestHelperNormal &
+ operator = (const TestHelperNormal &other);
+ bool operator == (const TestHelperNormal &other);
+ bool operator != (const TestHelperNormal &other);
+
+}; // class TestHelperNormal
+
+
+
+#include "TestHelperNormal.hpp"
+
+
+
+#endif // TestHelperNormal_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/TestHelperNormal.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/TestHelperNormal.hpp
new file mode 100644
index 000000000..e037696ae
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/TestHelperNormal.hpp
@@ -0,0 +1,99 @@
+/*****************************************************************************
+
+ TestHelperNormal.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (TestHelperNormal_CURRENT_CODEHEADER)
+ #error Recursive inclusion of TestHelperNormal code header.
+#endif
+#define TestHelperNormal_CURRENT_CODEHEADER
+
+#if ! defined (TestHelperNormal_CODEHEADER_INCLUDED)
+#define TestHelperNormal_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "test_settings.h"
+
+#include "TestAccuracy.h"
+#if defined (test_settings_SPEED_TEST_ENABLED)
+ #include "TestSpeed.h"
+#endif
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class DT>
+void TestHelperNormal <DT>::perform_test_accuracy (int &ret_val)
+{
+ const int len_arr [] = { 1, 2, 3, 4, 7, 8, 10, 12 };
+ const int nbr_len = sizeof (len_arr) / sizeof (len_arr [0]);
+ for (int k = 0; k < nbr_len && ret_val == 0; ++k)
+ {
+ const long len = 1L << (len_arr [k]);
+ FftType fft (len);
+ ret_val = TestAccuracy <FftType>::perform_test_single_object (fft);
+ }
+}
+
+
+
+template <class DT>
+void TestHelperNormal <DT>::perform_test_speed (int &ret_val)
+{
+#if defined (test_settings_SPEED_TEST_ENABLED)
+
+ const int len_arr [] = { 1, 2, 3, 4, 7, 8, 10, 12, 14, 16, 18, 20, 22 };
+ const int nbr_len = sizeof (len_arr) / sizeof (len_arr [0]);
+ for (int k = 0; k < nbr_len && ret_val == 0; ++k)
+ {
+ const long len = 1L << (len_arr [k]);
+ FftType fft (len);
+ ret_val = TestSpeed <FftType>::perform_test_single_object (fft);
+ }
+
+#endif
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+#endif // TestHelperNormal_CODEHEADER_INCLUDED
+
+#undef TestHelperNormal_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/TestSpeed.h b/examples/multimedia/spectrum/3rdparty/fftreal/TestSpeed.h
new file mode 100644
index 000000000..229578182
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/TestSpeed.h
@@ -0,0 +1,95 @@
+/*****************************************************************************
+
+ TestSpeed.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (TestSpeed_HEADER_INCLUDED)
+#define TestSpeed_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class FO>
+class TestSpeed
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ typedef typename FO::DataType DataType;
+
+ static int perform_test_single_object (FO &fft);
+ static int perform_test_d (FO &fft, const char *class_name_0);
+ static int perform_test_i (FO &fft, const char *class_name_0);
+ static int perform_test_di (FO &fft, const char *class_name_0);
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ enum { NBR_SPD_TESTS = 10 * 1000 * 1000 };
+ enum { MAX_NBR_TESTS = 10000 };
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ TestSpeed ();
+ ~TestSpeed ();
+ TestSpeed (const TestSpeed &other);
+ TestSpeed & operator = (const TestSpeed &other);
+ bool operator == (const TestSpeed &other);
+ bool operator != (const TestSpeed &other);
+
+}; // class TestSpeed
+
+
+
+#include "TestSpeed.hpp"
+
+
+
+#endif // TestSpeed_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/TestSpeed.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/TestSpeed.hpp
new file mode 100644
index 000000000..e716b2a76
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/TestSpeed.hpp
@@ -0,0 +1,223 @@
+/*****************************************************************************
+
+ TestSpeed.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (TestSpeed_CURRENT_CODEHEADER)
+ #error Recursive inclusion of TestSpeed code header.
+#endif
+#define TestSpeed_CURRENT_CODEHEADER
+
+#if ! defined (TestSpeed_CODEHEADER_INCLUDED)
+#define TestSpeed_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "test_fnc.h"
+#include "stopwatch/StopWatch.h"
+#include "TestWhiteNoiseGen.h"
+
+#include <typeinfo>
+
+#include <cstdio>
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class FO>
+int TestSpeed <FO>::perform_test_single_object (FO &fft)
+{
+ assert (&fft != 0);
+
+ int ret_val = 0;
+
+ const std::type_info & ti = typeid (fft);
+ const char * class_name_0 = ti.name ();
+
+ if (ret_val == 0)
+ {
+ perform_test_d (fft, class_name_0);
+ }
+ if (ret_val == 0)
+ {
+ perform_test_i (fft, class_name_0);
+ }
+ if (ret_val == 0)
+ {
+ perform_test_di (fft, class_name_0);
+ }
+
+ if (ret_val == 0)
+ {
+ printf ("\n");
+ }
+
+ return (ret_val);
+}
+
+
+
+template <class FO>
+int TestSpeed <FO>::perform_test_d (FO &fft, const char *class_name_0)
+{
+ assert (&fft != 0);
+ assert (class_name_0 != 0);
+
+ const long len = fft.get_length ();
+ const long nbr_tests = limit (
+ static_cast <long> (NBR_SPD_TESTS / len / len),
+ 1L,
+ static_cast <long> (MAX_NBR_TESTS)
+ );
+
+ TestWhiteNoiseGen <DataType> noise;
+ std::vector <DataType> x (len, 0);
+ std::vector <DataType> s (len);
+ noise.generate (&x [0], len);
+
+ printf (
+ "%s::do_fft () speed test [%ld samples]... ",
+ class_name_0,
+ len
+ );
+ fflush (stdout);
+
+ stopwatch::StopWatch chrono;
+ chrono.start ();
+ for (long test = 0; test < nbr_tests; ++ test)
+ {
+ fft.do_fft (&s [0], &x [0]);
+ chrono.stop_lap ();
+ }
+
+ printf ("%.1f clocks/sample\n", chrono.get_time_best_lap (len));
+
+ return (0);
+}
+
+
+
+template <class FO>
+int TestSpeed <FO>::perform_test_i (FO &fft, const char *class_name_0)
+{
+ assert (&fft != 0);
+ assert (class_name_0 != 0);
+
+ const long len = fft.get_length ();
+ const long nbr_tests = limit (
+ static_cast <long> (NBR_SPD_TESTS / len / len),
+ 1L,
+ static_cast <long> (MAX_NBR_TESTS)
+ );
+
+ TestWhiteNoiseGen <DataType> noise;
+ std::vector <DataType> x (len);
+ std::vector <DataType> s (len, 0);
+ noise.generate (&s [0], len);
+
+ printf (
+ "%s::do_ifft () speed test [%ld samples]... ",
+ class_name_0,
+ len
+ );
+ fflush (stdout);
+
+ stopwatch::StopWatch chrono;
+ chrono.start ();
+ for (long test = 0; test < nbr_tests; ++ test)
+ {
+ fft.do_ifft (&s [0], &x [0]);
+ chrono.stop_lap ();
+ }
+
+ printf ("%.1f clocks/sample\n", chrono.get_time_best_lap (len));
+
+ return (0);
+}
+
+
+
+template <class FO>
+int TestSpeed <FO>::perform_test_di (FO &fft, const char *class_name_0)
+{
+ assert (&fft != 0);
+ assert (class_name_0 != 0);
+
+ const long len = fft.get_length ();
+ const long nbr_tests = limit (
+ static_cast <long> (NBR_SPD_TESTS / len / len),
+ 1L,
+ static_cast <long> (MAX_NBR_TESTS)
+ );
+
+ TestWhiteNoiseGen <DataType> noise;
+ std::vector <DataType> x (len, 0);
+ std::vector <DataType> s (len);
+ std::vector <DataType> y (len);
+ noise.generate (&x [0], len);
+
+ printf (
+ "%s::do_fft () / do_ifft () / rescale () speed test [%ld samples]... ",
+ class_name_0,
+ len
+ );
+ fflush (stdout);
+
+ stopwatch::StopWatch chrono;
+
+ chrono.start ();
+ for (long test = 0; test < nbr_tests; ++ test)
+ {
+ fft.do_fft (&s [0], &x [0]);
+ fft.do_ifft (&s [0], &y [0]);
+ fft.rescale (&y [0]);
+ chrono.stop_lap ();
+ }
+
+ printf ("%.1f clocks/sample\n", chrono.get_time_best_lap (len));
+
+ return (0);
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+#endif // TestSpeed_CODEHEADER_INCLUDED
+
+#undef TestSpeed_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h b/examples/multimedia/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h
new file mode 100644
index 000000000..d815f8e31
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h
@@ -0,0 +1,95 @@
+/*****************************************************************************
+
+ TestWhiteNoiseGen.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (TestWhiteNoiseGen_HEADER_INCLUDED)
+#define TestWhiteNoiseGen_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class DT>
+class TestWhiteNoiseGen
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ typedef DT DataType;
+
+ TestWhiteNoiseGen ();
+ virtual ~TestWhiteNoiseGen () {}
+
+ void generate (DataType data_ptr [], long len);
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ typedef unsigned long StateType;
+
+ StateType _rand_state;
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ TestWhiteNoiseGen (const TestWhiteNoiseGen &other);
+ TestWhiteNoiseGen &
+ operator = (const TestWhiteNoiseGen &other);
+ bool operator == (const TestWhiteNoiseGen &other);
+ bool operator != (const TestWhiteNoiseGen &other);
+
+}; // class TestWhiteNoiseGen
+
+
+
+#include "TestWhiteNoiseGen.hpp"
+
+
+
+#endif // TestWhiteNoiseGen_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp
new file mode 100644
index 000000000..13b7eb3e0
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp
@@ -0,0 +1,91 @@
+/*****************************************************************************
+
+ TestWhiteNoiseGen.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (TestWhiteNoiseGen_CURRENT_CODEHEADER)
+ #error Recursive inclusion of TestWhiteNoiseGen code header.
+#endif
+#define TestWhiteNoiseGen_CURRENT_CODEHEADER
+
+#if ! defined (TestWhiteNoiseGen_CODEHEADER_INCLUDED)
+#define TestWhiteNoiseGen_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class DT>
+TestWhiteNoiseGen <DT>::TestWhiteNoiseGen ()
+: _rand_state (0)
+{
+ _rand_state = reinterpret_cast <StateType> (this);
+}
+
+
+
+template <class DT>
+void TestWhiteNoiseGen <DT>::generate (DataType data_ptr [], long len)
+{
+ assert (data_ptr != 0);
+ assert (len > 0);
+
+ const DataType one = static_cast <DataType> (1);
+ const DataType mul = one / static_cast <DataType> (0x80000000UL);
+
+ long pos = 0;
+ do
+ {
+ const DataType x = static_cast <DataType> (_rand_state & 0xFFFFFFFFUL);
+ data_ptr [pos] = x * mul - one;
+
+ _rand_state = _rand_state * 1234567UL + 890123UL;
+
+ ++ pos;
+ }
+ while (pos < len);
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+#endif // TestWhiteNoiseGen_CODEHEADER_INCLUDED
+
+#undef TestWhiteNoiseGen_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/bwins/fftrealu.def b/examples/multimedia/spectrum/3rdparty/fftreal/bwins/fftrealu.def
new file mode 100644
index 000000000..7a7939773
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/bwins/fftrealu.def
@@ -0,0 +1,5 @@
+EXPORTS
+ ??0FFTRealWrapper@@QAE@XZ @ 1 NONAME ; FFTRealWrapper::FFTRealWrapper(void)
+ ??1FFTRealWrapper@@QAE@XZ @ 2 NONAME ; FFTRealWrapper::~FFTRealWrapper(void)
+ ?calculateFFT@FFTRealWrapper@@QAEXQAMQBM@Z @ 3 NONAME ; void FFTRealWrapper::calculateFFT(float * const, float const * const)
+
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/def.h b/examples/multimedia/spectrum/3rdparty/fftreal/def.h
new file mode 100644
index 000000000..99c545f53
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/def.h
@@ -0,0 +1,60 @@
+/*****************************************************************************
+
+ def.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (def_HEADER_INCLUDED)
+#define def_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+
+const double PI = 3.1415926535897932384626433832795;
+const double SQRT2 = 1.41421356237309514547462185873883;
+
+#if defined (_MSC_VER)
+
+ #define FORCEINLINE __forceinline
+
+#else
+
+ #define FORCEINLINE inline
+
+#endif
+
+
+
+#endif // def_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/eabi/fftrealu.def b/examples/multimedia/spectrum/3rdparty/fftreal/eabi/fftrealu.def
new file mode 100644
index 000000000..f95a44140
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/eabi/fftrealu.def
@@ -0,0 +1,7 @@
+EXPORTS
+ _ZN14FFTRealWrapper12calculateFFTEPfPKf @ 1 NONAME
+ _ZN14FFTRealWrapperC1Ev @ 2 NONAME
+ _ZN14FFTRealWrapperC2Ev @ 3 NONAME
+ _ZN14FFTRealWrapperD1Ev @ 4 NONAME
+ _ZN14FFTRealWrapperD2Ev @ 5 NONAME
+
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/fftreal.pas b/examples/multimedia/spectrum/3rdparty/fftreal/fftreal.pas
new file mode 100644
index 000000000..ea6375450
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/fftreal.pas
@@ -0,0 +1,661 @@
+(*****************************************************************************
+
+ DIGITAL SIGNAL PROCESSING TOOLS
+ Version 1.03, 2001/06/15
+ (c) 1999 - Laurent de Soras
+
+ FFTReal.h
+ Fourier transformation of real number arrays.
+ Portable ISO C++
+
+------------------------------------------------------------------------------
+
+ LEGAL
+
+ Source code may be freely used for any purpose, including commercial
+ applications. Programs must display in their "About" dialog-box (or
+ documentation) a text telling they use these routines by Laurent de Soras.
+ Modified source code can be distributed, but modifications must be clearly
+ indicated.
+
+ CONTACT
+
+ Laurent de Soras
+ 92 avenue Albert 1er
+ 92500 Rueil-Malmaison
+ France
+
+ ldesoras@club-internet.fr
+
+------------------------------------------------------------------------------
+
+ Translation to ObjectPascal by :
+ Frederic Vanmol
+ frederic@axiworld.be
+
+*****************************************************************************)
+
+
+unit
+ FFTReal;
+
+interface
+
+uses
+ Windows;
+
+(* Change this typedef to use a different floating point type in your FFTs
+ (i.e. float, double or long double). *)
+type
+ pflt_t = ^flt_t;
+ flt_t = single;
+
+ pflt_array = ^flt_array;
+ flt_array = array[0..0] of flt_t;
+
+ plongarray = ^longarray;
+ longarray = array[0..0] of longint;
+
+const
+ sizeof_flt : longint = SizeOf(flt_t);
+
+
+
+type
+ // Bit reversed look-up table nested class
+ TBitReversedLUT = class
+ private
+ _ptr : plongint;
+ public
+ constructor Create(const nbr_bits: integer);
+ destructor Destroy; override;
+ function get_ptr: plongint;
+ end;
+
+ // Trigonometric look-up table nested class
+ TTrigoLUT = class
+ private
+ _ptr : pflt_t;
+ public
+ constructor Create(const nbr_bits: integer);
+ destructor Destroy; override;
+ function get_ptr(const level: integer): pflt_t;
+ end;
+
+ TFFTReal = class
+ private
+ _bit_rev_lut : TBitReversedLUT;
+ _trigo_lut : TTrigoLUT;
+ _sqrt2_2 : flt_t;
+ _length : longint;
+ _nbr_bits : integer;
+ _buffer_ptr : pflt_t;
+ public
+ constructor Create(const length: longint);
+ destructor Destroy; override;
+
+ procedure do_fft(f: pflt_array; const x: pflt_array);
+ procedure do_ifft(const f: pflt_array; x: pflt_array);
+ procedure rescale(x: pflt_array);
+ end;
+
+
+
+
+
+
+
+implementation
+
+uses
+ Math;
+
+{ TBitReversedLUT }
+
+constructor TBitReversedLUT.Create(const nbr_bits: integer);
+var
+ length : longint;
+ cnt : longint;
+ br_index : longint;
+ bit : longint;
+begin
+ inherited Create;
+
+ length := 1 shl nbr_bits;
+ GetMem(_ptr, length*SizeOf(longint));
+
+ br_index := 0;
+ plongarray(_ptr)^[0] := 0;
+ for cnt := 1 to length-1 do
+ begin
+ // ++br_index (bit reversed)
+ bit := length shr 1;
+ br_index := br_index xor bit;
+ while br_index and bit = 0 do
+ begin
+ bit := bit shr 1;
+ br_index := br_index xor bit;
+ end;
+
+ plongarray(_ptr)^[cnt] := br_index;
+ end;
+end;
+
+destructor TBitReversedLUT.Destroy;
+begin
+ FreeMem(_ptr);
+ _ptr := nil;
+ inherited;
+end;
+
+function TBitReversedLUT.get_ptr: plongint;
+begin
+ Result := _ptr;
+end;
+
+{ TTrigLUT }
+
+constructor TTrigoLUT.Create(const nbr_bits: integer);
+var
+ total_len : longint;
+ PI : double;
+ level : integer;
+ level_len : longint;
+ level_ptr : pflt_array;
+ mul : double;
+ i : longint;
+begin
+ inherited Create;
+
+ _ptr := nil;
+
+ if (nbr_bits > 3) then
+ begin
+ total_len := (1 shl (nbr_bits - 1)) - 4;
+ GetMem(_ptr, total_len * sizeof_flt);
+
+ PI := ArcTan(1) * 4;
+ for level := 3 to nbr_bits-1 do
+ begin
+ level_len := 1 shl (level - 1);
+ level_ptr := pointer(get_ptr(level));
+ mul := PI / (level_len shl 1);
+
+ for i := 0 to level_len-1 do
+ level_ptr^[i] := cos(i * mul);
+ end;
+ end;
+end;
+
+destructor TTrigoLUT.Destroy;
+begin
+ FreeMem(_ptr);
+ _ptr := nil;
+ inherited;
+end;
+
+function TTrigoLUT.get_ptr(const level: integer): pflt_t;
+var
+ tempp : pflt_t;
+begin
+ tempp := _ptr;
+ inc(tempp, (1 shl (level-1)) - 4);
+ Result := tempp;
+end;
+
+{ TFFTReal }
+
+constructor TFFTReal.Create(const length: longint);
+begin
+ inherited Create;
+
+ _length := length;
+ _nbr_bits := Floor(Ln(length) / Ln(2) + 0.5);
+ _bit_rev_lut := TBitReversedLUT.Create(Floor(Ln(length) / Ln(2) + 0.5));
+ _trigo_lut := TTrigoLUT.Create(Floor(Ln(length) / Ln(2) + 0.05));
+ _sqrt2_2 := Sqrt(2) * 0.5;
+
+ _buffer_ptr := nil;
+ if _nbr_bits > 2 then
+ GetMem(_buffer_ptr, _length * sizeof_flt);
+end;
+
+destructor TFFTReal.Destroy;
+begin
+ if _buffer_ptr <> nil then
+ begin
+ FreeMem(_buffer_ptr);
+ _buffer_ptr := nil;
+ end;
+
+ _bit_rev_lut.Free;
+ _bit_rev_lut := nil;
+ _trigo_lut.Free;
+ _trigo_lut := nil;
+
+ inherited;
+end;
+
+(*==========================================================================*/
+/* Name: do_fft */
+/* Description: Compute the FFT of the array. */
+/* Input parameters: */
+/* - x: pointer on the source array (time). */
+/* Output parameters: */
+/* - f: pointer on the destination array (frequencies). */
+/* f [0...length(x)/2] = real values, */
+/* f [length(x)/2+1...length(x)-1] = imaginary values of */
+/* coefficents 1...length(x)/2-1. */
+/*==========================================================================*)
+procedure TFFTReal.do_fft(f: pflt_array; const x: pflt_array);
+var
+ sf, df : pflt_array;
+ pass : integer;
+ nbr_coef : longint;
+ h_nbr_coef : longint;
+ d_nbr_coef : longint;
+ coef_index : longint;
+ bit_rev_lut_ptr : plongarray;
+ rev_index_0 : longint;
+ rev_index_1 : longint;
+ rev_index_2 : longint;
+ rev_index_3 : longint;
+ df2 : pflt_array;
+ n1, n2, n3 : integer;
+ sf_0, sf_2 : flt_t;
+ sqrt2_2 : flt_t;
+ v : flt_t;
+ cos_ptr : pflt_array;
+ i : longint;
+ sf1r, sf2r : pflt_array;
+ dfr, dfi : pflt_array;
+ sf1i, sf2i : pflt_array;
+ c, s : flt_t;
+ temp_ptr : pflt_array;
+ b_0, b_2 : flt_t;
+begin
+ n1 := 1;
+ n2 := 2;
+ n3 := 3;
+
+ (*______________________________________________
+ *
+ * General case
+ *______________________________________________
+ *)
+
+ if _nbr_bits > 2 then
+ begin
+ if _nbr_bits and 1 <> 0 then
+ begin
+ df := pointer(_buffer_ptr);
+ sf := f;
+ end
+ else
+ begin
+ df := f;
+ sf := pointer(_buffer_ptr);
+ end;
+
+ //
+ // Do the transformation in several passes
+ //
+
+ // First and second pass at once
+ bit_rev_lut_ptr := pointer(_bit_rev_lut.get_ptr);
+ coef_index := 0;
+
+ repeat
+ rev_index_0 := bit_rev_lut_ptr^[coef_index];
+ rev_index_1 := bit_rev_lut_ptr^[coef_index + 1];
+ rev_index_2 := bit_rev_lut_ptr^[coef_index + 2];
+ rev_index_3 := bit_rev_lut_ptr^[coef_index + 3];
+
+ df2 := pointer(longint(df) + (coef_index*sizeof_flt));
+ df2^[n1] := x^[rev_index_0] - x^[rev_index_1];
+ df2^[n3] := x^[rev_index_2] - x^[rev_index_3];
+
+ sf_0 := x^[rev_index_0] + x^[rev_index_1];
+ sf_2 := x^[rev_index_2] + x^[rev_index_3];
+
+ df2^[0] := sf_0 + sf_2;
+ df2^[n2] := sf_0 - sf_2;
+
+ inc(coef_index, 4);
+ until (coef_index >= _length);
+
+
+ // Third pass
+ coef_index := 0;
+ sqrt2_2 := _sqrt2_2;
+
+ repeat
+ sf^[coef_index] := df^[coef_index] + df^[coef_index + 4];
+ sf^[coef_index + 4] := df^[coef_index] - df^[coef_index + 4];
+ sf^[coef_index + 2] := df^[coef_index + 2];
+ sf^[coef_index + 6] := df^[coef_index + 6];
+
+ v := (df [coef_index + 5] - df^[coef_index + 7]) * sqrt2_2;
+ sf^[coef_index + 1] := df^[coef_index + 1] + v;
+ sf^[coef_index + 3] := df^[coef_index + 1] - v;
+
+ v := (df^[coef_index + 5] + df^[coef_index + 7]) * sqrt2_2;
+ sf [coef_index + 5] := v + df^[coef_index + 3];
+ sf [coef_index + 7] := v - df^[coef_index + 3];
+
+ inc(coef_index, 8);
+ until (coef_index >= _length);
+
+
+ // Next pass
+ for pass := 3 to _nbr_bits-1 do
+ begin
+ coef_index := 0;
+ nbr_coef := 1 shl pass;
+ h_nbr_coef := nbr_coef shr 1;
+ d_nbr_coef := nbr_coef shl 1;
+
+ cos_ptr := pointer(_trigo_lut.get_ptr(pass));
+ repeat
+ sf1r := pointer(longint(sf) + (coef_index * sizeof_flt));
+ sf2r := pointer(longint(sf1r) + (nbr_coef * sizeof_flt));
+ dfr := pointer(longint(df) + (coef_index * sizeof_flt));
+ dfi := pointer(longint(dfr) + (nbr_coef * sizeof_flt));
+
+ // Extreme coefficients are always real
+ dfr^[0] := sf1r^[0] + sf2r^[0];
+ dfi^[0] := sf1r^[0] - sf2r^[0]; // dfr [nbr_coef] =
+ dfr^[h_nbr_coef] := sf1r^[h_nbr_coef];
+ dfi^[h_nbr_coef] := sf2r^[h_nbr_coef];
+
+ // Others are conjugate complex numbers
+ sf1i := pointer(longint(sf1r) + (h_nbr_coef * sizeof_flt));
+ sf2i := pointer(longint(sf1i) + (nbr_coef * sizeof_flt));
+
+ for i := 1 to h_nbr_coef-1 do
+ begin
+ c := cos_ptr^[i]; // cos (i*PI/nbr_coef);
+ s := cos_ptr^[h_nbr_coef - i]; // sin (i*PI/nbr_coef);
+
+ v := sf2r^[i] * c - sf2i^[i] * s;
+ dfr^[i] := sf1r^[i] + v;
+ dfi^[-i] := sf1r^[i] - v; // dfr [nbr_coef - i] =
+
+ v := sf2r^[i] * s + sf2i^[i] * c;
+ dfi^[i] := v + sf1i^[i];
+ dfi^[nbr_coef - i] := v - sf1i^[i];
+ end;
+
+ inc(coef_index, d_nbr_coef);
+ until (coef_index >= _length);
+
+ // Prepare to the next pass
+ temp_ptr := df;
+ df := sf;
+ sf := temp_ptr;
+ end;
+ end
+
+ (*______________________________________________
+ *
+ * Special cases
+ *______________________________________________
+ *)
+
+ // 4-point FFT
+ else if _nbr_bits = 2 then
+ begin
+ f^[n1] := x^[0] - x^[n2];
+ f^[n3] := x^[n1] - x^[n3];
+
+ b_0 := x^[0] + x^[n2];
+ b_2 := x^[n1] + x^[n3];
+
+ f^[0] := b_0 + b_2;
+ f^[n2] := b_0 - b_2;
+ end
+
+ // 2-point FFT
+ else if _nbr_bits = 1 then
+ begin
+ f^[0] := x^[0] + x^[n1];
+ f^[n1] := x^[0] - x^[n1];
+ end
+
+ // 1-point FFT
+ else
+ f^[0] := x^[0];
+end;
+
+
+(*==========================================================================*/
+/* Name: do_ifft */
+/* Description: Compute the inverse FFT of the array. Notice that */
+/* IFFT (FFT (x)) = x * length (x). Data must be */
+/* post-scaled. */
+/* Input parameters: */
+/* - f: pointer on the source array (frequencies). */
+/* f [0...length(x)/2] = real values, */
+/* f [length(x)/2+1...length(x)-1] = imaginary values of */
+/* coefficents 1...length(x)/2-1. */
+/* Output parameters: */
+/* - x: pointer on the destination array (time). */
+/*==========================================================================*)
+procedure TFFTReal.do_ifft(const f: pflt_array; x: pflt_array);
+var
+ n1, n2, n3 : integer;
+ n4, n5, n6, n7 : integer;
+ sf, df, df_temp : pflt_array;
+ pass : integer;
+ nbr_coef : longint;
+ h_nbr_coef : longint;
+ d_nbr_coef : longint;
+ coef_index : longint;
+ cos_ptr : pflt_array;
+ i : longint;
+ sfr, sfi : pflt_array;
+ df1r, df2r : pflt_array;
+ df1i, df2i : pflt_array;
+ c, s, vr, vi : flt_t;
+ temp_ptr : pflt_array;
+ sqrt2_2 : flt_t;
+ bit_rev_lut_ptr : plongarray;
+ sf2 : pflt_array;
+ b_0, b_1, b_2, b_3 : flt_t;
+begin
+ n1 := 1;
+ n2 := 2;
+ n3 := 3;
+ n4 := 4;
+ n5 := 5;
+ n6 := 6;
+ n7 := 7;
+
+ (*______________________________________________
+ *
+ * General case
+ *______________________________________________
+ *)
+
+ if _nbr_bits > 2 then
+ begin
+ sf := f;
+
+ if _nbr_bits and 1 <> 0 then
+ begin
+ df := pointer(_buffer_ptr);
+ df_temp := x;
+ end
+ else
+ begin
+ df := x;
+ df_temp := pointer(_buffer_ptr);
+ end;
+
+ // Do the transformation in several pass
+
+ // First pass
+ for pass := _nbr_bits-1 downto 3 do
+ begin
+ coef_index := 0;
+ nbr_coef := 1 shl pass;
+ h_nbr_coef := nbr_coef shr 1;
+ d_nbr_coef := nbr_coef shl 1;
+
+ cos_ptr := pointer(_trigo_lut.get_ptr(pass));
+
+ repeat
+ sfr := pointer(longint(sf) + (coef_index*sizeof_flt));
+ sfi := pointer(longint(sfr) + (nbr_coef*sizeof_flt));
+ df1r := pointer(longint(df) + (coef_index*sizeof_flt));
+ df2r := pointer(longint(df1r) + (nbr_coef*sizeof_flt));
+
+ // Extreme coefficients are always real
+ df1r^[0] := sfr^[0] + sfi^[0]; // + sfr [nbr_coef]
+ df2r^[0] := sfr^[0] - sfi^[0]; // - sfr [nbr_coef]
+ df1r^[h_nbr_coef] := sfr^[h_nbr_coef] * 2;
+ df2r^[h_nbr_coef] := sfi^[h_nbr_coef] * 2;
+
+ // Others are conjugate complex numbers
+ df1i := pointer(longint(df1r) + (h_nbr_coef*sizeof_flt));
+ df2i := pointer(longint(df1i) + (nbr_coef*sizeof_flt));
+
+ for i := 1 to h_nbr_coef-1 do
+ begin
+ df1r^[i] := sfr^[i] + sfi^[-i]; // + sfr [nbr_coef - i]
+ df1i^[i] := sfi^[i] - sfi^[nbr_coef - i];
+
+ c := cos_ptr^[i]; // cos (i*PI/nbr_coef);
+ s := cos_ptr^[h_nbr_coef - i]; // sin (i*PI/nbr_coef);
+ vr := sfr^[i] - sfi^[-i]; // - sfr [nbr_coef - i]
+ vi := sfi^[i] + sfi^[nbr_coef - i];
+
+ df2r^[i] := vr * c + vi * s;
+ df2i^[i] := vi * c - vr * s;
+ end;
+
+ inc(coef_index, d_nbr_coef);
+ until (coef_index >= _length);
+
+
+ // Prepare to the next pass
+ if (pass < _nbr_bits - 1) then
+ begin
+ temp_ptr := df;
+ df := sf;
+ sf := temp_ptr;
+ end
+ else
+ begin
+ sf := df;
+ df := df_temp;
+ end
+ end;
+
+ // Antepenultimate pass
+ sqrt2_2 := _sqrt2_2;
+ coef_index := 0;
+
+ repeat
+ df^[coef_index] := sf^[coef_index] + sf^[coef_index + 4];
+ df^[coef_index + 4] := sf^[coef_index] - sf^[coef_index + 4];
+ df^[coef_index + 2] := sf^[coef_index + 2] * 2;
+ df^[coef_index + 6] := sf^[coef_index + 6] * 2;
+
+ df^[coef_index + 1] := sf^[coef_index + 1] + sf^[coef_index + 3];
+ df^[coef_index + 3] := sf^[coef_index + 5] - sf^[coef_index + 7];
+
+ vr := sf^[coef_index + 1] - sf^[coef_index + 3];
+ vi := sf^[coef_index + 5] + sf^[coef_index + 7];
+
+ df^[coef_index + 5] := (vr + vi) * sqrt2_2;
+ df^[coef_index + 7] := (vi - vr) * sqrt2_2;
+
+ inc(coef_index, 8);
+ until (coef_index >= _length);
+
+
+ // Penultimate and last pass at once
+ coef_index := 0;
+ bit_rev_lut_ptr := pointer(_bit_rev_lut.get_ptr);
+ sf2 := df;
+
+ repeat
+ b_0 := sf2^[0] + sf2^[n2];
+ b_2 := sf2^[0] - sf2^[n2];
+ b_1 := sf2^[n1] * 2;
+ b_3 := sf2^[n3] * 2;
+
+ x^[bit_rev_lut_ptr^[0]] := b_0 + b_1;
+ x^[bit_rev_lut_ptr^[n1]] := b_0 - b_1;
+ x^[bit_rev_lut_ptr^[n2]] := b_2 + b_3;
+ x^[bit_rev_lut_ptr^[n3]] := b_2 - b_3;
+
+ b_0 := sf2^[n4] + sf2^[n6];
+ b_2 := sf2^[n4] - sf2^[n6];
+ b_1 := sf2^[n5] * 2;
+ b_3 := sf2^[n7] * 2;
+
+ x^[bit_rev_lut_ptr^[n4]] := b_0 + b_1;
+ x^[bit_rev_lut_ptr^[n5]] := b_0 - b_1;
+ x^[bit_rev_lut_ptr^[n6]] := b_2 + b_3;
+ x^[bit_rev_lut_ptr^[n7]] := b_2 - b_3;
+
+ inc(sf2, 8);
+ inc(coef_index, 8);
+ inc(bit_rev_lut_ptr, 8);
+ until (coef_index >= _length);
+ end
+
+ (*______________________________________________
+ *
+ * Special cases
+ *______________________________________________
+ *)
+
+ // 4-point IFFT
+ else if _nbr_bits = 2 then
+ begin
+ b_0 := f^[0] + f [n2];
+ b_2 := f^[0] - f [n2];
+
+ x^[0] := b_0 + f [n1] * 2;
+ x^[n2] := b_0 - f [n1] * 2;
+ x^[n1] := b_2 + f [n3] * 2;
+ x^[n3] := b_2 - f [n3] * 2;
+ end
+
+ // 2-point IFFT
+ else if _nbr_bits = 1 then
+ begin
+ x^[0] := f^[0] + f^[n1];
+ x^[n1] := f^[0] - f^[n1];
+ end
+
+ // 1-point IFFT
+ else
+ x^[0] := f^[0];
+end;
+
+(*==========================================================================*/
+/* Name: rescale */
+/* Description: Scale an array by divide each element by its length. */
+/* This function should be called after FFT + IFFT. */
+/* Input/Output parameters: */
+/* - x: pointer on array to rescale (time or frequency). */
+/*==========================================================================*)
+procedure TFFTReal.rescale(x: pflt_array);
+var
+ mul : flt_t;
+ i : longint;
+begin
+ mul := 1.0 / _length;
+ i := _length - 1;
+
+ repeat
+ x^[i] := x^[i] * mul;
+ dec(i);
+ until (i < 0);
+end;
+
+end.
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/fftreal.pro b/examples/multimedia/spectrum/3rdparty/fftreal/fftreal.pro
new file mode 100644
index 000000000..f6abeeb15
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/fftreal.pro
@@ -0,0 +1,44 @@
+include(../../spectrum.pri)
+
+static: error(This library cannot be built for static linkage)
+
+TEMPLATE = lib
+TARGET = fftreal
+
+# FFTReal
+HEADERS += Array.h \
+ Array.hpp \
+ DynArray.h \
+ DynArray.hpp \
+ FFTRealFixLen.h \
+ FFTRealFixLen.hpp \
+ FFTRealFixLenParam.h \
+ FFTRealPassDirect.h \
+ FFTRealPassDirect.hpp \
+ FFTRealPassInverse.h \
+ FFTRealPassInverse.hpp \
+ FFTRealSelect.h \
+ FFTRealSelect.hpp \
+ FFTRealUseTrigo.h \
+ FFTRealUseTrigo.hpp \
+ OscSinCos.h \
+ OscSinCos.hpp \
+ def.h
+
+# Wrapper used to export the required instantiation of the FFTRealFixLen template
+HEADERS += fftreal_wrapper.h
+SOURCES += fftreal_wrapper.cpp
+
+DEFINES += FFTREAL_LIBRARY
+
+macx {
+ CONFIG += lib_bundle
+} else {
+ DESTDIR = ../..$${spectrum_build_dir}
+}
+
+EXAMPLE_FILES = bwins/fftreal.def eabi/fftreal.def readme.txt license.txt
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/spectrum
+INSTALLS += target
+
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp b/examples/multimedia/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp
new file mode 100644
index 000000000..ef216cb58
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp
@@ -0,0 +1,54 @@
+/***************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as
+** published by the Free Software Foundation, either version 2.1. This
+** program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+** for more details. You should have received a copy of the GNU General
+** Public License along with this program. If not, see
+** <http://www.gnu.org/licenses/>.
+**
+***************************************************************************/
+
+#include "fftreal_wrapper.h"
+
+// FFTReal code generates quite a lot of 'unused parameter' compiler warnings,
+// which we suppress here in order to get a clean build output.
+#if defined Q_CC_MSVC
+# pragma warning(disable:4100)
+#elif defined Q_CC_GNU
+# pragma GCC diagnostic ignored "-Wunused-parameter"
+#elif defined Q_CC_MWERKS
+# pragma warning off (10182)
+#endif
+
+#include "FFTRealFixLen.h"
+
+class FFTRealWrapperPrivate {
+public:
+ FFTRealFixLen<FFTLengthPowerOfTwo> m_fft;
+};
+
+
+FFTRealWrapper::FFTRealWrapper()
+ : m_private(new FFTRealWrapperPrivate)
+{
+
+}
+
+FFTRealWrapper::~FFTRealWrapper()
+{
+ delete m_private;
+}
+
+void FFTRealWrapper::calculateFFT(DataType in[], const DataType out[])
+{
+ m_private->m_fft.do_fft(in, out);
+}
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/fftreal_wrapper.h b/examples/multimedia/spectrum/3rdparty/fftreal/fftreal_wrapper.h
new file mode 100644
index 000000000..9a72fe662
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/fftreal_wrapper.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as
+** published by the Free Software Foundation, either version 2.1. This
+** program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+** for more details. You should have received a copy of the GNU General
+** Public License along with this program. If not, see
+** <http://www.gnu.org/licenses/>.
+**
+***************************************************************************/
+
+#ifndef FFTREAL_WRAPPER_H
+#define FFTREAL_WRAPPER_H
+
+#include <QtCore/QtGlobal>
+
+#if defined(FFTREAL_LIBRARY)
+# define FFTREAL_EXPORT Q_DECL_EXPORT
+#else
+# define FFTREAL_EXPORT Q_DECL_IMPORT
+#endif
+
+class FFTRealWrapperPrivate;
+
+// Each pass of the FFT processes 2^X samples, where X is the
+// number below.
+static const int FFTLengthPowerOfTwo = 12;
+
+/**
+ * Wrapper around the FFTRealFixLen template provided by the FFTReal
+ * library
+ *
+ * This class instantiates a single instance of FFTRealFixLen, using
+ * FFTLengthPowerOfTwo as the template parameter. It then exposes
+ * FFTRealFixLen<FFTLengthPowerOfTwo>::do_fft via the calculateFFT
+ * function, thereby allowing an application to dynamically link
+ * against the FFTReal implementation.
+ *
+ * See http://ldesoras.free.fr/prod.html
+ */
+class FFTREAL_EXPORT FFTRealWrapper
+{
+public:
+ FFTRealWrapper();
+ ~FFTRealWrapper();
+
+ typedef float DataType;
+ void calculateFFT(DataType in[], const DataType out[]);
+
+private:
+ FFTRealWrapperPrivate* m_private;
+};
+
+#endif // FFTREAL_WRAPPER_H
+
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/license.txt b/examples/multimedia/spectrum/3rdparty/fftreal/license.txt
new file mode 100644
index 000000000..918fe68ea
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/license.txt
@@ -0,0 +1,459 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/readme.txt b/examples/multimedia/spectrum/3rdparty/fftreal/readme.txt
new file mode 100644
index 000000000..0c5ce162f
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/readme.txt
@@ -0,0 +1,242 @@
+==============================================================================
+
+ FFTReal
+ Version 2.00, 2005/10/18
+
+ Fourier transformation (FFT, IFFT) library specialised for real data
+ Portable ISO C++
+
+ (c) Laurent de Soras <laurent.de.soras@club-internet.fr>
+ Object Pascal port (c) Frederic Vanmol <frederic@fruityloops.com>
+
+==============================================================================
+
+
+
+1. Legal
+--------
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Check the file license.txt to get full information about the license.
+
+
+
+2. Content
+----------
+
+FFTReal is a library to compute Discrete Fourier Transforms (DFT) with the
+FFT algorithm (Fast Fourier Transform) on arrays of real numbers. It can
+also compute the inverse transform.
+
+You should find in this package a lot of files ; some of them are of interest:
+- readme.txt: you are reading it
+- FFTReal.h: FFT, length fixed at run-time
+- FFTRealFixLen.h: FFT, length fixed at compile-time
+- FFTReal.pas: Pascal implementation (working but not up-to-date)
+- stopwatch directory
+
+
+
+3. Using FFTReal
+----------------
+
+Important - if you were using older versions of FFTReal (up to 1.03), some
+things have changed. FFTReal is now a template. Therefore use FFTReal<float>
+or FFTReal<double> in your code depending on the application datatype. The
+flt_t typedef has been removed.
+
+You have two ways to use FFTReal. In the first way, the FFT has its length
+fixed at run-time, when the object is instanciated. It means that you have
+not to know the length when you write the code. This is the usual way of
+proceeding.
+
+
+3.1 FFTReal - Length fixed at run-time
+--------------------------------------
+
+Just instanciate one time a FFTReal object. Specify the data type you want
+as template parameter (only floating point: float, double, long double or
+custom type). The constructor precompute a lot of things, so it may be a bit
+long. The parameter is the number of points used for the next FFTs. It must
+be a power of 2:
+
+ #include "FFTReal.h"
+ ...
+ long len = 1024;
+ ...
+ FFTReal <float> fft_object (len); // 1024-point FFT object constructed.
+
+Then you can use this object to compute as many FFTs and IFFTs as you want.
+They will be computed very quickly because a lot of work has been done in the
+object construction.
+
+ float x [1024];
+ float f [1024];
+
+ ...
+ fft_object.do_fft (f, x); // x (real) --FFT---> f (complex)
+ ...
+ fft_object.do_ifft (f, x); // f (complex) --IFFT--> x (real)
+ fft_object.rescale (x); // Post-scaling should be done after FFT+IFFT
+ ...
+
+x [] and f [] are floating point number arrays. x [] is the real number
+sequence which we want to compute the FFT. f [] is the result, in the
+"frequency" domain. f has the same number of elements as x [], but f []
+elements are complex numbers. The routine uses some FFT properties to
+optimize memory and to reduce calculations: the transformaton of a real
+number sequence is a conjugate complex number sequence: F [k] = F [-k]*.
+
+
+3.2 FFTRealFixLen - Length fixed at compile-time
+------------------------------------------------
+
+This class is significantly faster than the previous one, giving a speed
+gain between 50 and 100 %. The template parameter is the base-2 logarithm of
+the FFT length. The datatype is float; it can be changed by modifying the
+DataType typedef in FFTRealFixLenParam.h. As FFTReal class, it supports
+only floating-point types or equivalent.
+
+To instanciate the object, just proceed as below:
+
+ #include "FFTRealFixLen.h"
+ ...
+ FFTRealFixLen <10> fft_object; // 1024-point (2^10) FFT object constructed.
+
+Use is similar as the one of FFTReal.
+
+
+3.3 Data organisation
+---------------------
+
+Mathematically speaking, the formulas below show what does FFTReal:
+
+do_fft() : f(k) = sum (p = 0, N-1, x(p) * exp (+j*2*pi*k*p/N))
+do_ifft(): x(k) = sum (p = 0, N-1, f(p) * exp (-j*2*pi*k*p/N))
+
+Where j is the square root of -1. The formulas differ only by the sign of
+the exponential. When the sign is positive, the transform is called positive.
+Common formulas for Fourier transform are negative for the direct tranform and
+positive for the inverse one.
+
+However in these formulas, f is an array of complex numbers and doesn't
+correspound exactly to the f[] array taken as function parameter. The
+following table shows how the f[] sequence is mapped onto the usable FFT
+coefficients (called bins):
+
+ FFTReal output | Positive FFT equiv. | Negative FFT equiv.
+ ---------------+-----------------------+-----------------------
+ f [0] | Real (bin 0) | Real (bin 0)
+ f [...] | Real (bin ...) | Real (bin ...)
+ f [length/2] | Real (bin length/2) | Real (bin length/2)
+ f [length/2+1] | Imag (bin 1) | -Imag (bin 1)
+ f [...] | Imag (bin ...) | -Imag (bin ...)
+ f [length-1] | Imag (bin length/2-1) | -Imag (bin length/2-1)
+
+And FFT bins are distributed in f [] as above:
+
+ | | Positive FFT | Negative FFT
+ Bin | Real part | imaginary part | imaginary part
+ ------------+----------------+-----------------+---------------
+ 0 | f [0] | 0 | 0
+ 1 | f [1] | f [length/2+1] | -f [length/2+1]
+ ... | f [...], | f [...] | -f [...]
+ length/2-1 | f [length/2-1] | f [length-1] | -f [length-1]
+ length/2 | f [length/2] | 0 | 0
+ length/2+1 | f [length/2-1] | -f [length-1] | f [length-1]
+ ... | f [...] | -f [...] | f [...]
+ length-1 | f [1] | -f [length/2+1] | f [length/2+1]
+
+f [] coefficients have the same layout for FFT and IFFT functions. You may
+notice that scaling must be done if you want to retrieve x after FFT and IFFT.
+Actually, IFFT (FFT (x)) = x * length(x). This is a not a problem because
+most of the applications don't care about absolute values. Thus, the operation
+requires less calculation. If you want to use the FFT and IFFT to transform a
+signal, you have to apply post- (or pre-) processing yourself. Multiplying
+or dividing floating point numbers by a power of 2 doesn't generate extra
+computation noise.
+
+
+
+4. Compilation and testing
+--------------------------
+
+Drop the following files into your project or makefile:
+
+Array.*
+def.h
+DynArray.*
+FFTReal*.cpp
+FFTReal*.h*
+OscSinCos.*
+
+Other files are for testing purpose only, do not include them if you just need
+to use the library ; they are not needed to use FFTReal in your own programs.
+
+FFTReal may be compiled in two versions: release and debug. Debug version
+has checks that could slow down the code. Define NDEBUG to set the Release
+mode. For example, the command line to compile the test bench on GCC would
+look like:
+
+Debug mode:
+g++ -Wall -o fftreal_debug.exe *.cpp stopwatch/*.cpp
+
+Release mode:
+g++ -Wall -o fftreal_release.exe -DNDEBUG -O3 *.cpp stopwatch/*.cpp
+
+It may be tricky to compile the test bench because the speed tests use the
+stopwatch sub-library, which is not that cross-platform. If you encounter
+any problem that you cannot easily fix while compiling it, edit the file
+test_settings.h and un-define the speed test macro. Remove the stopwatch
+directory from your source file list, too.
+
+If it's not done by default, you should activate the exception handling
+of your compiler to get the class memory-leak-safe. Thus, when a memory
+allocation fails (in the constructor), an exception is thrown and the entire
+object is safely destructed. It reduces the permanent error checking overhead
+in the client code. Also, the test bench requires Run-Time Type Information
+(RTTI) to be enabled in order to display the names of the tested classes -
+sometimes mangled, depending on the compiler.
+
+The test bench may take a long time to compile, especially in Release mode,
+because a lot of recursive templates are instanciated.
+
+
+
+5. History
+----------
+
+v2.00 (2005.10.18)
+- Turned FFTReal class into template (data type as parameter)
+- Added FFTRealFixLen
+- Trigonometric tables are size-limited in order to preserve cache memory;
+over a given size, sin/cos functions are computed on the fly.
+- Better test bench for accuracy and speed
+
+v1.03 (2001.06.15)
+- Thanks to Frederic Vanmol for the Pascal port (works with Delphi).
+- Documentation improvement
+
+v1.02 (2001.03.25)
+- sqrt() is now precomputed when the object FFTReal is constructed, resulting
+in speed impovement for small size FFT.
+
+v1.01 (2000)
+- Small modifications, I don't remember what.
+
+v1.00 (1999.08.14)
+- First version released
+
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.cpp b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.cpp
new file mode 100644
index 000000000..fe1d4245f
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.cpp
@@ -0,0 +1,285 @@
+/*****************************************************************************
+
+ ClockCycleCounter.cpp
+ Copyright (c) 2003 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (_MSC_VER)
+ #pragma warning (1 : 4130) // "'operator' : logical operation on address of string constant"
+ #pragma warning (1 : 4223) // "nonstandard extension used : non-lvalue array converted to pointer"
+ #pragma warning (1 : 4705) // "statement has no effect"
+ #pragma warning (1 : 4706) // "assignment within conditional expression"
+ #pragma warning (4 : 4786) // "identifier was truncated to '255' characters in the debug information"
+ #pragma warning (4 : 4800) // "forcing value to bool 'true' or 'false' (performance warning)"
+ #pragma warning (4 : 4355) // "'this' : used in base member initializer list"
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "ClockCycleCounter.h"
+
+#include <cassert>
+
+
+
+namespace stopwatch
+{
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*
+==============================================================================
+Name: ctor
+Description:
+ The first object constructed initialise global data. This first
+ construction may be a bit slow.
+Throws: Nothing
+==============================================================================
+*/
+
+ClockCycleCounter::ClockCycleCounter ()
+: _start_time (0)
+, _state (0)
+, _best_score (-1)
+{
+ if (! _init_flag)
+ {
+ // Should be executed in this order
+ compute_clk_mul ();
+ compute_measure_time_total ();
+ compute_measure_time_lap ();
+
+ // Restores object state
+ _start_time = 0;
+ _state = 0;
+ _best_score = -1;
+
+ _init_flag = true;
+ }
+}
+
+
+
+/*
+==============================================================================
+Name: get_time_total
+Description:
+ Gives the time elapsed between the latest stop_lap() and start() calls.
+Returns:
+ The duration, in clock cycles.
+Throws: Nothing
+==============================================================================
+*/
+
+Int64 ClockCycleCounter::get_time_total () const
+{
+ const Int64 duration = _state - _start_time;
+ assert (duration >= 0);
+
+ const Int64 t = max (
+ duration - _measure_time_total,
+ static_cast <Int64> (0)
+ );
+
+ return (t * _clk_mul);
+}
+
+
+
+/*
+==============================================================================
+Name: get_time_best_lap
+Description:
+ Gives the smallest time between two consecutive stop_lap() or between
+ the stop_lap() and start(). The value is reset by a call to start().
+ Call this function only after a stop_lap().
+ The time is amputed from the duration of the stop_lap() call itself.
+Returns:
+ The smallest duration, in clock cycles.
+Throws: Nothing
+==============================================================================
+*/
+
+Int64 ClockCycleCounter::get_time_best_lap () const
+{
+ assert (_best_score >= 0);
+
+ const Int64 t1 = max (
+ _best_score - _measure_time_lap,
+ static_cast <Int64> (0)
+ );
+ const Int64 t = min (t1, get_time_total ());
+
+ return (t * _clk_mul);
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+#if defined (__MACOS__)
+
+static inline double stopwatch_ClockCycleCounter_get_time_s ()
+{
+ const Nanoseconds ns = AbsoluteToNanoseconds (UpTime ());
+
+ return (ns.hi * 4294967296e-9 + ns.lo * 1e-9);
+}
+
+#endif // __MACOS__
+
+
+
+/*
+==============================================================================
+Name: compute_clk_mul
+Description:
+ This function, only for PowerPC/MacOS computers, computes the multiplier
+ required to deduce clock cycles from the internal counter.
+Throws: Nothing
+==============================================================================
+*/
+
+void ClockCycleCounter::compute_clk_mul ()
+{
+ assert (! _init_flag);
+
+#if defined (__MACOS__)
+
+ long clk_speed_mhz = CurrentProcessorSpeed ();
+ const Int64 clk_speed =
+ static_cast <Int64> (clk_speed_mhz) * (1000L*1000L);
+
+ const double start_time_s = stopwatch_ClockCycleCounter_get_time_s ();
+ start ();
+
+ const double duration = 0.01; // Seconds
+ while (stopwatch_ClockCycleCounter_get_time_s () - start_time_s < duration)
+ {
+ continue;
+ }
+
+ const double stop_time_s = stopwatch_ClockCycleCounter_get_time_s ();
+ stop ();
+
+ const double diff_time_s = stop_time_s - start_time_s;
+ const double nbr_cycles = diff_time_s * static_cast <double> (clk_speed);
+
+ const Int64 diff_time_c = _state - _start_time;
+ const double clk_mul = nbr_cycles / static_cast <double> (diff_time_c);
+
+ _clk_mul = round_int (clk_mul);
+
+#endif // __MACOS__
+}
+
+
+
+void ClockCycleCounter::compute_measure_time_total ()
+{
+ start ();
+ spend_time ();
+
+ Int64 best_result = 0x7FFFFFFFL; // Should be enough
+ long nbr_tests = 100;
+ for (long cnt = 0; cnt < nbr_tests; ++cnt)
+ {
+ start ();
+ stop_lap ();
+ const Int64 duration = _state - _start_time;
+ best_result = min (best_result, duration);
+ }
+
+ _measure_time_total = best_result;
+}
+
+
+
+/*
+==============================================================================
+Name: compute_measure_time_lap
+Description:
+ Computes the duration of one stop_lap() call and store it. It will be used
+ later to get the real duration of the measured operation (by substracting
+ the measurement duration).
+Throws: Nothing
+==============================================================================
+*/
+
+void ClockCycleCounter::compute_measure_time_lap ()
+{
+ start ();
+ spend_time ();
+
+ long nbr_tests = 10;
+ for (long cnt = 0; cnt < nbr_tests; ++cnt)
+ {
+ stop_lap ();
+ stop_lap ();
+ stop_lap ();
+ stop_lap ();
+ }
+
+ _measure_time_lap = _best_score;
+}
+
+
+
+void ClockCycleCounter::spend_time ()
+{
+ const Int64 nbr_clocks = 500; // Number of clock cycles to spend
+
+ const Int64 start = read_clock_counter ();
+ Int64 current;
+
+ do
+ {
+ current = read_clock_counter ();
+ }
+ while ((current - start) * _clk_mul < nbr_clocks);
+}
+
+
+
+Int64 ClockCycleCounter::_measure_time_total = 0;
+Int64 ClockCycleCounter::_measure_time_lap = 0;
+int ClockCycleCounter::_clk_mul = 1;
+bool ClockCycleCounter::_init_flag = false;
+
+
+} // namespace stopwatch
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.h b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.h
new file mode 100644
index 000000000..ba7a99a46
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.h
@@ -0,0 +1,124 @@
+/*****************************************************************************
+
+ ClockCycleCounter.h
+ Copyright (c) 2003 Laurent de Soras
+
+Instrumentation class, for accurate time interval measurement. You may have
+to modify the implementation to adapt it to your system and/or compiler.
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (stopwatch_ClockCycleCounter_HEADER_INCLUDED)
+#define stopwatch_ClockCycleCounter_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "def.h"
+#include "Int64.h"
+
+
+
+namespace stopwatch
+{
+
+
+
+class ClockCycleCounter
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ ClockCycleCounter ();
+
+ stopwatch_FORCEINLINE void
+ start ();
+ stopwatch_FORCEINLINE void
+ stop_lap ();
+ Int64 get_time_total () const;
+ Int64 get_time_best_lap () const;
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ void compute_clk_mul ();
+ void compute_measure_time_total ();
+ void compute_measure_time_lap ();
+
+ static void spend_time ();
+ static stopwatch_FORCEINLINE Int64
+ read_clock_counter ();
+
+ Int64 _start_time;
+ Int64 _state;
+ Int64 _best_score;
+
+ static Int64 _measure_time_total;
+ static Int64 _measure_time_lap;
+ static int _clk_mul;
+ static bool _init_flag;
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ ClockCycleCounter (const ClockCycleCounter &other);
+ ClockCycleCounter &
+ operator = (const ClockCycleCounter &other);
+ bool operator == (const ClockCycleCounter &other);
+ bool operator != (const ClockCycleCounter &other);
+
+}; // class ClockCycleCounter
+
+
+
+} // namespace stopwatch
+
+
+
+#include "ClockCycleCounter.hpp"
+
+
+
+#endif // stopwatch_ClockCycleCounter_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.hpp
new file mode 100644
index 000000000..fbd511e25
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/ClockCycleCounter.hpp
@@ -0,0 +1,150 @@
+/*****************************************************************************
+
+ ClockCycleCounter.hpp
+ Copyright (c) 2003 Laurent de Soras
+
+Please complete the definitions according to your compiler/architecture.
+It's not a big deal if it's not possible to get the clock count...
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (stopwatch_ClockCycleCounter_CURRENT_CODEHEADER)
+ #error Recursive inclusion of ClockCycleCounter code header.
+#endif
+#define stopwatch_ClockCycleCounter_CURRENT_CODEHEADER
+
+#if ! defined (stopwatch_ClockCycleCounter_CODEHEADER_INCLUDED)
+#define stopwatch_ClockCycleCounter_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "fnc.h"
+
+#include <climits>
+
+
+
+namespace stopwatch
+{
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*
+==============================================================================
+Name: start
+Description:
+ Starts the counter.
+Throws: Nothing
+==============================================================================
+*/
+
+void ClockCycleCounter::start ()
+{
+ _best_score = (static_cast <Int64> (1) << (sizeof (Int64) * CHAR_BIT - 2));
+ const Int64 start_clock = read_clock_counter ();
+ _start_time = start_clock;
+ _state = start_clock - _best_score;
+}
+
+
+
+/*
+==============================================================================
+Name: stop_lap
+Description:
+ Captures the current time and updates the smallest duration between two
+ consecutive calls to stop_lap() or the latest start().
+ start() must have been called at least once before calling this function.
+Throws: Nothing
+==============================================================================
+*/
+
+void ClockCycleCounter::stop_lap ()
+{
+ const Int64 end_clock = read_clock_counter ();
+ _best_score = min (end_clock - _state, _best_score);
+ _state = end_clock;
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+Int64 ClockCycleCounter::read_clock_counter ()
+{
+ register Int64 clock_cnt;
+
+#if defined (_MSC_VER)
+
+ __asm
+ {
+ lea edi, clock_cnt
+ rdtsc
+ mov [edi ], eax
+ mov [edi + 4], edx
+ }
+
+#elif defined (__GNUC__) && defined (__i386__)
+
+ __asm__ __volatile__ ("rdtsc" : "=A" (clock_cnt));
+
+#elif (__MWERKS__) && defined (__POWERPC__)
+
+ asm
+ {
+ loop:
+ mftbu clock_cnt@hiword
+ mftb clock_cnt@loword
+ mftbu r5
+ cmpw clock_cnt@hiword,r5
+ bne loop
+ }
+
+#endif
+
+ return (clock_cnt);
+}
+
+
+
+} // namespace stopwatch
+
+
+
+#endif // stopwatch_ClockCycleCounter_CODEHEADER_INCLUDED
+
+#undef stopwatch_ClockCycleCounter_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/Int64.h b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/Int64.h
new file mode 100644
index 000000000..1e786e255
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/Int64.h
@@ -0,0 +1,71 @@
+/*****************************************************************************
+
+ Int64.h
+ Copyright (c) 2003 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (stopwatch_Int64_HEADER_INCLUDED)
+#define stopwatch_Int64_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+namespace stopwatch
+{
+
+
+#if defined (_MSC_VER)
+
+ typedef __int64 Int64;
+
+#elif defined (__MWERKS__) || defined (__GNUC__)
+
+ typedef long long Int64;
+
+#elif defined (__BEOS__)
+
+ typedef int64 Int64;
+
+#else
+
+ #error No 64-bit integer type defined for this compiler !
+
+#endif
+
+
+} // namespace stopwatch
+
+
+
+#endif // stopwatch_Int64_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.cpp b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.cpp
new file mode 100644
index 000000000..7795d86d6
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.cpp
@@ -0,0 +1,101 @@
+/*****************************************************************************
+
+ StopWatch.cpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (_MSC_VER)
+ #pragma warning (1 : 4130) // "'operator' : logical operation on address of string constant"
+ #pragma warning (1 : 4223) // "nonstandard extension used : non-lvalue array converted to pointer"
+ #pragma warning (1 : 4705) // "statement has no effect"
+ #pragma warning (1 : 4706) // "assignment within conditional expression"
+ #pragma warning (4 : 4786) // "identifier was truncated to '255' characters in the debug information"
+ #pragma warning (4 : 4800) // "forcing value to bool 'true' or 'false' (performance warning)"
+ #pragma warning (4 : 4355) // "'this' : used in base member initializer list"
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "StopWatch.h"
+
+#include <cassert>
+
+
+
+namespace stopwatch
+{
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+StopWatch::StopWatch ()
+: _ccc ()
+, _nbr_laps (0)
+{
+ // Nothing
+}
+
+
+
+double StopWatch::get_time_total (Int64 nbr_op) const
+{
+ assert (_nbr_laps > 0);
+ assert (nbr_op > 0);
+
+ return (
+ static_cast <double> (_ccc.get_time_total ())
+ / (static_cast <double> (nbr_op) * static_cast <double> (_nbr_laps))
+ );
+}
+
+
+
+double StopWatch::get_time_best_lap (Int64 nbr_op) const
+{
+ assert (nbr_op > 0);
+
+ return (
+ static_cast <double> (_ccc.get_time_best_lap ())
+ / static_cast <double> (nbr_op)
+ );
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+} // namespace stopwatch
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.h b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.h
new file mode 100644
index 000000000..9cc47e5f2
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.h
@@ -0,0 +1,110 @@
+/*****************************************************************************
+
+ StopWatch.h
+ Copyright (c) 2005 Laurent de Soras
+
+Utility class based on ClockCycleCounter to measure the unit time of a
+repeated operation.
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (stopwatch_StopWatch_HEADER_INCLUDED)
+#define stopwatch_StopWatch_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "ClockCycleCounter.h"
+
+
+
+namespace stopwatch
+{
+
+
+
+class StopWatch
+{
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+public:
+
+ StopWatch ();
+
+ stopwatch_FORCEINLINE void
+ start ();
+ stopwatch_FORCEINLINE void
+ stop_lap ();
+
+ double get_time_total (Int64 nbr_op) const;
+ double get_time_best_lap (Int64 nbr_op) const;
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+protected:
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ ClockCycleCounter
+ _ccc;
+ Int64 _nbr_laps;
+
+
+
+/*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+private:
+
+ StopWatch (const StopWatch &other);
+ StopWatch & operator = (const StopWatch &other);
+ bool operator == (const StopWatch &other);
+ bool operator != (const StopWatch &other);
+
+}; // class StopWatch
+
+
+
+} // namespace stopwatch
+
+
+
+#include "StopWatch.hpp"
+
+
+
+#endif // stopwatch_StopWatch_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.hpp
new file mode 100644
index 000000000..74482a7a7
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/StopWatch.hpp
@@ -0,0 +1,83 @@
+/*****************************************************************************
+
+ StopWatch.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (stopwatch_StopWatch_CURRENT_CODEHEADER)
+ #error Recursive inclusion of StopWatch code header.
+#endif
+#define stopwatch_StopWatch_CURRENT_CODEHEADER
+
+#if ! defined (stopwatch_StopWatch_CODEHEADER_INCLUDED)
+#define stopwatch_StopWatch_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+namespace stopwatch
+{
+
+
+
+/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+void StopWatch::start ()
+{
+ _nbr_laps = 0;
+ _ccc.start ();
+}
+
+
+
+void StopWatch::stop_lap ()
+{
+ _ccc.stop_lap ();
+ ++ _nbr_laps;
+}
+
+
+
+/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+} // namespace stopwatch
+
+
+
+#endif // stopwatch_StopWatch_CODEHEADER_INCLUDED
+
+#undef stopwatch_StopWatch_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/def.h b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/def.h
new file mode 100644
index 000000000..81ee6aaa3
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/def.h
@@ -0,0 +1,65 @@
+/*****************************************************************************
+
+ def.h
+ Copyright (c) 2003 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (stopwatch_def_HEADER_INCLUDED)
+#define stopwatch_def_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+namespace stopwatch
+{
+
+
+
+#if defined (_MSC_VER)
+
+ #define stopwatch_FORCEINLINE __forceinline
+
+#else
+
+ #define stopwatch_FORCEINLINE inline
+
+#endif
+
+
+
+} // namespace stopwatch
+
+
+
+#endif // stopwatch_def_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/fnc.h b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/fnc.h
new file mode 100644
index 000000000..055453543
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/fnc.h
@@ -0,0 +1,67 @@
+/*****************************************************************************
+
+ fnc.h
+ Copyright (c) 2003 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (stopwatch_fnc_HEADER_INCLUDED)
+#define stopwatch_fnc_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+namespace stopwatch
+{
+
+
+
+template <typename T>
+inline T min (T a, T b);
+
+template <typename T>
+inline T max (T a, T b);
+
+inline int round_int (double x);
+
+
+
+} // namespace rsp
+
+
+
+#include "fnc.hpp"
+
+
+
+#endif // stopwatch_fnc_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/fnc.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/fnc.hpp
new file mode 100644
index 000000000..0ab5949ef
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/stopwatch/fnc.hpp
@@ -0,0 +1,85 @@
+/*****************************************************************************
+
+ fnc.hpp
+ Copyright (c) 2003 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (stopwatch_fnc_CURRENT_CODEHEADER)
+ #error Recursive inclusion of fnc code header.
+#endif
+#define stopwatch_fnc_CURRENT_CODEHEADER
+
+#if ! defined (stopwatch_fnc_CODEHEADER_INCLUDED)
+#define stopwatch_fnc_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include <cassert>
+#include <cmath>
+
+namespace std {}
+
+
+
+namespace stopwatch
+{
+
+
+
+template <typename T>
+inline T min (T a, T b)
+{
+ return ((a < b) ? a : b);
+}
+
+
+
+template <typename T>
+inline T max (T a, T b)
+{
+ return ((b < a) ? a : b);
+}
+
+
+
+int round_int (double x)
+{
+ using namespace std;
+
+ return (static_cast <int> (floor (x + 0.5)));
+}
+
+
+
+} // namespace stopwatch
+
+
+
+#endif // stopwatch_fnc_CODEHEADER_INCLUDED
+
+#undef stopwatch_fnc_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/test.cpp b/examples/multimedia/spectrum/3rdparty/fftreal/test.cpp
new file mode 100644
index 000000000..7b6ed2cab
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/test.cpp
@@ -0,0 +1,267 @@
+/*****************************************************************************
+
+ test.cpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (_MSC_VER)
+ #pragma warning (4 : 4786) // "identifier was truncated to '255' characters in the debug information"
+ #pragma warning (4 : 4800) // "forcing value to bool 'true' or 'false' (performance warning)"
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+#include "test_settings.h"
+#include "TestHelperFixLen.h"
+#include "TestHelperNormal.h"
+
+#if defined (_MSC_VER)
+#include <crtdbg.h>
+#include <new.h>
+#endif // _MSC_VER
+
+#include <new>
+
+#include <cassert>
+#include <cstdio>
+
+
+
+#define TEST_
+
+
+/*\\\ FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+static int TEST_perform_test_accuracy_all ();
+static int TEST_perform_test_speed_all ();
+
+static void TEST_prog_init ();
+static void TEST_prog_end ();
+
+
+
+int main (int argc, char *argv [])
+{
+ using namespace std;
+
+ int ret_val = 0;
+
+ TEST_prog_init ();
+
+ try
+ {
+ if (ret_val == 0)
+ {
+ ret_val = TEST_perform_test_accuracy_all ();
+ }
+
+ if (ret_val == 0)
+ {
+ ret_val = TEST_perform_test_speed_all ();
+ }
+ }
+
+ catch (std::exception &e)
+ {
+ printf ("\n*** main(): Exception (std::exception) : %s\n", e.what ());
+ ret_val = -1;
+ }
+
+ catch (...)
+ {
+ printf ("\n*** main(): Undefined exception\n");
+ ret_val = -1;
+ }
+
+ TEST_prog_end ();
+
+ return (ret_val);
+}
+
+
+
+int TEST_perform_test_accuracy_all ()
+{
+ int ret_val = 0;
+
+ TestHelperNormal <float >::perform_test_accuracy (ret_val);
+ TestHelperNormal <double>::perform_test_accuracy (ret_val);
+
+ TestHelperFixLen < 1>::perform_test_accuracy (ret_val);
+ TestHelperFixLen < 2>::perform_test_accuracy (ret_val);
+ TestHelperFixLen < 3>::perform_test_accuracy (ret_val);
+ TestHelperFixLen < 4>::perform_test_accuracy (ret_val);
+ TestHelperFixLen < 7>::perform_test_accuracy (ret_val);
+ TestHelperFixLen < 8>::perform_test_accuracy (ret_val);
+ TestHelperFixLen <10>::perform_test_accuracy (ret_val);
+ TestHelperFixLen <12>::perform_test_accuracy (ret_val);
+ TestHelperFixLen <13>::perform_test_accuracy (ret_val);
+
+ return (ret_val);
+}
+
+
+
+int TEST_perform_test_speed_all ()
+{
+ int ret_val = 0;
+
+#if defined (test_settings_SPEED_TEST_ENABLED)
+
+ TestHelperNormal <float >::perform_test_speed (ret_val);
+ TestHelperNormal <double>::perform_test_speed (ret_val);
+
+ TestHelperFixLen < 1>::perform_test_speed (ret_val);
+ TestHelperFixLen < 2>::perform_test_speed (ret_val);
+ TestHelperFixLen < 3>::perform_test_speed (ret_val);
+ TestHelperFixLen < 4>::perform_test_speed (ret_val);
+ TestHelperFixLen < 7>::perform_test_speed (ret_val);
+ TestHelperFixLen < 8>::perform_test_speed (ret_val);
+ TestHelperFixLen <10>::perform_test_speed (ret_val);
+ TestHelperFixLen <12>::perform_test_speed (ret_val);
+ TestHelperFixLen <14>::perform_test_speed (ret_val);
+ TestHelperFixLen <16>::perform_test_speed (ret_val);
+ TestHelperFixLen <20>::perform_test_speed (ret_val);
+
+#endif
+
+ return (ret_val);
+}
+
+
+
+#if defined (_MSC_VER)
+static int __cdecl TEST_new_handler_cb (size_t dummy)
+{
+ throw std::bad_alloc ();
+ return (0);
+}
+#endif // _MSC_VER
+
+
+
+#if defined (_MSC_VER) && ! defined (NDEBUG)
+static int __cdecl TEST_debug_alloc_hook_cb (int alloc_type, void *user_data_ptr, size_t size, int block_type, long request_nbr, const unsigned char *filename_0, int line_nbr)
+{
+ if (block_type != _CRT_BLOCK) // Ignore CRT blocks to prevent infinite recursion
+ {
+ switch (alloc_type)
+ {
+ case _HOOK_ALLOC:
+ case _HOOK_REALLOC:
+ case _HOOK_FREE:
+
+ // Put some debug code here
+
+ break;
+
+ default:
+ assert (false); // Undefined allocation type
+ break;
+ }
+ }
+
+ return (1);
+}
+#endif
+
+
+
+#if defined (_MSC_VER) && ! defined (NDEBUG)
+static int __cdecl TEST_debug_report_hook_cb (int report_type, char *user_msg_0, int *ret_val_ptr)
+{
+ *ret_val_ptr = 0; // 1 to override the CRT default reporting mode
+
+ switch (report_type)
+ {
+ case _CRT_WARN:
+ case _CRT_ERROR:
+ case _CRT_ASSERT:
+
+// Put some debug code here
+
+ break;
+ }
+
+ return (*ret_val_ptr);
+}
+#endif
+
+
+
+static void TEST_prog_init ()
+{
+#if defined (_MSC_VER)
+ ::_set_new_handler (::TEST_new_handler_cb);
+#endif // _MSC_VER
+
+#if defined (_MSC_VER) && ! defined (NDEBUG)
+ {
+ const int mode = (1 * _CRTDBG_MODE_DEBUG)
+ | (1 * _CRTDBG_MODE_WNDW);
+ ::_CrtSetReportMode (_CRT_WARN, mode);
+ ::_CrtSetReportMode (_CRT_ERROR, mode);
+ ::_CrtSetReportMode (_CRT_ASSERT, mode);
+
+ const int old_flags = ::_CrtSetDbgFlag (_CRTDBG_REPORT_FLAG);
+ ::_CrtSetDbgFlag ( old_flags
+ | (1 * _CRTDBG_LEAK_CHECK_DF)
+ | (1 * _CRTDBG_CHECK_ALWAYS_DF));
+ ::_CrtSetBreakAlloc (-1); // Specify here a memory bloc number
+ ::_CrtSetAllocHook (TEST_debug_alloc_hook_cb);
+ ::_CrtSetReportHook (TEST_debug_report_hook_cb);
+
+ // Speed up I/O but breaks C stdio compatibility
+// std::cout.sync_with_stdio (false);
+// std::cin.sync_with_stdio (false);
+// std::cerr.sync_with_stdio (false);
+// std::clog.sync_with_stdio (false);
+ }
+#endif // _MSC_VER, NDEBUG
+}
+
+
+
+static void TEST_prog_end ()
+{
+#if defined (_MSC_VER) && ! defined (NDEBUG)
+ {
+ const int mode = (1 * _CRTDBG_MODE_DEBUG)
+ | (0 * _CRTDBG_MODE_WNDW);
+ ::_CrtSetReportMode (_CRT_WARN, mode);
+ ::_CrtSetReportMode (_CRT_ERROR, mode);
+ ::_CrtSetReportMode (_CRT_ASSERT, mode);
+
+ ::_CrtMemState mem_state;
+ ::_CrtMemCheckpoint (&mem_state);
+ ::_CrtMemDumpStatistics (&mem_state);
+ }
+#endif // _MSC_VER, NDEBUG
+}
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/test_fnc.h b/examples/multimedia/spectrum/3rdparty/fftreal/test_fnc.h
new file mode 100644
index 000000000..262215664
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/test_fnc.h
@@ -0,0 +1,53 @@
+/*****************************************************************************
+
+ test_fnc.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (test_fnc_HEADER_INCLUDED)
+#define test_fnc_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class T>
+inline T limit (const T &x, const T &inf, const T &sup);
+
+
+
+#include "test_fnc.hpp"
+
+
+
+#endif // test_fnc_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/test_fnc.hpp b/examples/multimedia/spectrum/3rdparty/fftreal/test_fnc.hpp
new file mode 100644
index 000000000..4b5f9f59e
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/test_fnc.hpp
@@ -0,0 +1,56 @@
+/*****************************************************************************
+
+ test_fnc.hpp
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if defined (test_fnc_CURRENT_CODEHEADER)
+ #error Recursive inclusion of test_fnc code header.
+#endif
+#define test_fnc_CURRENT_CODEHEADER
+
+#if ! defined (test_fnc_CODEHEADER_INCLUDED)
+#define test_fnc_CODEHEADER_INCLUDED
+
+
+
+/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
+
+
+
+template <class T>
+T limit (const T &x, const T &inf, const T &sup)
+{
+ assert (! (sup < inf));
+
+ return ((x < inf) ? inf : ((sup < x) ? sup : x));
+}
+
+
+
+#endif // test_fnc_CODEHEADER_INCLUDED
+
+#undef test_fnc_CURRENT_CODEHEADER
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/test_settings.h b/examples/multimedia/spectrum/3rdparty/fftreal/test_settings.h
new file mode 100644
index 000000000..b893afc8d
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/test_settings.h
@@ -0,0 +1,45 @@
+/*****************************************************************************
+
+ test_settings.h
+ Copyright (c) 2005 Laurent de Soras
+
+--- Legal stuff ---
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*Tab=3***********************************************************************/
+
+
+
+#if ! defined (test_settings_HEADER_INCLUDED)
+#define test_settings_HEADER_INCLUDED
+
+#if defined (_MSC_VER)
+ #pragma once
+ #pragma warning (4 : 4250) // "Inherits via dominance."
+#endif
+
+
+
+// #undef this label to avoid speed test compilation.
+#define test_settings_SPEED_TEST_ENABLED
+
+
+
+#endif // test_settings_HEADER_INCLUDED
+
+
+
+/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
diff --git a/examples/multimedia/spectrum/3rdparty/fftreal/testapp.dpr b/examples/multimedia/spectrum/3rdparty/fftreal/testapp.dpr
new file mode 100644
index 000000000..54f2eb99a
--- /dev/null
+++ b/examples/multimedia/spectrum/3rdparty/fftreal/testapp.dpr
@@ -0,0 +1,150 @@
+program testapp;
+{$APPTYPE CONSOLE}
+uses
+ SysUtils,
+ fftreal in 'fftreal.pas',
+ Math,
+ Windows;
+
+var
+ nbr_points : longint;
+ x, f : pflt_array;
+ fft : TFFTReal;
+ i : longint;
+ PI : double;
+ areal, img : double;
+ f_abs : double;
+ buffer_size : longint;
+ nbr_tests : longint;
+ time0, time1, time2 : int64;
+ timereso : int64;
+ offset : longint;
+ t0, t1 : double;
+ nbr_s_chn : longint;
+ tempp1, tempp2 : pflt_array;
+
+begin
+ (*______________________________________________
+ *
+ * Exactness test
+ *______________________________________________
+ *)
+
+ WriteLn('Accuracy test:');
+ WriteLn;
+
+ nbr_points := 16; // Power of 2
+ GetMem(x, nbr_points * sizeof_flt);
+ GetMem(f, nbr_points * sizeof_flt);
+ fft := TFFTReal.Create(nbr_points); // FFT object initialized here
+
+ // Test signal
+ PI := ArcTan(1) * 4;
+ for i := 0 to nbr_points-1 do
+ begin
+ x^[i] := -1 + sin (3*2*PI*i/nbr_points)
+ + cos (5*2*PI*i/nbr_points) * 2
+ - sin (7*2*PI*i/nbr_points) * 3
+ + cos (8*2*PI*i/nbr_points) * 5;
+ end;
+
+ // Compute FFT and IFFT
+ fft.do_fft(f, x);
+ fft.do_ifft(f, x);
+ fft.rescale(x);
+
+ // Display the result
+ WriteLn('FFT:');
+ for i := 0 to nbr_points div 2 do
+ begin
+ areal := f^[i];
+ if (i > 0) and (i < nbr_points div 2) then
+ img := f^[i + nbr_points div 2]
+ else
+ img := 0;
+
+ f_abs := Sqrt(areal * areal + img * img);
+ WriteLn(Format('%5d: %12.6f %12.6f (%12.6f)', [i, areal, img, f_abs]));
+ end;
+
+ WriteLn;
+ WriteLn('IFFT:');
+ for i := 0 to nbr_points-1 do
+ WriteLn(Format('%5d: %f', [i, x^[i]]));
+
+ WriteLn;
+
+ FreeMem(x);
+ FreeMem(f);
+ fft.Free;
+
+
+ (*______________________________________________
+ *
+ * Speed test
+ *______________________________________________
+ *)
+
+ WriteLn('Speed test:');
+ WriteLn('Please wait...');
+ WriteLn;
+
+ nbr_points := 1024; // Power of 2
+ buffer_size := 256*nbr_points; // Number of flt_t (float or double)
+ nbr_tests := 10000;
+
+ assert(nbr_points <= buffer_size);
+ GetMem(x, buffer_size * sizeof_flt);
+ GetMem(f, buffer_size * sizeof_flt);
+ fft := TFFTReal.Create(nbr_points); // FFT object initialized here
+
+ // Test signal: noise
+ for i := 0 to nbr_points-1 do
+ x^[i] := Random($7fff) - ($7fff shr 1);
+
+ // timing
+ QueryPerformanceFrequency(timereso);
+ QueryPerformanceCounter(time0);
+
+ for i := 0 to nbr_tests-1 do
+ begin
+ offset := (i * nbr_points) and (buffer_size - 1);
+ tempp1 := f;
+ inc(tempp1, offset);
+ tempp2 := x;
+ inc(tempp2, offset);
+ fft.do_fft(tempp1, tempp2);
+ end;
+
+ QueryPerformanceCounter(time1);
+
+ for i := 0 to nbr_tests-1 do
+ begin
+ offset := (i * nbr_points) and (buffer_size - 1);
+ tempp1 := f;
+ inc(tempp1, offset);
+ tempp2 := x;
+ inc(tempp2, offset);
+ fft.do_ifft(tempp1, tempp2);
+ fft.rescale(x);
+ end;
+
+ QueryPerformanceCounter(time2);
+
+ t0 := ((time1-time0) / timereso) / nbr_tests;
+ t1 := ((time2-time1) / timereso) / nbr_tests;
+
+ WriteLn(Format('%d-points FFT : %.0f us.', [nbr_points, t0 * 1000000]));
+ WriteLn(Format('%d-points IFFT + scaling: %.0f us.', [nbr_points, t1 * 1000000]));
+
+ nbr_s_chn := Floor(nbr_points / ((t0 + t1) * 44100 * 2));
+ WriteLn(Format('Peak performance: FFT+IFFT on %d mono channels at 44.1 KHz (with overlapping)', [nbr_s_chn]));
+ WriteLn;
+
+ FreeMem(x);
+ FreeMem(f);
+ fft.Free;
+
+ WriteLn('Press [Return] key to terminate...');
+ ReadLn;
+end.
diff --git a/examples/multimedia/spectrum/README.txt b/examples/multimedia/spectrum/README.txt
new file mode 100644
index 000000000..c39d4a709
--- /dev/null
+++ b/examples/multimedia/spectrum/README.txt
@@ -0,0 +1,103 @@
+Spectrum analyser demo app
+==========================
+
+Introduction
+------------
+
+This application is a demo which uses the QtMultimedia APIs to capture and play back PCM audio. While either recording or playback is ongoing, the application performs real-time level and frequency spectrum analysis, displaying the results in its main window.
+
+
+Acknowledgments
+---------------
+
+The application uses the FFTReal v2.00 library by Laurent de Soras to perform frequency analysis of the audio signal. For further information, see the project home page:
+ http://ldesoras.free.fr/prod.html
+
+
+Quick start
+-----------
+
+Play generated tone
+1. Select 'Play generated tone' from the mode menu
+2. Ensure that the 'Frequency sweep' box is checked
+3. Press 'OK'
+4. Press the play button
+You should hear a rising tone, and see progressively higher frequencies indicated by the spectrograph.
+
+Record and playback
+1. Select 'Record and play back audio' from the mode menu
+2. Press the record button, and speak into the microphone
+3. Wait until the buffer is full (shown as a full blue bar in the top widget)
+4. Press play, and wait until playback of the buffer is complete
+
+Play file
+1. Select 'Play file' from the mode menu
+2. Select a WAV file
+3. Press the play button
+You should hear the first few seconds of the file being played. The waveform, spectrograph and level meter should be updated as the file is played.
+
+
+Things to play with
+-------------------
+
+Try repeating the 'Play generated tone' sequence using different window functions. These can be selected from the settings dialog - launch it by pressing the spanner icon. The window function is applied to the audio signal before performing the frequency analysis; different windows should have a visible effect on the resulting frequency spectrum.
+
+Try clicking on one of the spectrograph bars while the tone is being played. The frequency range for that bar will be displayed at the top of the application window.
+
+
+Troubleshooting
+---------------
+
+If either recording or playback do not work, you may need to select a different input / output audio device. This can be done in the settings dialog - launch it by pressing the spanner icon.
+
+If that doesn't work, there may be a problem either in the application or in Qt. Report a bug in the usual way.
+
+
+Application interface
+---------------------
+
+The main window of the application contains the following widgets, starting at the top:
+
+Message box
+This shows various messages during execution, such as the current audio format.
+
+Progress bar / waveform display
+- While recording or playback is ongoing, the audio waveform is displayed, sliding from right to left.
+- Superimposed on the waveform, the amount of data currently in the buffer is showed as a blue bar. When recording, this blue bar fills up from left to right; when playing, the bar gets consumed from left to right.
+- A green window shows which part of the buffer has most recently been analysed. This window should be close to the 'leading edge' of recording or playback, i.e. the most recently recorded / played data, although it will lag slightly depending on the performance of the machine on which the application is running.
+
+Frequency spectrograph (on the left)
+The spectrograph shows 10 bars, each representing a frequency range. The frequency range of each bar is displayed in the message box when the bar is clicked. The height of the bar shows the maximum amplitude of freqencies within its range.
+
+Level meter (on the right)
+The current peak audio level is shown as a pink bar; the current RMS level is shown as a red bar. The 'high water mark' during a recent period is shown as a thin red line.
+
+Button panel
+- The mode menu allows switching between the three operation modes - 'Play generated tone', 'Record and play back' and 'Play file'.
+- The record button starts or resumes audio capture from the current input device.
+- The pause button suspends either capture or recording.
+- The play button starts or resumes audio playback to the current output device.
+- The settings button launches the settings dialog.
+
+
+Hacking
+-------
+
+If you want to hack the application, here are some pointers to get started.
+
+The spectrum.pri file contains several macros which you can enable by uncommenting:
+- LOG_FOO Enable logging from class Foo via qDebug()
+- DUMP_FOO Dump data from class Foo to the file system
+ e.g. DUMP_SPECTRUMANALYSER writes files containing the raw FFT input and output.
+ Be aware that this can generate a *lot* of data and may slow the app down considerably.
+- DISABLE_FOO Disable specified functionality
+
+If you don't like the combination of the waveform and progress bar in a single widget, separate them by commenting out SUPERIMPOSE_PROGRESS_ON_WAVEFORM.
+
+The spectrum.h file defines a number of parameters which can be played with. These control things such as the number of audio samples analysed per FFT calculation, the range and number of bands displayed by the spectrograph, and so on.
+
+The part of the application which interacts with QtMultimedia is in the Engine class.
+
+Some ideas for enhancements to the app are listed in TODO.txt. Feel free to start work on any of them :)
+
+
diff --git a/examples/multimedia/spectrum/TODO.txt b/examples/multimedia/spectrum/TODO.txt
new file mode 100644
index 000000000..7e5881abf
--- /dev/null
+++ b/examples/multimedia/spectrum/TODO.txt
@@ -0,0 +1,34 @@
+TODO list for spectrum analyser
+===============================
+
+Bug fixes
+---------
+
+
+New features
+------------
+
+* Wrap user-visible strings in tr()
+
+* Allow user to set frequency range
+There should be some constraints on this, e.g.
+ - Maximum frequency must not be greater than Nyquist frequency
+ - Range is divisible by number of bars?
+
+* Add more visualizers other than bar spectrogram
+e.g. Funky OpenGL visualizers, particle effects etc
+
+
+Non-functional stuff
+--------------------
+
+* Improve robustness of QComboBox -> enum mapping
+At the moment, SettingsDialog relies on casting the combobox item index directly to the enumerated type. This is clearly a bit fragile...
+
+* For functions which take or return qint64 values, make a clear distinction between duration (microseconds) and length (bytes).
+A sensible convention would be that the default is bytes - i.e. microseconds must be indicated by adding a Us suffix, where not already obvious from the function name.
+
+
+
+
+
diff --git a/examples/multimedia/spectrum/app/.gitignore b/examples/multimedia/spectrum/app/.gitignore
new file mode 100644
index 000000000..82cf2a28f
--- /dev/null
+++ b/examples/multimedia/spectrum/app/.gitignore
@@ -0,0 +1,2 @@
+spectrum
+spectrum.exe
diff --git a/examples/multimedia/spectrum/app/app.pro b/examples/multimedia/spectrum/app/app.pro
new file mode 100644
index 000000000..581848a7f
--- /dev/null
+++ b/examples/multimedia/spectrum/app/app.pro
@@ -0,0 +1,85 @@
+include(../spectrum.pri)
+
+static: error(This application cannot be statically linked to the fftreal library)
+
+TEMPLATE = app
+
+TARGET = spectrum
+
+QT += multimedia widgets
+
+SOURCES += main.cpp \
+ engine.cpp \
+ frequencyspectrum.cpp \
+ levelmeter.cpp \
+ mainwidget.cpp \
+ progressbar.cpp \
+ settingsdialog.cpp \
+ spectrograph.cpp \
+ spectrumanalyser.cpp \
+ tonegenerator.cpp \
+ tonegeneratordialog.cpp \
+ utils.cpp \
+ waveform.cpp \
+ wavfile.cpp
+
+HEADERS += engine.h \
+ frequencyspectrum.h \
+ levelmeter.h \
+ mainwidget.h \
+ progressbar.h \
+ settingsdialog.h \
+ spectrograph.h \
+ spectrum.h \
+ spectrumanalyser.h \
+ tonegenerator.h \
+ tonegeneratordialog.h \
+ utils.h \
+ waveform.h \
+ wavfile.h
+
+fftreal_dir = ../3rdparty/fftreal
+
+INCLUDEPATH += $${fftreal_dir}
+
+RESOURCES = spectrum.qrc
+
+# Dynamic linkage against FFTReal DLL
+!contains(DEFINES, DISABLE_FFT) {
+ macx {
+ # Link to fftreal framework
+ LIBS += -F$${fftreal_dir}
+ LIBS += -framework fftreal
+ } else {
+ LIBS += -L..$${spectrum_build_dir}
+ LIBS += -lfftreal
+ }
+}
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/spectrum
+INSTALLS += target
+
+# Deployment
+
+DESTDIR = ..$${spectrum_build_dir}
+macx {
+ !contains(DEFINES, DISABLE_FFT) {
+ # Relocate fftreal.framework into spectrum.app bundle
+ framework_dir = ../spectrum.app/Contents/Frameworks
+ framework_name = fftreal.framework/Versions/1/fftreal
+ QMAKE_POST_LINK = \
+ mkdir -p $${framework_dir} &&\
+ rm -rf $${framework_dir}/fftreal.framework &&\
+ cp -R $${fftreal_dir}/fftreal.framework $${framework_dir} &&\
+ install_name_tool -id @executable_path/../Frameworks/$${framework_name} \
+ $${framework_dir}/$${framework_name} &&\
+ install_name_tool -change $${framework_name} \
+ @executable_path/../Frameworks/$${framework_name} \
+ ../spectrum.app/Contents/MacOS/spectrum
+ }
+} else {
+ linux-g++*: {
+ # Provide relative path from application to fftreal library
+ QMAKE_LFLAGS += -Wl,--rpath=\\\$\$ORIGIN
+ }
+}
diff --git a/examples/multimedia/spectrum/app/engine.cpp b/examples/multimedia/spectrum/app/engine.cpp
new file mode 100644
index 000000000..908cb9df6
--- /dev/null
+++ b/examples/multimedia/spectrum/app/engine.cpp
@@ -0,0 +1,754 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "engine.h"
+#include "tonegenerator.h"
+#include "utils.h"
+
+#include <math.h>
+
+#include <QAudioInput>
+#include <QAudioOutput>
+#include <QCoreApplication>
+#include <QDebug>
+#include <QFile>
+#include <QMetaObject>
+#include <QSet>
+#include <QThread>
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+const qint64 BufferDurationUs = 10 * 1000000;
+const int NotifyIntervalMs = 100;
+
+// Size of the level calculation window in microseconds
+const int LevelWindowUs = 0.1 * 1000000;
+
+//-----------------------------------------------------------------------------
+// Constructor and destructor
+//-----------------------------------------------------------------------------
+
+Engine::Engine(QObject *parent)
+ : QObject(parent)
+ , m_mode(QAudio::AudioInput)
+ , m_state(QAudio::StoppedState)
+ , m_generateTone(false)
+ , m_file(0)
+ , m_analysisFile(0)
+ , m_availableAudioInputDevices
+ (QAudioDeviceInfo::availableDevices(QAudio::AudioInput))
+ , m_audioInputDevice(QAudioDeviceInfo::defaultInputDevice())
+ , m_audioInput(0)
+ , m_audioInputIODevice(0)
+ , m_recordPosition(0)
+ , m_availableAudioOutputDevices
+ (QAudioDeviceInfo::availableDevices(QAudio::AudioOutput))
+ , m_audioOutputDevice(QAudioDeviceInfo::defaultOutputDevice())
+ , m_audioOutput(0)
+ , m_playPosition(0)
+ , m_bufferPosition(0)
+ , m_bufferLength(0)
+ , m_dataLength(0)
+ , m_levelBufferLength(0)
+ , m_rmsLevel(0.0)
+ , m_peakLevel(0.0)
+ , m_spectrumBufferLength(0)
+ , m_spectrumAnalyser()
+ , m_spectrumPosition(0)
+ , m_count(0)
+{
+ qRegisterMetaType<FrequencySpectrum>("FrequencySpectrum");
+ qRegisterMetaType<WindowFunction>("WindowFunction");
+ CHECKED_CONNECT(&m_spectrumAnalyser,
+ SIGNAL(spectrumChanged(FrequencySpectrum)),
+ this,
+ SLOT(spectrumChanged(FrequencySpectrum)));
+
+ initialize();
+
+#ifdef DUMP_DATA
+ createOutputDir();
+#endif
+
+#ifdef DUMP_SPECTRUM
+ m_spectrumAnalyser.setOutputPath(outputPath());
+#endif
+}
+
+Engine::~Engine()
+{
+
+}
+
+//-----------------------------------------------------------------------------
+// Public functions
+//-----------------------------------------------------------------------------
+
+bool Engine::loadFile(const QString &fileName)
+{
+ reset();
+ bool result = false;
+ Q_ASSERT(!m_generateTone);
+ Q_ASSERT(!m_file);
+ Q_ASSERT(!fileName.isEmpty());
+ m_file = new WavFile(this);
+ if (m_file->open(fileName)) {
+ if (isPCMS16LE(m_file->fileFormat())) {
+ result = initialize();
+ } else {
+ emit errorMessage(tr("Audio format not supported"),
+ formatToString(m_file->fileFormat()));
+ }
+ } else {
+ emit errorMessage(tr("Could not open file"), fileName);
+ }
+ if (result) {
+ m_analysisFile = new WavFile(this);
+ m_analysisFile->open(fileName);
+ }
+ return result;
+}
+
+bool Engine::generateTone(const Tone &tone)
+{
+ reset();
+ Q_ASSERT(!m_generateTone);
+ Q_ASSERT(!m_file);
+ m_generateTone = true;
+ m_tone = tone;
+ ENGINE_DEBUG << "Engine::generateTone"
+ << "startFreq" << m_tone.startFreq
+ << "endFreq" << m_tone.endFreq
+ << "amp" << m_tone.amplitude;
+ return initialize();
+}
+
+bool Engine::generateSweptTone(qreal amplitude)
+{
+ Q_ASSERT(!m_generateTone);
+ Q_ASSERT(!m_file);
+ m_generateTone = true;
+ m_tone.startFreq = 1;
+ m_tone.endFreq = 0;
+ m_tone.amplitude = amplitude;
+ ENGINE_DEBUG << "Engine::generateSweptTone"
+ << "startFreq" << m_tone.startFreq
+ << "amp" << m_tone.amplitude;
+ return initialize();
+}
+
+bool Engine::initializeRecord()
+{
+ reset();
+ ENGINE_DEBUG << "Engine::initializeRecord";
+ Q_ASSERT(!m_generateTone);
+ Q_ASSERT(!m_file);
+ m_generateTone = false;
+ m_tone = SweptTone();
+ return initialize();
+}
+
+qint64 Engine::bufferLength() const
+{
+ return m_file ? m_file->size() : m_bufferLength;
+}
+
+void Engine::setWindowFunction(WindowFunction type)
+{
+ m_spectrumAnalyser.setWindowFunction(type);
+}
+
+
+//-----------------------------------------------------------------------------
+// Public slots
+//-----------------------------------------------------------------------------
+
+void Engine::startRecording()
+{
+ if (m_audioInput) {
+ if (QAudio::AudioInput == m_mode &&
+ QAudio::SuspendedState == m_state) {
+ m_audioInput->resume();
+ } else {
+ m_spectrumAnalyser.cancelCalculation();
+ spectrumChanged(0, 0, FrequencySpectrum());
+
+ m_buffer.fill(0);
+ setRecordPosition(0, true);
+ stopPlayback();
+ m_mode = QAudio::AudioInput;
+ CHECKED_CONNECT(m_audioInput, SIGNAL(stateChanged(QAudio::State)),
+ this, SLOT(audioStateChanged(QAudio::State)));
+ CHECKED_CONNECT(m_audioInput, SIGNAL(notify()),
+ this, SLOT(audioNotify()));
+ m_count = 0;
+ m_dataLength = 0;
+ emit dataLengthChanged(0);
+ m_audioInputIODevice = m_audioInput->start();
+ CHECKED_CONNECT(m_audioInputIODevice, SIGNAL(readyRead()),
+ this, SLOT(audioDataReady()));
+ }
+ }
+}
+
+void Engine::startPlayback()
+{
+ if (m_audioOutput) {
+ if (QAudio::AudioOutput == m_mode &&
+ QAudio::SuspendedState == m_state) {
+#ifdef Q_OS_WIN
+ // The Windows backend seems to internally go back into ActiveState
+ // while still returning SuspendedState, so to ensure that it doesn't
+ // ignore the resume() call, we first re-suspend
+ m_audioOutput->suspend();
+#endif
+ m_audioOutput->resume();
+ } else {
+ m_spectrumAnalyser.cancelCalculation();
+ spectrumChanged(0, 0, FrequencySpectrum());
+ setPlayPosition(0, true);
+ stopRecording();
+ m_mode = QAudio::AudioOutput;
+ CHECKED_CONNECT(m_audioOutput, SIGNAL(stateChanged(QAudio::State)),
+ this, SLOT(audioStateChanged(QAudio::State)));
+ CHECKED_CONNECT(m_audioOutput, SIGNAL(notify()),
+ this, SLOT(audioNotify()));
+ m_count = 0;
+ if (m_file) {
+ m_file->seek(0);
+ m_bufferPosition = 0;
+ m_dataLength = 0;
+ m_audioOutput->start(m_file);
+ } else {
+ m_audioOutputIODevice.close();
+ m_audioOutputIODevice.setBuffer(&m_buffer);
+ m_audioOutputIODevice.open(QIODevice::ReadOnly);
+ m_audioOutput->start(&m_audioOutputIODevice);
+ }
+ }
+ }
+}
+
+void Engine::suspend()
+{
+ if (QAudio::ActiveState == m_state ||
+ QAudio::IdleState == m_state) {
+ switch (m_mode) {
+ case QAudio::AudioInput:
+ m_audioInput->suspend();
+ break;
+ case QAudio::AudioOutput:
+ m_audioOutput->suspend();
+ break;
+ }
+ }
+}
+
+void Engine::setAudioInputDevice(const QAudioDeviceInfo &device)
+{
+ if (device.deviceName() != m_audioInputDevice.deviceName()) {
+ m_audioInputDevice = device;
+ initialize();
+ }
+}
+
+void Engine::setAudioOutputDevice(const QAudioDeviceInfo &device)
+{
+ if (device.deviceName() != m_audioOutputDevice.deviceName()) {
+ m_audioOutputDevice = device;
+ initialize();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Private slots
+//-----------------------------------------------------------------------------
+
+void Engine::audioNotify()
+{
+ switch (m_mode) {
+ case QAudio::AudioInput: {
+ const qint64 recordPosition = qMin(m_bufferLength, audioLength(m_format, m_audioInput->processedUSecs()));
+ setRecordPosition(recordPosition);
+ const qint64 levelPosition = m_dataLength - m_levelBufferLength;
+ if (levelPosition >= 0)
+ calculateLevel(levelPosition, m_levelBufferLength);
+ if (m_dataLength >= m_spectrumBufferLength) {
+ const qint64 spectrumPosition = m_dataLength - m_spectrumBufferLength;
+ calculateSpectrum(spectrumPosition);
+ }
+ emit bufferChanged(0, m_dataLength, m_buffer);
+ }
+ break;
+ case QAudio::AudioOutput: {
+ const qint64 playPosition = audioLength(m_format, m_audioOutput->processedUSecs());
+ setPlayPosition(qMin(bufferLength(), playPosition));
+ const qint64 levelPosition = playPosition - m_levelBufferLength;
+ const qint64 spectrumPosition = playPosition - m_spectrumBufferLength;
+ if (m_file) {
+ if (levelPosition > m_bufferPosition ||
+ spectrumPosition > m_bufferPosition ||
+ qMax(m_levelBufferLength, m_spectrumBufferLength) > m_dataLength) {
+ m_bufferPosition = 0;
+ m_dataLength = 0;
+ // Data needs to be read into m_buffer in order to be analysed
+ const qint64 readPos = qMax(qint64(0), qMin(levelPosition, spectrumPosition));
+ const qint64 readEnd = qMin(m_analysisFile->size(), qMax(levelPosition + m_levelBufferLength, spectrumPosition + m_spectrumBufferLength));
+ const qint64 readLen = readEnd - readPos + audioLength(m_format, WaveformWindowDuration);
+ qDebug() << "Engine::audioNotify [1]"
+ << "analysisFileSize" << m_analysisFile->size()
+ << "readPos" << readPos
+ << "readLen" << readLen;
+ if (m_analysisFile->seek(readPos + m_analysisFile->headerLength())) {
+ m_buffer.resize(readLen);
+ m_bufferPosition = readPos;
+ m_dataLength = m_analysisFile->read(m_buffer.data(), readLen);
+ qDebug() << "Engine::audioNotify [2]" << "bufferPosition" << m_bufferPosition << "dataLength" << m_dataLength;
+ } else {
+ qDebug() << "Engine::audioNotify [2]" << "file seek error";
+ }
+ emit bufferChanged(m_bufferPosition, m_dataLength, m_buffer);
+ }
+ } else {
+ if (playPosition >= m_dataLength)
+ stopPlayback();
+ }
+ if (levelPosition >= 0 && levelPosition + m_levelBufferLength < m_bufferPosition + m_dataLength)
+ calculateLevel(levelPosition, m_levelBufferLength);
+ if (spectrumPosition >= 0 && spectrumPosition + m_spectrumBufferLength < m_bufferPosition + m_dataLength)
+ calculateSpectrum(spectrumPosition);
+ }
+ break;
+ }
+}
+
+void Engine::audioStateChanged(QAudio::State state)
+{
+ ENGINE_DEBUG << "Engine::audioStateChanged from" << m_state
+ << "to" << state;
+
+ if (QAudio::IdleState == state && m_file && m_file->pos() == m_file->size()) {
+ stopPlayback();
+ } else {
+ if (QAudio::StoppedState == state) {
+ // Check error
+ QAudio::Error error = QAudio::NoError;
+ switch (m_mode) {
+ case QAudio::AudioInput:
+ error = m_audioInput->error();
+ break;
+ case QAudio::AudioOutput:
+ error = m_audioOutput->error();
+ break;
+ }
+ if (QAudio::NoError != error) {
+ reset();
+ return;
+ }
+ }
+ setState(state);
+ }
+}
+
+void Engine::audioDataReady()
+{
+ Q_ASSERT(0 == m_bufferPosition);
+ const qint64 bytesReady = m_audioInput->bytesReady();
+ const qint64 bytesSpace = m_buffer.size() - m_dataLength;
+ const qint64 bytesToRead = qMin(bytesReady, bytesSpace);
+
+ const qint64 bytesRead = m_audioInputIODevice->read(
+ m_buffer.data() + m_dataLength,
+ bytesToRead);
+
+ if (bytesRead) {
+ m_dataLength += bytesRead;
+ emit dataLengthChanged(dataLength());
+ }
+
+ if (m_buffer.size() == m_dataLength)
+ stopRecording();
+}
+
+void Engine::spectrumChanged(const FrequencySpectrum &spectrum)
+{
+ ENGINE_DEBUG << "Engine::spectrumChanged" << "pos" << m_spectrumPosition;
+ emit spectrumChanged(m_spectrumPosition, m_spectrumBufferLength, spectrum);
+}
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void Engine::resetAudioDevices()
+{
+ delete m_audioInput;
+ m_audioInput = 0;
+ m_audioInputIODevice = 0;
+ setRecordPosition(0);
+ delete m_audioOutput;
+ m_audioOutput = 0;
+ setPlayPosition(0);
+ m_spectrumPosition = 0;
+ setLevel(0.0, 0.0, 0);
+}
+
+void Engine::reset()
+{
+ stopRecording();
+ stopPlayback();
+ setState(QAudio::AudioInput, QAudio::StoppedState);
+ setFormat(QAudioFormat());
+ m_generateTone = false;
+ delete m_file;
+ m_file = 0;
+ delete m_analysisFile;
+ m_analysisFile = 0;
+ m_buffer.clear();
+ m_bufferPosition = 0;
+ m_bufferLength = 0;
+ m_dataLength = 0;
+ emit dataLengthChanged(0);
+ resetAudioDevices();
+}
+
+bool Engine::initialize()
+{
+ bool result = false;
+
+ QAudioFormat format = m_format;
+
+ if (selectFormat()) {
+ if (m_format != format) {
+ resetAudioDevices();
+ if (m_file) {
+ emit bufferLengthChanged(bufferLength());
+ emit dataLengthChanged(dataLength());
+ emit bufferChanged(0, 0, m_buffer);
+ setRecordPosition(bufferLength());
+ result = true;
+ } else {
+ m_bufferLength = audioLength(m_format, BufferDurationUs);
+ m_buffer.resize(m_bufferLength);
+ m_buffer.fill(0);
+ emit bufferLengthChanged(bufferLength());
+ if (m_generateTone) {
+ if (0 == m_tone.endFreq) {
+ const qreal nyquist = nyquistFrequency(m_format);
+ m_tone.endFreq = qMin(qreal(SpectrumHighFreq), nyquist);
+ }
+ // Call function defined in utils.h, at global scope
+ ::generateTone(m_tone, m_format, m_buffer);
+ m_dataLength = m_bufferLength;
+ emit dataLengthChanged(dataLength());
+ emit bufferChanged(0, m_dataLength, m_buffer);
+ setRecordPosition(m_bufferLength);
+ result = true;
+ } else {
+ emit bufferChanged(0, 0, m_buffer);
+ m_audioInput = new QAudioInput(m_audioInputDevice, m_format, this);
+ m_audioInput->setNotifyInterval(NotifyIntervalMs);
+ result = true;
+ }
+ }
+ m_audioOutput = new QAudioOutput(m_audioOutputDevice, m_format, this);
+ m_audioOutput->setNotifyInterval(NotifyIntervalMs);
+ }
+ } else {
+ if (m_file)
+ emit errorMessage(tr("Audio format not supported"),
+ formatToString(m_format));
+ else if (m_generateTone)
+ emit errorMessage(tr("No suitable format found"), "");
+ else
+ emit errorMessage(tr("No common input / output format found"), "");
+ }
+
+ ENGINE_DEBUG << "Engine::initialize" << "m_bufferLength" << m_bufferLength;
+ ENGINE_DEBUG << "Engine::initialize" << "m_dataLength" << m_dataLength;
+ ENGINE_DEBUG << "Engine::initialize" << "format" << m_format;
+
+ return result;
+}
+
+bool Engine::selectFormat()
+{
+ bool foundSupportedFormat = false;
+
+ if (m_file || QAudioFormat() != m_format) {
+ QAudioFormat format = m_format;
+ if (m_file)
+ // Header is read from the WAV file; just need to check whether
+ // it is supported by the audio output device
+ format = m_file->fileFormat();
+ if (m_audioOutputDevice.isFormatSupported(format)) {
+ setFormat(format);
+ foundSupportedFormat = true;
+ }
+ } else {
+
+ QList<int> sampleRatesList;
+ #ifdef Q_OS_WIN
+ // The Windows audio backend does not correctly report format support
+ // (see QTBUG-9100). Furthermore, although the audio subsystem captures
+ // at 11025Hz, the resulting audio is corrupted.
+ sampleRatesList += 8000;
+ #endif
+
+ if (!m_generateTone)
+ sampleRatesList += m_audioInputDevice.supportedSampleRates();
+
+ sampleRatesList += m_audioOutputDevice.supportedSampleRates();
+ sampleRatesList = sampleRatesList.toSet().toList(); // remove duplicates
+ qSort(sampleRatesList);
+ ENGINE_DEBUG << "Engine::initialize frequenciesList" << sampleRatesList;
+
+ QList<int> channelsList;
+ channelsList += m_audioInputDevice.supportedChannelCounts();
+ channelsList += m_audioOutputDevice.supportedChannelCounts();
+ channelsList = channelsList.toSet().toList();
+ qSort(channelsList);
+ ENGINE_DEBUG << "Engine::initialize channelsList" << channelsList;
+
+ QAudioFormat format;
+ format.setByteOrder(QAudioFormat::LittleEndian);
+ format.setCodec("audio/pcm");
+ format.setSampleSize(16);
+ format.setSampleType(QAudioFormat::SignedInt);
+ int sampleRate, channels;
+ foreach (sampleRate, sampleRatesList) {
+ if (foundSupportedFormat)
+ break;
+ format.setSampleRate(sampleRate);
+ foreach (channels, channelsList) {
+ format.setChannelCount(channels);
+ const bool inputSupport = m_generateTone ||
+ m_audioInputDevice.isFormatSupported(format);
+ const bool outputSupport = m_audioOutputDevice.isFormatSupported(format);
+ ENGINE_DEBUG << "Engine::initialize checking " << format
+ << "input" << inputSupport
+ << "output" << outputSupport;
+ if (inputSupport && outputSupport) {
+ foundSupportedFormat = true;
+ break;
+ }
+ }
+ }
+
+ if (!foundSupportedFormat)
+ format = QAudioFormat();
+
+ setFormat(format);
+ }
+
+ return foundSupportedFormat;
+}
+
+void Engine::stopRecording()
+{
+ if (m_audioInput) {
+ m_audioInput->stop();
+ QCoreApplication::instance()->processEvents();
+ m_audioInput->disconnect();
+ }
+ m_audioInputIODevice = 0;
+
+#ifdef DUMP_AUDIO
+ dumpData();
+#endif
+}
+
+void Engine::stopPlayback()
+{
+ if (m_audioOutput) {
+ m_audioOutput->stop();
+ QCoreApplication::instance()->processEvents();
+ m_audioOutput->disconnect();
+ setPlayPosition(0);
+ }
+}
+
+void Engine::setState(QAudio::State state)
+{
+ const bool changed = (m_state != state);
+ m_state = state;
+ if (changed)
+ emit stateChanged(m_mode, m_state);
+}
+
+void Engine::setState(QAudio::Mode mode, QAudio::State state)
+{
+ const bool changed = (m_mode != mode || m_state != state);
+ m_mode = mode;
+ m_state = state;
+ if (changed)
+ emit stateChanged(m_mode, m_state);
+}
+
+void Engine::setRecordPosition(qint64 position, bool forceEmit)
+{
+ const bool changed = (m_recordPosition != position);
+ m_recordPosition = position;
+ if (changed || forceEmit)
+ emit recordPositionChanged(m_recordPosition);
+}
+
+void Engine::setPlayPosition(qint64 position, bool forceEmit)
+{
+ const bool changed = (m_playPosition != position);
+ m_playPosition = position;
+ if (changed || forceEmit)
+ emit playPositionChanged(m_playPosition);
+}
+
+void Engine::calculateLevel(qint64 position, qint64 length)
+{
+#ifdef DISABLE_LEVEL
+ Q_UNUSED(position)
+ Q_UNUSED(length)
+#else
+ Q_ASSERT(position + length <= m_bufferPosition + m_dataLength);
+
+ qreal peakLevel = 0.0;
+
+ qreal sum = 0.0;
+ const char *ptr = m_buffer.constData() + position - m_bufferPosition;
+ const char *const end = ptr + length;
+ while (ptr < end) {
+ const qint16 value = *reinterpret_cast<const qint16*>(ptr);
+ const qreal fracValue = pcmToReal(value);
+ peakLevel = qMax(peakLevel, fracValue);
+ sum += fracValue * fracValue;
+ ptr += 2;
+ }
+ const int numSamples = length / 2;
+ qreal rmsLevel = sqrt(sum / numSamples);
+
+ rmsLevel = qMax(qreal(0.0), rmsLevel);
+ rmsLevel = qMin(qreal(1.0), rmsLevel);
+ setLevel(rmsLevel, peakLevel, numSamples);
+
+ ENGINE_DEBUG << "Engine::calculateLevel" << "pos" << position << "len" << length
+ << "rms" << rmsLevel << "peak" << peakLevel;
+#endif
+}
+
+void Engine::calculateSpectrum(qint64 position)
+{
+#ifdef DISABLE_SPECTRUM
+ Q_UNUSED(position)
+#else
+ Q_ASSERT(position + m_spectrumBufferLength <= m_bufferPosition + m_dataLength);
+ Q_ASSERT(0 == m_spectrumBufferLength % 2); // constraint of FFT algorithm
+
+ // QThread::currentThread is marked 'for internal use only', but
+ // we're only using it for debug output here, so it's probably OK :)
+ ENGINE_DEBUG << "Engine::calculateSpectrum" << QThread::currentThread()
+ << "count" << m_count << "pos" << position << "len" << m_spectrumBufferLength
+ << "spectrumAnalyser.isReady" << m_spectrumAnalyser.isReady();
+
+ if (m_spectrumAnalyser.isReady()) {
+ m_spectrumBuffer = QByteArray::fromRawData(m_buffer.constData() + position - m_bufferPosition,
+ m_spectrumBufferLength);
+ m_spectrumPosition = position;
+ m_spectrumAnalyser.calculate(m_spectrumBuffer, m_format);
+ }
+#endif
+}
+
+void Engine::setFormat(const QAudioFormat &format)
+{
+ const bool changed = (format != m_format);
+ m_format = format;
+ m_levelBufferLength = audioLength(m_format, LevelWindowUs);
+ m_spectrumBufferLength = SpectrumLengthSamples *
+ (m_format.sampleSize() / 8) * m_format.channelCount();
+ if (changed)
+ emit formatChanged(m_format);
+}
+
+void Engine::setLevel(qreal rmsLevel, qreal peakLevel, int numSamples)
+{
+ m_rmsLevel = rmsLevel;
+ m_peakLevel = peakLevel;
+ emit levelChanged(m_rmsLevel, m_peakLevel, numSamples);
+}
+
+#ifdef DUMP_DATA
+void Engine::createOutputDir()
+{
+ m_outputDir.setPath("output");
+
+ // Ensure output directory exists and is empty
+ if (m_outputDir.exists()) {
+ const QStringList files = m_outputDir.entryList(QDir::Files);
+ QString file;
+ foreach (file, files)
+ m_outputDir.remove(file);
+ } else {
+ QDir::current().mkdir("output");
+ }
+}
+#endif // DUMP_DATA
+
+#ifdef DUMP_AUDIO
+void Engine::dumpData()
+{
+ const QString txtFileName = m_outputDir.filePath("data.txt");
+ QFile txtFile(txtFileName);
+ txtFile.open(QFile::WriteOnly | QFile::Text);
+ QTextStream stream(&txtFile);
+ const qint16 *ptr = reinterpret_cast<const qint16*>(m_buffer.constData());
+ const int numSamples = m_dataLength / (2 * m_format.channels());
+ for (int i=0; i<numSamples; ++i) {
+ stream << i << "\t" << *ptr << "\n";
+ ptr += m_format.channels();
+ }
+
+ const QString pcmFileName = m_outputDir.filePath("data.pcm");
+ QFile pcmFile(pcmFileName);
+ pcmFile.open(QFile::WriteOnly);
+ pcmFile.write(m_buffer.constData(), m_dataLength);
+}
+#endif // DUMP_AUDIO
diff --git a/examples/multimedia/spectrum/app/engine.h b/examples/multimedia/spectrum/app/engine.h
new file mode 100644
index 000000000..f3ca5c97a
--- /dev/null
+++ b/examples/multimedia/spectrum/app/engine.h
@@ -0,0 +1,315 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 ENGINE_H
+#define ENGINE_H
+
+#include "spectrum.h"
+#include "spectrumanalyser.h"
+#include "wavfile.h"
+
+#include <QAudioDeviceInfo>
+#include <QAudioFormat>
+#include <QBuffer>
+#include <QByteArray>
+#include <QDir>
+#include <QObject>
+#include <QVector>
+
+#ifdef DUMP_CAPTURED_AUDIO
+#define DUMP_DATA
+#endif
+
+#ifdef DUMP_SPECTRUM
+#define DUMP_DATA
+#endif
+
+class FrequencySpectrum;
+QT_BEGIN_NAMESPACE
+class QAudioInput;
+class QAudioOutput;
+QT_END_NAMESPACE
+
+/**
+ * This class interfaces with the QtMultimedia audio classes, and also with
+ * the SpectrumAnalyser class. Its role is to manage the capture and playback
+ * of audio data, meanwhile performing real-time analysis of the audio level
+ * and frequency spectrum.
+ */
+class Engine : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit Engine(QObject *parent = 0);
+ ~Engine();
+
+ 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);
+
+ /**
+ * 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 suspend();
+ void setAudioInputDevice(const QAudioDeviceInfo &device);
+ void setAudioOutputDevice(const QAudioDeviceInfo &device);
+
+signals:
+ void stateChanged(QAudio::Mode mode, QAudio::State state);
+
+ /**
+ * Informational message for non-modal display
+ */
+ 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(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(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(qint64 position, qint64 length, const QByteArray &buffer);
+
+private slots:
+ void audioNotify();
+ void audioStateChanged(QAudio::State state);
+ void audioDataReady();
+ void spectrumChanged(const FrequencySpectrum &spectrum);
+
+private:
+ void resetAudioDevices();
+ bool initialize();
+ bool selectFormat();
+ void stopRecording();
+ void stopPlayback();
+ void setState(QAudio::State state);
+ void setState(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 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:
+ QAudio::Mode m_mode;
+ QAudio::State m_state;
+
+ bool m_generateTone;
+ SweptTone m_tone;
+
+ 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;
+
+#ifdef DUMP_DATA
+ QDir m_outputDir;
+#endif
+
+};
+
+#endif // ENGINE_H
diff --git a/examples/multimedia/spectrum/app/frequencyspectrum.cpp b/examples/multimedia/spectrum/app/frequencyspectrum.cpp
new file mode 100644
index 000000000..6a7fd1fab
--- /dev/null
+++ b/examples/multimedia/spectrum/app/frequencyspectrum.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "frequencyspectrum.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();
+}
diff --git a/examples/multimedia/spectrum/app/frequencyspectrum.h b/examples/multimedia/spectrum/app/frequencyspectrum.h
new file mode 100644
index 000000000..10843ab39
--- /dev/null
+++ b/examples/multimedia/spectrum/app/frequencyspectrum.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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
diff --git a/examples/multimedia/spectrum/app/images/record.png b/examples/multimedia/spectrum/app/images/record.png
new file mode 100644
index 000000000..e7493aad9
--- /dev/null
+++ b/examples/multimedia/spectrum/app/images/record.png
Binary files differ
diff --git a/examples/multimedia/spectrum/app/images/settings.png b/examples/multimedia/spectrum/app/images/settings.png
new file mode 100644
index 000000000..12179dc9a
--- /dev/null
+++ b/examples/multimedia/spectrum/app/images/settings.png
Binary files differ
diff --git a/examples/multimedia/spectrum/app/levelmeter.cpp b/examples/multimedia/spectrum/app/levelmeter.cpp
new file mode 100644
index 000000000..2fde9184a
--- /dev/null
+++ b/examples/multimedia/spectrum/app/levelmeter.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "levelmeter.h"
+
+#include <math.h>
+
+#include <QPainter>
+#include <QTimer>
+#include <QDebug>
+
+
+// Constants
+const int RedrawInterval = 100; // ms
+const qreal PeakDecayRate = 0.001;
+const int PeakHoldLevelDuration = 2000; // ms
+
+
+LevelMeter::LevelMeter(QWidget *parent)
+ : QWidget(parent)
+ , m_rmsLevel(0.0)
+ , m_peakLevel(0.0)
+ , m_decayedPeakLevel(0.0)
+ , m_peakDecayRate(PeakDecayRate)
+ , m_peakHoldLevel(0.0)
+ , m_redrawTimer(new QTimer(this))
+ , m_rmsColor(Qt::red)
+ , m_peakColor(255, 200, 200, 255)
+{
+ setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
+ setMinimumWidth(30);
+
+ connect(m_redrawTimer, SIGNAL(timeout()), this, SLOT(redrawTimerExpired()));
+ m_redrawTimer->start(RedrawInterval);
+}
+
+LevelMeter::~LevelMeter()
+{
+
+}
+
+void LevelMeter::reset()
+{
+ m_rmsLevel = 0.0;
+ m_peakLevel = 0.0;
+ update();
+}
+
+void LevelMeter::levelChanged(qreal rmsLevel, qreal peakLevel, int numSamples)
+{
+ // Smooth the RMS signal
+ const qreal smooth = pow(qreal(0.9), static_cast<qreal>(numSamples) / 256); // TODO: remove this magic number
+ m_rmsLevel = (m_rmsLevel * smooth) + (rmsLevel * (1.0 - smooth));
+
+ if (peakLevel > m_decayedPeakLevel) {
+ m_peakLevel = peakLevel;
+ m_decayedPeakLevel = peakLevel;
+ m_peakLevelChanged.start();
+ }
+
+ if (peakLevel > m_peakHoldLevel) {
+ m_peakHoldLevel = peakLevel;
+ m_peakHoldLevelChanged.start();
+ }
+
+ update();
+}
+
+void LevelMeter::redrawTimerExpired()
+{
+ // Decay the peak signal
+ const int elapsedMs = m_peakLevelChanged.elapsed();
+ const qreal decayAmount = m_peakDecayRate * elapsedMs;
+ if (decayAmount < m_peakLevel)
+ m_decayedPeakLevel = m_peakLevel - decayAmount;
+ else
+ m_decayedPeakLevel = 0.0;
+
+ // Check whether to clear the peak hold level
+ if (m_peakHoldLevelChanged.elapsed() > PeakHoldLevelDuration)
+ m_peakHoldLevel = 0.0;
+
+ update();
+}
+
+void LevelMeter::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event)
+
+ QPainter painter(this);
+ painter.fillRect(rect(), Qt::black);
+
+ QRect bar = rect();
+
+ bar.setTop(rect().top() + (1.0 - m_peakHoldLevel) * rect().height());
+ bar.setBottom(bar.top() + 5);
+ painter.fillRect(bar, m_rmsColor);
+ bar.setBottom(rect().bottom());
+
+ bar.setTop(rect().top() + (1.0 - m_decayedPeakLevel) * rect().height());
+ painter.fillRect(bar, m_peakColor);
+
+ bar.setTop(rect().top() + (1.0 - m_rmsLevel) * rect().height());
+ painter.fillRect(bar, m_rmsColor);
+}
diff --git a/examples/multimedia/spectrum/app/levelmeter.h b/examples/multimedia/spectrum/app/levelmeter.h
new file mode 100644
index 000000000..53147ff7b
--- /dev/null
+++ b/examples/multimedia/spectrum/app/levelmeter.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 LEVELMETER_H
+#define LEVELMETER_H
+
+#include <QTime>
+#include <QWidget>
+
+/**
+ * Widget which displays a vertical audio level meter, indicating the
+ * RMS and peak levels of the window of audio samples most recently analyzed
+ * by the Engine.
+ */
+class LevelMeter : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit LevelMeter(QWidget *parent = 0);
+ ~LevelMeter();
+
+ void paintEvent(QPaintEvent *event);
+
+public slots:
+ void reset();
+ void levelChanged(qreal rmsLevel, qreal peakLevel, int numSamples);
+
+private slots:
+ void redrawTimerExpired();
+
+private:
+ /**
+ * Height of RMS level bar.
+ * Range 0.0 - 1.0.
+ */
+ qreal m_rmsLevel;
+
+ /**
+ * Most recent peak level.
+ * Range 0.0 - 1.0.
+ */
+ qreal m_peakLevel;
+
+ /**
+ * Height of peak level bar.
+ * This is calculated by decaying m_peakLevel depending on the
+ * elapsed time since m_peakLevelChanged, and the value of m_decayRate.
+ */
+ qreal m_decayedPeakLevel;
+
+ /**
+ * Time at which m_peakLevel was last changed.
+ */
+ QTime m_peakLevelChanged;
+
+ /**
+ * Rate at which peak level bar decays.
+ * Expressed in level units / millisecond.
+ */
+ qreal m_peakDecayRate;
+
+ /**
+ * High watermark of peak level.
+ * Range 0.0 - 1.0.
+ */
+ qreal m_peakHoldLevel;
+
+ /**
+ * Time at which m_peakHoldLevel was last changed.
+ */
+ QTime m_peakHoldLevelChanged;
+
+ QTimer *m_redrawTimer;
+
+ QColor m_rmsColor;
+ QColor m_peakColor;
+
+};
+
+#endif // LEVELMETER_H
diff --git a/examples/multimedia/spectrum/app/main.cpp b/examples/multimedia/spectrum/app/main.cpp
new file mode 100644
index 000000000..7f47beb0c
--- /dev/null
+++ b/examples/multimedia/spectrum/app/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "mainwidget.h"
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ app.setApplicationName("QtMultimedia spectrum analyzer");
+
+ MainWidget w;
+ w.show();
+
+ return app.exec();
+}
diff --git a/examples/multimedia/spectrum/app/mainwidget.cpp b/examples/multimedia/spectrum/app/mainwidget.cpp
new file mode 100644
index 000000000..ea1f0ad86
--- /dev/null
+++ b/examples/multimedia/spectrum/app/mainwidget.cpp
@@ -0,0 +1,447 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "engine.h"
+#include "levelmeter.h"
+#include "mainwidget.h"
+#include "waveform.h"
+#include "progressbar.h"
+#include "settingsdialog.h"
+#include "spectrograph.h"
+#include "tonegeneratordialog.h"
+#include "utils.h"
+
+#include <QLabel>
+#include <QPushButton>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QStyle>
+#include <QMenu>
+#include <QFileDialog>
+#include <QTimerEvent>
+#include <QMessageBox>
+
+const int NullTimerId = -1;
+
+MainWidget::MainWidget(QWidget *parent)
+ : QWidget(parent)
+ , m_mode(NoMode)
+ , m_engine(new Engine(this))
+#ifndef DISABLE_WAVEFORM
+ , m_waveform(new Waveform(this))
+#endif
+ , m_progressBar(new ProgressBar(this))
+ , m_spectrograph(new Spectrograph(this))
+ , m_levelMeter(new LevelMeter(this))
+ , m_modeButton(new QPushButton(this))
+ , m_recordButton(new QPushButton(this))
+ , m_pauseButton(new QPushButton(this))
+ , m_playButton(new QPushButton(this))
+ , m_settingsButton(new QPushButton(this))
+ , m_infoMessage(new QLabel(tr("Select a mode to begin"), this))
+ , m_infoMessageTimerId(NullTimerId)
+ , m_settingsDialog(new SettingsDialog(
+ m_engine->availableAudioInputDevices(),
+ m_engine->availableAudioOutputDevices(),
+ this))
+ , m_toneGeneratorDialog(new ToneGeneratorDialog(this))
+ , m_modeMenu(new QMenu(this))
+ , m_loadFileAction(0)
+ , m_generateToneAction(0)
+ , m_recordAction(0)
+{
+ m_spectrograph->setParams(SpectrumNumBands, SpectrumLowFreq, SpectrumHighFreq);
+
+ createUi();
+ connectUi();
+}
+
+MainWidget::~MainWidget()
+{
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Public slots
+//-----------------------------------------------------------------------------
+
+void MainWidget::stateChanged(QAudio::Mode mode, QAudio::State state)
+{
+ Q_UNUSED(mode);
+
+ updateButtonStates();
+
+ if (QAudio::ActiveState != state && QAudio::SuspendedState != state) {
+ m_levelMeter->reset();
+ m_spectrograph->reset();
+ }
+}
+
+void MainWidget::formatChanged(const QAudioFormat &format)
+{
+ infoMessage(formatToString(format), NullMessageTimeout);
+
+#ifndef DISABLE_WAVEFORM
+ if (QAudioFormat() != format) {
+ m_waveform->initialize(format, WaveformTileLength,
+ WaveformWindowDuration);
+ }
+#endif
+}
+
+void MainWidget::spectrumChanged(qint64 position, qint64 length,
+ const FrequencySpectrum &spectrum)
+{
+ m_progressBar->windowChanged(position, length);
+ m_spectrograph->spectrumChanged(spectrum);
+}
+
+void MainWidget::infoMessage(const QString &message, int timeoutMs)
+{
+ m_infoMessage->setText(message);
+
+ if (NullTimerId != m_infoMessageTimerId) {
+ killTimer(m_infoMessageTimerId);
+ m_infoMessageTimerId = NullTimerId;
+ }
+
+ if (NullMessageTimeout != timeoutMs)
+ m_infoMessageTimerId = startTimer(timeoutMs);
+}
+
+void MainWidget::errorMessage(const QString &heading, const QString &detail)
+{
+ QMessageBox::warning(this, heading, detail, QMessageBox::Close);
+}
+
+void MainWidget::timerEvent(QTimerEvent *event)
+{
+ Q_ASSERT(event->timerId() == m_infoMessageTimerId);
+ Q_UNUSED(event) // suppress warnings in release builds
+ killTimer(m_infoMessageTimerId);
+ m_infoMessageTimerId = NullTimerId;
+ m_infoMessage->setText("");
+}
+
+void MainWidget::audioPositionChanged(qint64 position)
+{
+#ifndef DISABLE_WAVEFORM
+ m_waveform->audioPositionChanged(position);
+#else
+ Q_UNUSED(position)
+#endif
+}
+
+void MainWidget::bufferLengthChanged(qint64 length)
+{
+ m_progressBar->bufferLengthChanged(length);
+}
+
+
+//-----------------------------------------------------------------------------
+// Private slots
+//-----------------------------------------------------------------------------
+
+void MainWidget::showFileDialog()
+{
+ const QString dir;
+ const QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open WAV file"), dir, "*.wav");
+ if (fileNames.count()) {
+ reset();
+ setMode(LoadFileMode);
+ m_engine->loadFile(fileNames.front());
+ updateButtonStates();
+ } else {
+ updateModeMenu();
+ }
+}
+
+void MainWidget::showSettingsDialog()
+{
+ m_settingsDialog->exec();
+ if (m_settingsDialog->result() == QDialog::Accepted) {
+ m_engine->setAudioInputDevice(m_settingsDialog->inputDevice());
+ m_engine->setAudioOutputDevice(m_settingsDialog->outputDevice());
+ m_engine->setWindowFunction(m_settingsDialog->windowFunction());
+ }
+}
+
+void MainWidget::showToneGeneratorDialog()
+{
+ m_toneGeneratorDialog->exec();
+ if (m_toneGeneratorDialog->result() == QDialog::Accepted) {
+ reset();
+ setMode(GenerateToneMode);
+ const qreal amplitude = m_toneGeneratorDialog->amplitude();
+ if (m_toneGeneratorDialog->isFrequencySweepEnabled()) {
+ m_engine->generateSweptTone(amplitude);
+ } else {
+ const qreal frequency = m_toneGeneratorDialog->frequency();
+ const Tone tone(frequency, amplitude);
+ m_engine->generateTone(tone);
+ updateButtonStates();
+ }
+ } else {
+ updateModeMenu();
+ }
+}
+
+void MainWidget::initializeRecord()
+{
+ reset();
+ setMode(RecordMode);
+ if (m_engine->initializeRecord())
+ updateButtonStates();
+}
+
+
+//-----------------------------------------------------------------------------
+// Private functions
+//-----------------------------------------------------------------------------
+
+void MainWidget::createUi()
+{
+ createMenus();
+
+ setWindowTitle(tr("Spectrum Analyser"));
+
+ QVBoxLayout *windowLayout = new QVBoxLayout(this);
+
+ m_infoMessage->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ m_infoMessage->setAlignment(Qt::AlignHCenter);
+ windowLayout->addWidget(m_infoMessage);
+
+#ifdef SUPERIMPOSE_PROGRESS_ON_WAVEFORM
+ QScopedPointer<QHBoxLayout> waveformLayout(new QHBoxLayout);
+ waveformLayout->addWidget(m_progressBar);
+ m_progressBar->setMinimumHeight(m_waveform->minimumHeight());
+ waveformLayout->setMargin(0);
+ m_waveform->setLayout(waveformLayout.data());
+ waveformLayout.take();
+ windowLayout->addWidget(m_waveform);
+#else
+#ifndef DISABLE_WAVEFORM
+ windowLayout->addWidget(m_waveform);
+#endif // DISABLE_WAVEFORM
+ windowLayout->addWidget(m_progressBar);
+#endif // SUPERIMPOSE_PROGRESS_ON_WAVEFORM
+
+ // Spectrograph and level meter
+
+ QScopedPointer<QHBoxLayout> analysisLayout(new QHBoxLayout);
+ analysisLayout->addWidget(m_spectrograph);
+ analysisLayout->addWidget(m_levelMeter);
+ windowLayout->addLayout(analysisLayout.data());
+ analysisLayout.take();
+
+ // Button panel
+
+ const QSize buttonSize(30, 30);
+
+ m_modeButton->setText(tr("Mode"));
+
+ m_recordIcon = QIcon(":/images/record.png");
+ m_recordButton->setIcon(m_recordIcon);
+ m_recordButton->setEnabled(false);
+ m_recordButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ m_recordButton->setMinimumSize(buttonSize);
+
+ m_pauseIcon = style()->standardIcon(QStyle::SP_MediaPause);
+ m_pauseButton->setIcon(m_pauseIcon);
+ m_pauseButton->setEnabled(false);
+ m_pauseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ m_pauseButton->setMinimumSize(buttonSize);
+
+ m_playIcon = style()->standardIcon(QStyle::SP_MediaPlay);
+ m_playButton->setIcon(m_playIcon);
+ m_playButton->setEnabled(false);
+ m_playButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ m_playButton->setMinimumSize(buttonSize);
+
+ m_settingsIcon = QIcon(":/images/settings.png");
+ m_settingsButton->setIcon(m_settingsIcon);
+ m_settingsButton->setEnabled(true);
+ m_settingsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ m_settingsButton->setMinimumSize(buttonSize);
+
+ QScopedPointer<QHBoxLayout> buttonPanelLayout(new QHBoxLayout);
+ buttonPanelLayout->addStretch();
+ buttonPanelLayout->addWidget(m_modeButton);
+ buttonPanelLayout->addWidget(m_recordButton);
+ buttonPanelLayout->addWidget(m_pauseButton);
+ buttonPanelLayout->addWidget(m_playButton);
+ buttonPanelLayout->addWidget(m_settingsButton);
+
+ QWidget *buttonPanel = new QWidget(this);
+ buttonPanel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ buttonPanel->setLayout(buttonPanelLayout.data());
+ buttonPanelLayout.take(); // ownership transferred to buttonPanel
+
+ QScopedPointer<QHBoxLayout> bottomPaneLayout(new QHBoxLayout);
+ bottomPaneLayout->addWidget(buttonPanel);
+ windowLayout->addLayout(bottomPaneLayout.data());
+ bottomPaneLayout.take(); // ownership transferred to windowLayout
+
+ // Apply layout
+
+ setLayout(windowLayout);
+}
+
+void MainWidget::connectUi()
+{
+ CHECKED_CONNECT(m_recordButton, SIGNAL(clicked()),
+ m_engine, SLOT(startRecording()));
+
+ CHECKED_CONNECT(m_pauseButton, SIGNAL(clicked()),
+ m_engine, SLOT(suspend()));
+
+ CHECKED_CONNECT(m_playButton, SIGNAL(clicked()),
+ m_engine, SLOT(startPlayback()));
+
+ CHECKED_CONNECT(m_settingsButton, SIGNAL(clicked()),
+ this, SLOT(showSettingsDialog()));
+
+ CHECKED_CONNECT(m_engine, SIGNAL(stateChanged(QAudio::Mode,QAudio::State)),
+ this, SLOT(stateChanged(QAudio::Mode,QAudio::State)));
+
+ CHECKED_CONNECT(m_engine, SIGNAL(formatChanged(const QAudioFormat &)),
+ this, SLOT(formatChanged(const QAudioFormat &)));
+
+ m_progressBar->bufferLengthChanged(m_engine->bufferLength());
+
+ CHECKED_CONNECT(m_engine, SIGNAL(bufferLengthChanged(qint64)),
+ this, SLOT(bufferLengthChanged(qint64)));
+
+ CHECKED_CONNECT(m_engine, SIGNAL(dataLengthChanged(qint64)),
+ this, SLOT(updateButtonStates()));
+
+ CHECKED_CONNECT(m_engine, SIGNAL(recordPositionChanged(qint64)),
+ m_progressBar, SLOT(recordPositionChanged(qint64)));
+
+ CHECKED_CONNECT(m_engine, SIGNAL(playPositionChanged(qint64)),
+ m_progressBar, SLOT(playPositionChanged(qint64)));
+
+ CHECKED_CONNECT(m_engine, SIGNAL(recordPositionChanged(qint64)),
+ this, SLOT(audioPositionChanged(qint64)));
+
+ CHECKED_CONNECT(m_engine, SIGNAL(playPositionChanged(qint64)),
+ this, SLOT(audioPositionChanged(qint64)));
+
+ CHECKED_CONNECT(m_engine, SIGNAL(levelChanged(qreal, qreal, int)),
+ m_levelMeter, SLOT(levelChanged(qreal, qreal, int)));
+
+ CHECKED_CONNECT(m_engine, SIGNAL(spectrumChanged(qint64, qint64, const FrequencySpectrum &)),
+ this, SLOT(spectrumChanged(qint64, qint64, const FrequencySpectrum &)));
+
+ CHECKED_CONNECT(m_engine, SIGNAL(infoMessage(QString, int)),
+ this, SLOT(infoMessage(QString, int)));
+
+ CHECKED_CONNECT(m_engine, SIGNAL(errorMessage(QString, QString)),
+ this, SLOT(errorMessage(QString, QString)));
+
+ CHECKED_CONNECT(m_spectrograph, SIGNAL(infoMessage(QString, int)),
+ this, SLOT(infoMessage(QString, int)));
+
+#ifndef DISABLE_WAVEFORM
+ CHECKED_CONNECT(m_engine, SIGNAL(bufferChanged(qint64, qint64, const QByteArray &)),
+ m_waveform, SLOT(bufferChanged(qint64, qint64, const QByteArray &)));
+#endif
+}
+
+void MainWidget::createMenus()
+{
+ m_modeButton->setMenu(m_modeMenu);
+
+ m_generateToneAction = m_modeMenu->addAction(tr("Play generated tone"));
+ m_recordAction = m_modeMenu->addAction(tr("Record and play back"));
+ m_loadFileAction = m_modeMenu->addAction(tr("Play file"));
+
+ m_loadFileAction->setCheckable(true);
+ m_generateToneAction->setCheckable(true);
+ m_recordAction->setCheckable(true);
+
+ connect(m_loadFileAction, SIGNAL(triggered(bool)), this, SLOT(showFileDialog()));
+ connect(m_generateToneAction, SIGNAL(triggered(bool)), this, SLOT(showToneGeneratorDialog()));
+ connect(m_recordAction, SIGNAL(triggered(bool)), this, SLOT(initializeRecord()));
+}
+
+void MainWidget::updateButtonStates()
+{
+ const bool recordEnabled = ((QAudio::AudioOutput == m_engine->mode() ||
+ (QAudio::ActiveState != m_engine->state() &&
+ QAudio::IdleState != m_engine->state())) &&
+ RecordMode == m_mode);
+ m_recordButton->setEnabled(recordEnabled);
+
+ const bool pauseEnabled = (QAudio::ActiveState == m_engine->state() ||
+ QAudio::IdleState == m_engine->state());
+ m_pauseButton->setEnabled(pauseEnabled);
+
+ const bool playEnabled = (/*m_engine->dataLength() &&*/
+ (QAudio::AudioOutput != m_engine->mode() ||
+ (QAudio::ActiveState != m_engine->state() &&
+ QAudio::IdleState != m_engine->state())));
+ m_playButton->setEnabled(playEnabled);
+}
+
+void MainWidget::reset()
+{
+#ifndef DISABLE_WAVEFORM
+ m_waveform->reset();
+#endif
+ m_engine->reset();
+ m_levelMeter->reset();
+ m_spectrograph->reset();
+ m_progressBar->reset();
+}
+
+void MainWidget::setMode(Mode mode)
+{
+ m_mode = mode;
+ updateModeMenu();
+}
+
+void MainWidget::updateModeMenu()
+{
+ m_loadFileAction->setChecked(LoadFileMode == m_mode);
+ m_generateToneAction->setChecked(GenerateToneMode == m_mode);
+ m_recordAction->setChecked(RecordMode == m_mode);
+}
diff --git a/examples/multimedia/spectrum/app/mainwidget.h b/examples/multimedia/spectrum/app/mainwidget.h
new file mode 100644
index 000000000..971d90381
--- /dev/null
+++ b/examples/multimedia/spectrum/app/mainwidget.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 MAINWIDGET_H
+#define MAINWIDGET_H
+
+#include <QAudio>
+#include <QIcon>
+#include <QWidget>
+
+class Engine;
+class FrequencySpectrum;
+class LevelMeter;
+class ProgressBar;
+class SettingsDialog;
+class Spectrograph;
+class ToneGeneratorDialog;
+class Waveform;
+
+QT_BEGIN_NAMESPACE
+class QAction;
+class QAudioFormat;
+class QLabel;
+class QMenu;
+class QPushButton;
+QT_END_NAMESPACE
+
+/**
+ * Main application widget, responsible for connecting the various UI
+ * elements to the Engine.
+ */
+class MainWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit MainWidget(QWidget *parent = 0);
+ ~MainWidget();
+
+ // QObject
+ void timerEvent(QTimerEvent *event);
+
+public slots:
+ void stateChanged(QAudio::Mode mode, QAudio::State state);
+ void formatChanged(const QAudioFormat &format);
+ void spectrumChanged(qint64 position, qint64 length,
+ const FrequencySpectrum &spectrum);
+ void infoMessage(const QString &message, int timeoutMs);
+ void errorMessage(const QString &heading, const QString &detail);
+ void audioPositionChanged(qint64 position);
+ void bufferLengthChanged(qint64 length);
+
+private slots:
+ void showFileDialog();
+ void showSettingsDialog();
+ void showToneGeneratorDialog();
+ void initializeRecord();
+ void updateModeMenu();
+ void updateButtonStates();
+
+private:
+ void createUi();
+ void createMenus();
+ void connectUi();
+ void reset();
+
+ enum Mode {
+ NoMode,
+ RecordMode,
+ GenerateToneMode,
+ LoadFileMode
+ };
+
+ void setMode(Mode mode);
+
+private:
+ Mode m_mode;
+
+ Engine* m_engine;
+
+#ifndef DISABLE_WAVEFORM
+ Waveform* m_waveform;
+#endif
+ ProgressBar* m_progressBar;
+ Spectrograph* m_spectrograph;
+ LevelMeter* m_levelMeter;
+
+ QPushButton* m_modeButton;
+ QPushButton* m_recordButton;
+ QIcon m_recordIcon;
+ QPushButton* m_pauseButton;
+ QIcon m_pauseIcon;
+ QPushButton* m_playButton;
+ QIcon m_playIcon;
+ QPushButton* m_settingsButton;
+ QIcon m_settingsIcon;
+
+ QLabel* m_infoMessage;
+ int m_infoMessageTimerId;
+
+ SettingsDialog* m_settingsDialog;
+ ToneGeneratorDialog* m_toneGeneratorDialog;
+
+ QMenu* m_modeMenu;
+ QAction* m_loadFileAction;
+ QAction* m_generateToneAction;
+ QAction* m_recordAction;
+};
+
+#endif // MAINWIDGET_H
diff --git a/examples/multimedia/spectrum/app/progressbar.cpp b/examples/multimedia/spectrum/app/progressbar.cpp
new file mode 100644
index 000000000..79596cdca
--- /dev/null
+++ b/examples/multimedia/spectrum/app/progressbar.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "progressbar.h"
+#include "spectrum.h"
+#include <QPainter>
+
+ProgressBar::ProgressBar(QWidget *parent)
+ : QWidget(parent)
+ , m_bufferLength(0)
+ , m_recordPosition(0)
+ , m_playPosition(0)
+ , m_windowPosition(0)
+ , m_windowLength(0)
+{
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ setMinimumHeight(30);
+#ifdef SUPERIMPOSE_PROGRESS_ON_WAVEFORM
+ setAutoFillBackground(false);
+#endif
+}
+
+ProgressBar::~ProgressBar()
+{
+
+}
+
+void ProgressBar::reset()
+{
+ m_bufferLength = 0;
+ m_recordPosition = 0;
+ m_playPosition = 0;
+ m_windowPosition = 0;
+ m_windowLength = 0;
+ update();
+}
+
+void ProgressBar::paintEvent(QPaintEvent * /*event*/)
+{
+ QPainter painter(this);
+
+ QColor bufferColor(0, 0, 255);
+ QColor windowColor(0, 255, 0);
+
+#ifdef SUPERIMPOSE_PROGRESS_ON_WAVEFORM
+ bufferColor.setAlphaF(0.5);
+ windowColor.setAlphaF(0.5);
+#else
+ painter.fillRect(rect(), Qt::black);
+#endif
+
+ if (m_bufferLength) {
+ QRect bar = rect();
+ const qreal play = qreal(m_playPosition) / m_bufferLength;
+ bar.setLeft(rect().left() + play * rect().width());
+ const qreal record = qreal(m_recordPosition) / m_bufferLength;
+ bar.setRight(rect().left() + record * rect().width());
+ painter.fillRect(bar, bufferColor);
+
+ QRect window = rect();
+ const qreal windowLeft = qreal(m_windowPosition) / m_bufferLength;
+ window.setLeft(rect().left() + windowLeft * rect().width());
+ const qreal windowWidth = qreal(m_windowLength) / m_bufferLength;
+ window.setWidth(windowWidth * rect().width());
+ painter.fillRect(window, windowColor);
+ }
+}
+
+void ProgressBar::bufferLengthChanged(qint64 bufferSize)
+{
+ m_bufferLength = bufferSize;
+ m_recordPosition = 0;
+ m_playPosition = 0;
+ m_windowPosition = 0;
+ m_windowLength = 0;
+ repaint();
+}
+
+void ProgressBar::recordPositionChanged(qint64 recordPosition)
+{
+ Q_ASSERT(recordPosition >= 0);
+ Q_ASSERT(recordPosition <= m_bufferLength);
+ m_recordPosition = recordPosition;
+ repaint();
+}
+
+void ProgressBar::playPositionChanged(qint64 playPosition)
+{
+ Q_ASSERT(playPosition >= 0);
+ Q_ASSERT(playPosition <= m_bufferLength);
+ m_playPosition = playPosition;
+ repaint();
+}
+
+void ProgressBar::windowChanged(qint64 position, qint64 length)
+{
+ Q_ASSERT(position >= 0);
+ Q_ASSERT(position <= m_bufferLength);
+ Q_ASSERT(position + length <= m_bufferLength);
+ m_windowPosition = position;
+ m_windowLength = length;
+ repaint();
+}
diff --git a/examples/multimedia/spectrum/app/progressbar.h b/examples/multimedia/spectrum/app/progressbar.h
new file mode 100644
index 000000000..9ee505d49
--- /dev/null
+++ b/examples/multimedia/spectrum/app/progressbar.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 PROGRESSBAR_H
+#define PROGRESSBAR_H
+
+#include <QWidget>
+
+/**
+ * Widget which displays a the current fill state of the Engine's internal
+ * buffer, and the current play/record position within that buffer.
+ */
+class ProgressBar : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ProgressBar(QWidget *parent = 0);
+ ~ProgressBar();
+
+ void reset();
+ void paintEvent(QPaintEvent *event);
+
+public slots:
+ void bufferLengthChanged(qint64 length);
+ void recordPositionChanged(qint64 recordPosition);
+ void playPositionChanged(qint64 playPosition);
+ void windowChanged(qint64 position, qint64 length);
+
+private:
+ qint64 m_bufferLength;
+ qint64 m_recordPosition;
+ qint64 m_playPosition;
+ qint64 m_windowPosition;
+ qint64 m_windowLength;
+};
+
+#endif // PROGRESSBAR_H
diff --git a/examples/multimedia/spectrum/app/settingsdialog.cpp b/examples/multimedia/spectrum/app/settingsdialog.cpp
new file mode 100644
index 000000000..abca69783
--- /dev/null
+++ b/examples/multimedia/spectrum/app/settingsdialog.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "settingsdialog.h"
+#include <QCheckBox>
+#include <QComboBox>
+#include <QDialogButtonBox>
+#include <QLabel>
+#include <QPushButton>
+#include <QSlider>
+#include <QSpinBox>
+#include <QVBoxLayout>
+
+SettingsDialog::SettingsDialog(
+ const QList<QAudioDeviceInfo> &availableInputDevices,
+ const QList<QAudioDeviceInfo> &availableOutputDevices,
+ QWidget *parent)
+ : QDialog(parent)
+ , m_windowFunction(DefaultWindowFunction)
+ , m_inputDeviceComboBox(new QComboBox(this))
+ , m_outputDeviceComboBox(new QComboBox(this))
+ , m_windowFunctionComboBox(new QComboBox(this))
+{
+ QVBoxLayout *dialogLayout = new QVBoxLayout(this);
+
+ // Populate combo boxes
+
+ QAudioDeviceInfo device;
+ foreach (device, availableInputDevices)
+ m_inputDeviceComboBox->addItem(device.deviceName(),
+ QVariant::fromValue(device));
+ foreach (device, availableOutputDevices)
+ m_outputDeviceComboBox->addItem(device.deviceName(),
+ QVariant::fromValue(device));
+
+ m_windowFunctionComboBox->addItem(tr("None"), QVariant::fromValue(int(NoWindow)));
+ m_windowFunctionComboBox->addItem("Hann", QVariant::fromValue(int(HannWindow)));
+ m_windowFunctionComboBox->setCurrentIndex(m_windowFunction);
+
+ // Initialize default devices
+ if (!availableInputDevices.empty())
+ m_inputDevice = availableInputDevices.front();
+ if (!availableOutputDevices.empty())
+ m_outputDevice = availableOutputDevices.front();
+
+ // Add widgets to layout
+
+ QScopedPointer<QHBoxLayout> inputDeviceLayout(new QHBoxLayout);
+ QLabel *inputDeviceLabel = new QLabel(tr("Input device"), this);
+ 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);
+ 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)));
+
+ // Add standard buttons to layout
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
+ buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ dialogLayout->addWidget(buttonBox);
+
+ // Connect standard buttons
+ CHECKED_CONNECT(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()),
+ this, SLOT(accept()));
+ CHECKED_CONNECT(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()),
+ this, SLOT(reject()));
+
+ 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>();
+}
+
diff --git a/examples/multimedia/spectrum/app/settingsdialog.h b/examples/multimedia/spectrum/app/settingsdialog.h
new file mode 100644
index 000000000..0ce114dc9
--- /dev/null
+++ b/examples/multimedia/spectrum/app/settingsdialog.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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>
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QCheckBox;
+class QSlider;
+class QSpinBox;
+class QGridLayout;
+QT_END_NAMESPACE
+
+/**
+ * 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:
+ WindowFunction m_windowFunction;
+ QAudioDeviceInfo m_inputDevice;
+ QAudioDeviceInfo m_outputDevice;
+
+ QComboBox *m_inputDeviceComboBox;
+ QComboBox *m_outputDeviceComboBox;
+ QComboBox *m_windowFunctionComboBox;
+};
+
+#endif // SETTINGSDIALOG_H
diff --git a/examples/multimedia/spectrum/app/spectrograph.cpp b/examples/multimedia/spectrum/app/spectrograph.cpp
new file mode 100644
index 000000000..b1785e728
--- /dev/null
+++ b/examples/multimedia/spectrum/app/spectrograph.cpp
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "spectrograph.h"
+#include <QDebug>
+#include <QMouseEvent>
+#include <QPainter>
+#include <QTimerEvent>
+
+const int NullTimerId = -1;
+const int NullIndex = -1;
+const int BarSelectionInterval = 2000;
+
+Spectrograph::Spectrograph(QWidget *parent)
+ : QWidget(parent)
+ , m_barSelected(NullIndex)
+ , m_timerId(NullTimerId)
+ , m_lowFreq(0.0)
+ , m_highFreq(0.0)
+{
+ setMinimumHeight(100);
+}
+
+Spectrograph::~Spectrograph()
+{
+
+}
+
+void Spectrograph::setParams(int numBars, qreal lowFreq, qreal highFreq)
+{
+ Q_ASSERT(numBars > 0);
+ Q_ASSERT(highFreq > lowFreq);
+ m_bars.resize(numBars);
+ m_lowFreq = lowFreq;
+ m_highFreq = highFreq;
+ updateBars();
+}
+
+void Spectrograph::timerEvent(QTimerEvent *event)
+{
+ Q_ASSERT(event->timerId() == m_timerId);
+ Q_UNUSED(event) // suppress warnings in release builds
+ killTimer(m_timerId);
+ m_timerId = NullTimerId;
+ m_barSelected = NullIndex;
+ update();
+}
+
+void Spectrograph::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event)
+
+ QPainter painter(this);
+ painter.fillRect(rect(), Qt::black);
+
+ const int numBars = m_bars.count();
+
+ // Highlight region of selected bar
+ if (m_barSelected != NullIndex && numBars) {
+ QRect regionRect = rect();
+ regionRect.setLeft(m_barSelected * rect().width() / numBars);
+ regionRect.setWidth(rect().width() / numBars);
+ QColor regionColor(202, 202, 64);
+ painter.setBrush(Qt::DiagCrossPattern);
+ painter.fillRect(regionRect, regionColor);
+ painter.setBrush(Qt::NoBrush);
+ }
+
+ QColor barColor(51, 204, 102);
+ QColor clipColor(255, 255, 0);
+
+ // Draw the outline
+ const QColor gridColor = barColor.darker();
+ QPen gridPen(gridColor);
+ painter.setPen(gridPen);
+ painter.drawLine(rect().topLeft(), rect().topRight());
+ painter.drawLine(rect().topRight(), rect().bottomRight());
+ painter.drawLine(rect().bottomRight(), rect().bottomLeft());
+ painter.drawLine(rect().bottomLeft(), rect().topLeft());
+
+ QVector<qreal> dashes;
+ dashes << 2 << 2;
+ gridPen.setDashPattern(dashes);
+ painter.setPen(gridPen);
+
+ // Draw vertical lines between bars
+ if (numBars) {
+ const int numHorizontalSections = numBars;
+ QLine line(rect().topLeft(), rect().bottomLeft());
+ for (int i=1; i<numHorizontalSections; ++i) {
+ line.translate(rect().width()/numHorizontalSections, 0);
+ painter.drawLine(line);
+ }
+ }
+
+ // Draw horizontal lines
+ const int numVerticalSections = 10;
+ QLine line(rect().topLeft(), rect().topRight());
+ for (int i=1; i<numVerticalSections; ++i) {
+ line.translate(0, rect().height()/numVerticalSections);
+ painter.drawLine(line);
+ }
+
+ barColor = barColor.lighter();
+ barColor.setAlphaF(0.75);
+ clipColor.setAlphaF(0.75);
+
+ // Draw the bars
+ if (numBars) {
+ // Calculate width of bars and gaps
+ const int widgetWidth = rect().width();
+ const int barPlusGapWidth = widgetWidth / numBars;
+ const int barWidth = 0.8 * barPlusGapWidth;
+ const int gapWidth = barPlusGapWidth - barWidth;
+ const int paddingWidth = widgetWidth - numBars * (barWidth + gapWidth);
+ const int leftPaddingWidth = (paddingWidth + gapWidth) / 2;
+ const int barHeight = rect().height() - 2 * gapWidth;
+
+ for (int i=0; i<numBars; ++i) {
+ const qreal value = m_bars[i].value;
+ Q_ASSERT(value >= 0.0 && value <= 1.0);
+ QRect bar = rect();
+ bar.setLeft(rect().left() + leftPaddingWidth + (i * (gapWidth + barWidth)));
+ bar.setWidth(barWidth);
+ bar.setTop(rect().top() + gapWidth + (1.0 - value) * barHeight);
+ bar.setBottom(rect().bottom() - gapWidth);
+
+ QColor color = barColor;
+ if (m_bars[i].clipped)
+ color = clipColor;
+
+ painter.fillRect(bar, color);
+ }
+ }
+}
+
+void Spectrograph::mousePressEvent(QMouseEvent *event)
+{
+ const QPoint pos = event->pos();
+ const int index = m_bars.count() * (pos.x() - rect().left()) / rect().width();
+ selectBar(index);
+}
+
+void Spectrograph::reset()
+{
+ m_spectrum.reset();
+ spectrumChanged(m_spectrum);
+}
+
+void Spectrograph::spectrumChanged(const FrequencySpectrum &spectrum)
+{
+ m_spectrum = spectrum;
+ updateBars();
+}
+
+int Spectrograph::barIndex(qreal frequency) const
+{
+ Q_ASSERT(frequency >= m_lowFreq && frequency < m_highFreq);
+ const qreal bandWidth = (m_highFreq - m_lowFreq) / m_bars.count();
+ const int index = (frequency - m_lowFreq) / bandWidth;
+ if (index <0 || index >= m_bars.count())
+ Q_ASSERT(false);
+ return index;
+}
+
+QPair<qreal, qreal> Spectrograph::barRange(int index) const
+{
+ Q_ASSERT(index >= 0 && index < m_bars.count());
+ const qreal bandWidth = (m_highFreq - m_lowFreq) / m_bars.count();
+ return QPair<qreal, qreal>(index * bandWidth, (index+1) * bandWidth);
+}
+
+void Spectrograph::updateBars()
+{
+ m_bars.fill(Bar());
+ FrequencySpectrum::const_iterator i = m_spectrum.begin();
+ const FrequencySpectrum::const_iterator end = m_spectrum.end();
+ for ( ; i != end; ++i) {
+ const FrequencySpectrum::Element e = *i;
+ if (e.frequency >= m_lowFreq && e.frequency < m_highFreq) {
+ Bar &bar = m_bars[barIndex(e.frequency)];
+ bar.value = qMax(bar.value, e.amplitude);
+ bar.clipped |= e.clipped;
+ }
+ }
+ update();
+}
+
+void Spectrograph::selectBar(int index) {
+ const QPair<qreal, qreal> frequencyRange = barRange(index);
+ const QString message = QString("%1 - %2 Hz")
+ .arg(frequencyRange.first)
+ .arg(frequencyRange.second);
+ emit infoMessage(message, BarSelectionInterval);
+
+ if (NullTimerId != m_timerId)
+ killTimer(m_timerId);
+ m_timerId = startTimer(BarSelectionInterval);
+
+ m_barSelected = index;
+ update();
+}
+
+
diff --git a/examples/multimedia/spectrum/app/spectrograph.h b/examples/multimedia/spectrum/app/spectrograph.h
new file mode 100644
index 000000000..470d4e5e2
--- /dev/null
+++ b/examples/multimedia/spectrum/app/spectrograph.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 SPECTROGRAPH_H
+#define SPECTROGRAPH_H
+
+#include "frequencyspectrum.h"
+
+#include <QWidget>
+
+/**
+ * Widget which displays a spectrograph showing the frequency spectrum
+ * of the window of audio samples most recently analyzed by the Engine.
+ */
+class Spectrograph : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit Spectrograph(QWidget *parent = 0);
+ ~Spectrograph();
+
+ void setParams(int numBars, qreal lowFreq, qreal highFreq);
+
+ // QObject
+ void timerEvent(QTimerEvent *event);
+
+ // QWidget
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+
+signals:
+ void infoMessage(const QString &message, int intervalMs);
+
+public slots:
+ void reset();
+ void spectrumChanged(const FrequencySpectrum &spectrum);
+
+private:
+ int barIndex(qreal frequency) const;
+ QPair<qreal, qreal> barRange(int barIndex) const;
+ void updateBars();
+
+ void selectBar(int index);
+
+private:
+ struct Bar {
+ Bar() : value(0.0), clipped(false) { }
+ qreal value;
+ bool clipped;
+ };
+
+ QVector<Bar> m_bars;
+ int m_barSelected;
+ int m_timerId;
+ qreal m_lowFreq;
+ qreal m_highFreq;
+ FrequencySpectrum m_spectrum;
+};
+
+#endif // SPECTROGRAPH_H
diff --git a/examples/multimedia/spectrum/app/spectrum.h b/examples/multimedia/spectrum/app/spectrum.h
new file mode 100644
index 000000000..f79aaa9de
--- /dev/null
+++ b/examples/multimedia/spectrum/app/spectrum.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 SPECTRUM_H
+#define SPECTRUM_H
+
+#include <qglobal.h>
+#include "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;
+
+// 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
+};
+
+const WindowFunction DefaultWindowFunction = HannWindow;
+
+struct Tone
+{
+ Tone(qreal freq = 0.0, qreal amp = 0.0)
+ : frequency(freq), amplitude(amp)
+ { }
+
+ // Start and end frequencies for swept tone generation
+ qreal frequency;
+
+ // Amplitude in range [0.0, 1.0]
+ qreal amplitude;
+};
+
+struct SweptTone
+{
+ SweptTone(qreal start = 0.0, qreal end = 0.0, qreal amp = 0.0)
+ : startFreq(start), endFreq(end), amplitude(amp)
+ { Q_ASSERT(end >= start); }
+
+ SweptTone(const Tone &tone)
+ : startFreq(tone.frequency), endFreq(tone.frequency), amplitude(tone.amplitude)
+ { }
+
+ // Start and end frequencies for swept tone generation
+ qreal startFreq;
+ qreal endFreq;
+
+ // Amplitude in range [0.0, 1.0]
+ qreal amplitude;
+};
+
+
+//-----------------------------------------------------------------------------
+// Macros
+//-----------------------------------------------------------------------------
+
+// Macro which connects a signal to a slot, and which causes application to
+// abort if the connection fails. This is intended to catch programming errors
+// such as mis-typing a signal or slot name. It is necessary to write our own
+// macro to do this - the following idiom
+// Q_ASSERT(connect(source, signal, receiver, slot));
+// will not work because Q_ASSERT compiles to a no-op in release builds.
+
+#define CHECKED_CONNECT(source, signal, receiver, slot) \
+ if (!connect(source, signal, receiver, slot)) \
+ qt_assert_x(Q_FUNC_INFO, "CHECKED_CONNECT failed", __FILE__, __LINE__);
+
+// Handle some dependencies between macros defined in the .pro file
+
+#ifdef DISABLE_WAVEFORM
+#undef SUPERIMPOSE_PROGRESS_ON_WAVEFORM
+#endif
+
+#endif // SPECTRUM_H
+
diff --git a/examples/multimedia/spectrum/app/spectrum.qrc b/examples/multimedia/spectrum/app/spectrum.qrc
new file mode 100644
index 000000000..61004791b
--- /dev/null
+++ b/examples/multimedia/spectrum/app/spectrum.qrc
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>images/record.png</file>
+ <file>images/settings.png</file>
+</qresource>
+</RCC>
+
diff --git a/examples/multimedia/spectrum/app/spectrumanalyser.cpp b/examples/multimedia/spectrum/app/spectrumanalyser.cpp
new file mode 100644
index 000000000..d3fe5114b
--- /dev/null
+++ b/examples/multimedia/spectrum/app/spectrumanalyser.cpp
@@ -0,0 +1,276 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "spectrumanalyser.h"
+#include "utils.h"
+#include "fftreal_wrapper.h"
+
+#include <qmath.h>
+#include <qmetatype.h>
+#include <QAudioFormat>
+#include <QThread>
+
+SpectrumAnalyserThread::SpectrumAnalyserThread(QObject *parent)
+ : QObject(parent)
+#ifndef DISABLE_FFT
+ , m_fft(new FFTRealWrapper)
+#endif
+ , 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
+ calculateWindow();
+}
+
+SpectrumAnalyserThread::~SpectrumAnalyserThread()
+{
+#ifndef DISABLE_FFT
+ delete m_fft;
+#endif
+}
+
+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((2 * M_PI * i) / (m_numSamples - 1)));
+ break;
+ default:
+ Q_ASSERT(false);
+ }
+
+ m_window[i] = x;
+ }
+}
+
+void SpectrumAnalyserThread::calculateSpectrum(const QByteArray &buffer,
+ int inputFrequency,
+ int bytesPerSample)
+{
+#ifndef DISABLE_FFT
+ 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;
+ ptr += bytesPerSample;
+ }
+
+ // Calculate the FFT
+ m_fft->calculateFFT(m_output.data(), m_input.data());
+
+ // 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];
+ qreal imag = 0.0;
+ if (i>0 && i<m_numSamples/2)
+ imag = m_output[m_numSamples/2 + i];
+
+ 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;
+ }
+#endif
+
+ 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)));
+}
+
+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::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;
+
+ if (isReady()) {
+ Q_ASSERT(isPCMS16LE(format));
+
+ const int bytesPerSample = format.sampleSize() * format.channelCount() / 8;
+
+#ifdef DUMP_SPECTRUMANALYSER
+ m_count++;
+ const QString pcmFileName = m_outputDir.filePath(QString("spectrum_%1.pcm").arg(m_count, 4, 10, QChar('0')));
+ QFile pcmFile(pcmFileName);
+ pcmFile.open(QIODevice::WriteOnly);
+ const int bufferLength = m_numSamples * bytesPerSample;
+ pcmFile.write(buffer, bufferLength);
+
+ m_textStream << "TimeDomain " << m_count << "\n";
+ const qint16* input = reinterpret_cast<const qint16*>(buffer);
+ for (int i=0; i<m_numSamples; ++i) {
+ m_textStream << i << "\t" << *input << "\n";
+ input += format.channels();
+ }
+#endif
+
+ 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;
+}
diff --git a/examples/multimedia/spectrum/app/spectrumanalyser.h b/examples/multimedia/spectrum/app/spectrumanalyser.h
new file mode 100644
index 000000000..582d032de
--- /dev/null
+++ b/examples/multimedia/spectrum/app/spectrumanalyser.h
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 SPECTRUMANALYSER_H
+#define SPECTRUMANALYSER_H
+
+#include <QByteArray>
+#include <QObject>
+#include <QVector>
+
+#ifdef DUMP_SPECTRUMANALYSER
+#include <QDir>
+#include <QFile>
+#include <QTextStream>
+#endif
+
+#include "frequencyspectrum.h"
+#include "spectrum.h"
+
+#ifndef DISABLE_FFT
+#include "FFTRealFixLenParam.h"
+#endif
+
+QT_FORWARD_DECLARE_CLASS(QAudioFormat)
+QT_FORWARD_DECLARE_CLASS(QThread)
+
+class FFTRealWrapper;
+
+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);
+
+signals:
+ void calculationComplete(const FrequencySpectrum &spectrum);
+
+private:
+ void calculateWindow();
+
+private:
+#ifndef DISABLE_FFT
+ FFTRealWrapper* m_fft;
+#endif
+
+ const int m_numSamples;
+
+ WindowFunction m_windowFunction;
+
+#ifdef DISABLE_FFT
+ typedef qreal DataType;
+#else
+ typedef FFTRealFixLenParam::DataType DataType;
+#endif
+ QVector<DataType> m_window;
+
+ QVector<DataType> m_input;
+ QVector<DataType> m_output;
+
+ FrequencySpectrum m_spectrum;
+
+#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);
+
+ /*
+ * 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);
+
+private slots:
+ void calculationComplete(const FrequencySpectrum &spectrum);
+
+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 // SPECTRUMANALYSER_H
+
diff --git a/examples/multimedia/spectrum/app/tonegenerator.cpp b/examples/multimedia/spectrum/app/tonegenerator.cpp
new file mode 100644
index 000000000..51a1de357
--- /dev/null
+++ b/examples/multimedia/spectrum/app/tonegenerator.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "spectrum.h"
+#include "utils.h"
+#include <QByteArray>
+#include <QAudioFormat>
+#include <qmath.h>
+#include <qendian.h>
+
+void generateTone(const SweptTone &tone, const QAudioFormat &format, QByteArray &buffer)
+{
+ Q_ASSERT(isPCMS16LE(format));
+
+ const int channelBytes = format.sampleSize() / 8;
+ const int sampleBytes = format.channelCount() * channelBytes;
+ int length = buffer.size();
+ const int numSamples = buffer.size() / sampleBytes;
+
+ Q_ASSERT(length % sampleBytes == 0);
+ Q_UNUSED(sampleBytes) // suppress warning in release builds
+
+ unsigned char *ptr = reinterpret_cast<unsigned char *>(buffer.data());
+
+ qreal phase = 0.0;
+
+ const qreal d = 2 * M_PI / format.sampleRate();
+
+ // We can't generate a zero-frequency sine wave
+ const qreal startFreq = tone.startFreq ? tone.startFreq : 1.0;
+
+ // Amount by which phase increases on each sample
+ qreal phaseStep = d * startFreq;
+
+ // Amount by which phaseStep increases on each sample
+ // If this is non-zero, the output is a frequency-swept tone
+ const qreal phaseStepStep = d * (tone.endFreq - startFreq) / numSamples;
+
+ while (length) {
+ const qreal x = tone.amplitude * qSin(phase);
+ const qint16 value = realToPcm(x);
+ for (int i=0; i<format.channelCount(); ++i) {
+ qToLittleEndian<qint16>(value, ptr);
+ ptr += channelBytes;
+ length -= channelBytes;
+ }
+
+ phase += phaseStep;
+ while (phase > 2 * M_PI)
+ phase -= 2 * M_PI;
+ phaseStep += phaseStepStep;
+ }
+}
diff --git a/examples/multimedia/spectrum/app/tonegenerator.h b/examples/multimedia/spectrum/app/tonegenerator.h
new file mode 100644
index 000000000..40cfc3d32
--- /dev/null
+++ b/examples/multimedia/spectrum/app/tonegenerator.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 TONEGENERATOR_H
+#define TONEGENERATOR_H
+
+#include <qglobal.h>
+#include "spectrum.h"
+
+QT_BEGIN_NAMESPACE
+class QAudioFormat;
+class QByteArray;
+QT_END_NAMESPACE
+
+/**
+ * Generate a sine wave
+ */
+void generateTone(const SweptTone &tone, const QAudioFormat &format, QByteArray &buffer);
+
+#endif // TONEGENERATOR_H
+
diff --git a/examples/multimedia/spectrum/app/tonegeneratordialog.cpp b/examples/multimedia/spectrum/app/tonegeneratordialog.cpp
new file mode 100644
index 000000000..27c9d0dba
--- /dev/null
+++ b/examples/multimedia/spectrum/app/tonegeneratordialog.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "tonegeneratordialog.h"
+#include <QComboBox>
+#include <QDialogButtonBox>
+#include <QLabel>
+#include <QPushButton>
+#include <QVBoxLayout>
+#include <QCheckBox>
+#include <QSlider>
+#include <QSpinBox>
+
+const int ToneGeneratorFreqMin = 1;
+const int ToneGeneratorFreqMax = 1000;
+const int ToneGeneratorFreqDefault = 440;
+const int ToneGeneratorAmplitudeDefault = 75;
+
+ToneGeneratorDialog::ToneGeneratorDialog(QWidget *parent)
+ : QDialog(parent)
+ , m_toneGeneratorSweepCheckBox(new QCheckBox(tr("Frequency sweep"), this))
+ , m_frequencySweepEnabled(true)
+ , m_toneGeneratorControl(new QWidget(this))
+ , m_toneGeneratorFrequencyControl(new QWidget(this))
+ , m_frequencySlider(new QSlider(Qt::Horizontal, this))
+ , m_frequencySpinBox(new QSpinBox(this))
+ , m_frequency(ToneGeneratorFreqDefault)
+ , m_amplitudeSlider(new QSlider(Qt::Horizontal, this))
+{
+ QVBoxLayout *dialogLayout = new QVBoxLayout(this);
+
+ m_toneGeneratorSweepCheckBox->setChecked(true);
+
+ // Configure tone generator controls
+ m_frequencySlider->setRange(ToneGeneratorFreqMin, ToneGeneratorFreqMax);
+ m_frequencySlider->setValue(ToneGeneratorFreqDefault);
+ m_frequencySpinBox->setRange(ToneGeneratorFreqMin, ToneGeneratorFreqMax);
+ m_frequencySpinBox->setValue(ToneGeneratorFreqDefault);
+ m_amplitudeSlider->setRange(0, 100);
+ m_amplitudeSlider->setValue(ToneGeneratorAmplitudeDefault);
+
+ // Add widgets to layout
+ QGridLayout *frequencyControlLayout = new QGridLayout;
+ QLabel *frequencyLabel = new QLabel(tr("Frequency (Hz)"), this);
+ frequencyControlLayout->addWidget(frequencyLabel, 0, 0, 2, 1);
+ frequencyControlLayout->addWidget(m_frequencySlider, 0, 1);
+ frequencyControlLayout->addWidget(m_frequencySpinBox, 1, 1);
+ m_toneGeneratorFrequencyControl->setLayout(frequencyControlLayout);
+ m_toneGeneratorFrequencyControl->setEnabled(false);
+
+ QGridLayout *toneGeneratorLayout = new QGridLayout;
+ QLabel *amplitudeLabel = new QLabel(tr("Amplitude"), this);
+ toneGeneratorLayout->addWidget(m_toneGeneratorSweepCheckBox, 0, 1);
+ toneGeneratorLayout->addWidget(m_toneGeneratorFrequencyControl, 1, 0, 1, 2);
+ toneGeneratorLayout->addWidget(amplitudeLabel, 2, 0);
+ toneGeneratorLayout->addWidget(m_amplitudeSlider, 2, 1);
+ m_toneGeneratorControl->setLayout(toneGeneratorLayout);
+ m_toneGeneratorControl->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ dialogLayout->addWidget(m_toneGeneratorControl);
+
+ // Connect
+ CHECKED_CONNECT(m_toneGeneratorSweepCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(frequencySweepEnabled(bool)));
+ CHECKED_CONNECT(m_frequencySlider, SIGNAL(valueChanged(int)),
+ m_frequencySpinBox, SLOT(setValue(int)));
+ CHECKED_CONNECT(m_frequencySpinBox, SIGNAL(valueChanged(int)),
+ m_frequencySlider, SLOT(setValue(int)));
+
+ // Add standard buttons to layout
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
+ buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ dialogLayout->addWidget(buttonBox);
+
+ // Connect standard buttons
+ CHECKED_CONNECT(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()),
+ this, SLOT(accept()));
+ CHECKED_CONNECT(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()),
+ this, SLOT(reject()));
+
+ setLayout(dialogLayout);
+}
+
+ToneGeneratorDialog::~ToneGeneratorDialog()
+{
+
+}
+
+bool ToneGeneratorDialog::isFrequencySweepEnabled() const
+{
+ return m_toneGeneratorSweepCheckBox->isChecked();
+}
+
+qreal ToneGeneratorDialog::frequency() const
+{
+ return qreal(m_frequencySlider->value());
+}
+
+qreal ToneGeneratorDialog::amplitude() const
+{
+ return qreal(m_amplitudeSlider->value()) / 100.0;
+}
+
+void ToneGeneratorDialog::frequencySweepEnabled(bool enabled)
+{
+ m_frequencySweepEnabled = enabled;
+ m_toneGeneratorFrequencyControl->setEnabled(!enabled);
+}
diff --git a/examples/multimedia/spectrum/app/tonegeneratordialog.h b/examples/multimedia/spectrum/app/tonegeneratordialog.h
new file mode 100644
index 000000000..a38a1f611
--- /dev/null
+++ b/examples/multimedia/spectrum/app/tonegeneratordialog.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 TONEGENERATORDIALOG_H
+#define TONEGENERATORDIALOG_H
+
+#include "spectrum.h"
+#include <QAudioDeviceInfo>
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+class QCheckBox;
+class QSlider;
+class QSpinBox;
+class QGridLayout;
+QT_END_NAMESPACE
+
+/**
+ * Dialog which controls the parameters of the tone generator.
+ */
+class ToneGeneratorDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit ToneGeneratorDialog(QWidget *parent = 0);
+ ~ToneGeneratorDialog();
+
+ bool isFrequencySweepEnabled() const;
+ qreal frequency() const;
+ qreal amplitude() const;
+
+private slots:
+ void frequencySweepEnabled(bool enabled);
+
+private:
+ QCheckBox *m_toneGeneratorSweepCheckBox;
+ bool m_frequencySweepEnabled;
+ QWidget *m_toneGeneratorControl;
+ QWidget *m_toneGeneratorFrequencyControl;
+ QSlider *m_frequencySlider;
+ QSpinBox *m_frequencySpinBox;
+ qreal m_frequency;
+ QSlider *m_amplitudeSlider;
+};
+
+#endif // TONEGENERATORDIALOG_H
diff --git a/examples/multimedia/spectrum/app/utils.cpp b/examples/multimedia/spectrum/app/utils.cpp
new file mode 100644
index 000000000..92e2d6d18
--- /dev/null
+++ b/examples/multimedia/spectrum/app/utils.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <QAudioFormat>
+#include "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;
+}
+
+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;
+}
diff --git a/examples/multimedia/spectrum/app/utils.h b/examples/multimedia/spectrum/app/utils.h
new file mode 100644
index 000000000..daf5fae8e
--- /dev/null
+++ b/examples/multimedia/spectrum/app/utils.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 UTILS_H
+#define UTILS_H
+
+#include <QtCore/qglobal.h>
+#include <QDebug>
+
+QT_FORWARD_DECLARE_CLASS(QAudioFormat)
+
+//-----------------------------------------------------------------------------
+// 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);
+
+// 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; };
+
+
+//-----------------------------------------------------------------------------
+// Debug output
+//-----------------------------------------------------------------------------
+
+class NullDebug
+{
+public:
+ template <typename T>
+ NullDebug& operator<<(const T&) { return *this; }
+};
+
+inline NullDebug nullDebug() { return NullDebug(); }
+
+#ifdef LOG_ENGINE
+# define ENGINE_DEBUG qDebug()
+#else
+# define ENGINE_DEBUG nullDebug()
+#endif
+
+#ifdef LOG_SPECTRUMANALYSER
+# define SPECTRUMANALYSER_DEBUG qDebug()
+#else
+# define SPECTRUMANALYSER_DEBUG nullDebug()
+#endif
+
+#ifdef LOG_WAVEFORM
+# define WAVEFORM_DEBUG qDebug()
+#else
+# define WAVEFORM_DEBUG nullDebug()
+#endif
+
+#endif // UTILS_H
diff --git a/examples/multimedia/spectrum/app/waveform.cpp b/examples/multimedia/spectrum/app/waveform.cpp
new file mode 100644
index 000000000..3b17f7855
--- /dev/null
+++ b/examples/multimedia/spectrum/app/waveform.cpp
@@ -0,0 +1,437 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 "waveform.h"
+#include "utils.h"
+#include <QPainter>
+#include <QResizeEvent>
+#include <QDebug>
+
+//#define PAINT_EVENT_TRACE
+#ifdef PAINT_EVENT_TRACE
+# define WAVEFORM_PAINT_DEBUG qDebug()
+#else
+# define WAVEFORM_PAINT_DEBUG nullDebug()
+#endif
+
+Waveform::Waveform(QWidget *parent)
+ : QWidget(parent)
+ , m_bufferPosition(0)
+ , m_bufferLength(0)
+ , m_audioPosition(0)
+ , m_active(false)
+ , m_tileLength(0)
+ , m_tileArrayStart(0)
+ , m_windowPosition(0)
+ , m_windowLength(0)
+{
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ setMinimumHeight(50);
+}
+
+Waveform::~Waveform()
+{
+ deletePixmaps();
+}
+
+void Waveform::paintEvent(QPaintEvent * /*event*/)
+{
+ QPainter painter(this);
+
+ painter.fillRect(rect(), Qt::black);
+
+ if (m_active) {
+ WAVEFORM_PAINT_DEBUG << "Waveform::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 << "Waveform::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);
+
+ QRect destRect = rect();
+ destRect.setLeft(destLeft);
+ destRect.setRight(destRight);
+
+ QRect sourceRect(QPoint(), m_pixmapSize);
+ sourceRect.setLeft(point.pixelOffset);
+ sourceRect.setRight(sourceRight);
+
+ WAVEFORM_PAINT_DEBUG << "Waveform::paintEvent" << "tileIndex" << point.index
+ << "source" << point.pixelOffset << sourceRight
+ << "dest" << destLeft << destRight;
+
+ painter.drawPixmap(destRect, *tile.pixmap, sourceRect);
+
+ destLeft = destRight;
+
+ if (point.index < m_tiles.count()) {
+ pos = tilePosition(point.index + 1);
+ WAVEFORM_PAINT_DEBUG << "Waveform::paintEvent" << "pos ->" << pos;
+ } else {
+ // Reached end of tile array
+ WAVEFORM_PAINT_DEBUG << "Waveform::paintEvent" << "reached end of tile array";
+ break;
+ }
+ } else {
+ // Passed last tile which is painted
+ WAVEFORM_PAINT_DEBUG << "Waveform::paintEvent" << "tile" << point.index << "not painted";
+ break;
+ }
+ } else {
+ // pos is past end of tile array
+ WAVEFORM_PAINT_DEBUG << "Waveform::paintEvent" << "pos" << pos << "past end of tile array";
+ break;
+ }
+ }
+
+ WAVEFORM_PAINT_DEBUG << "Waveform::paintEvent" << "final pos" << pos << "final x" << destRight;
+ }
+}
+
+void Waveform::resizeEvent(QResizeEvent *event)
+{
+ if (event->size() != event->oldSize())
+ createPixmaps(event->size());
+}
+
+void Waveform::initialize(const QAudioFormat &format, qint64 audioBufferSize, qint64 windowDurationUs)
+{
+ WAVEFORM_DEBUG << "Waveform::initialize"
+ << "audioBufferSize" << audioBufferSize
+ << "windowDurationUs" << windowDurationUs;
+
+ reset();
+
+ m_format = format;
+
+ // 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 << "Waveform::initialize"
+ << "tileLength" << m_tileLength
+ << "windowLength" << m_windowLength
+ << "nTiles" << nTiles;
+
+ m_pixmaps.fill(0, nTiles);
+ m_tiles.resize(nTiles);
+
+ createPixmaps(rect().size());
+
+ m_active = true;
+}
+
+void Waveform::reset()
+{
+ WAVEFORM_DEBUG << "Waveform::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(qint64 position, qint64 length, const QByteArray &buffer)
+{
+ WAVEFORM_DEBUG << "Waveform::bufferChanged"
+ << "audioPosition" << m_audioPosition
+ << "bufferPosition" << position
+ << "bufferLength" << length;
+ m_bufferPosition = position;
+ m_bufferLength = length;
+ m_buffer = buffer;
+ paintTiles();
+}
+
+void Waveform::audioPositionChanged(qint64 position)
+{
+ WAVEFORM_DEBUG << "Waveform::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 &widgetSize)
+{
+ m_pixmapSize = widgetSize;
+ m_pixmapSize.setWidth(qreal(widgetSize.width()) * m_tileLength / m_windowLength);
+
+ WAVEFORM_DEBUG << "Waveform::createPixmaps"
+ << "widgetSize" << widgetSize
+ << "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 << "Waveform::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)
+ 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
+{
+ Q_ASSERT(positionOffset >= 0 && positionOffset <= m_windowLength);
+ const int result = (qreal(positionOffset) / m_windowLength) * rect().width();
+ return result;
+}
+
+bool Waveform::paintTiles()
+{
+ WAVEFORM_DEBUG << "Waveform::paintTiles";
+ bool updateRequired = false;
+
+ for (int i=0; i<m_tiles.count(); ++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)
+ update();
+
+ return updateRequired;
+}
+
+void Waveform::paintTile(int index)
+{
+ const qint64 tileStart = m_tileArrayStart + index * m_tileLength;
+
+ WAVEFORM_DEBUG << "Waveform::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);
+
+ QPen pen(Qt::white);
+ 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();
+
+ const int offset = reinterpret_cast<const char*>(ptr) - m_buffer.constData();
+ Q_ASSERT(offset >= 0);
+ Q_ASSERT(offset < m_bufferLength);
+ Q_UNUSED(offset);
+
+ 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 << "Waveform::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 << "Waveform::shuffleTiles" << "tileArrayStart" << m_tileArrayStart;
+}
+
+void Waveform::resetTiles(qint64 newStartPos)
+{
+ WAVEFORM_DEBUG << "Waveform::resetTiles" << "newStartPos" << newStartPos;
+
+ QVector<Tile>::iterator i = m_tiles.begin();
+ for ( ; i != m_tiles.end(); ++i)
+ i->painted = false;
+
+ m_tileArrayStart = newStartPos;
+}
+
diff --git a/examples/multimedia/spectrum/app/waveform.h b/examples/multimedia/spectrum/app/waveform.h
new file mode 100644
index 000000000..019e86ac5
--- /dev/null
+++ b/examples/multimedia/spectrum/app/waveform.h
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 WAVEFORM_H
+#define WAVEFORM_H
+
+#include <QAudioFormat>
+#include <QPixmap>
+#include <QScopedPointer>
+#include <QWidget>
+
+/**
+ * Widget which displays 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 QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit Waveform(QWidget *parent = 0);
+ ~Waveform();
+
+ // QWidget
+ void paintEvent(QPaintEvent *event);
+ void resizeEvent(QResizeEvent *event);
+
+ void initialize(const QAudioFormat &format, qint64 audioBufferSize, qint64 windowDurationUs);
+ void reset();
+
+ void setAutoUpdatePosition(bool enabled);
+
+public slots:
+ void bufferChanged(qint64 position, qint64 length, const QByteArray &buffer);
+ void audioPositionChanged(qint64 position);
+
+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;
+
+ /*
+ * 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:
+ 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;
+};
+
+#endif // WAVEFORM_H
diff --git a/examples/multimedia/spectrum/app/wavfile.cpp b/examples/multimedia/spectrum/app/wavfile.cpp
new file mode 100644
index 000000000..dc1655c3a
--- /dev/null
+++ b/examples/multimedia/spectrum/app/wavfile.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 <qendian.h>
+#include <QVector>
+#include <QDebug>
+#include "utils.h"
+#include "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);
+ 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)) {
+
+ // 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;
+}
diff --git a/examples/multimedia/spectrum/app/wavfile.h b/examples/multimedia/spectrum/app/wavfile.h
new file mode 100644
index 000000000..977071366
--- /dev/null
+++ b/examples/multimedia/spectrum/app/wavfile.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia Plc 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 WAVFILE_H
+#define WAVFILE_H
+
+#include <QObject>
+#include <QFile>
+#include <QAudioFormat>
+
+class WavFile : public QFile
+{
+public:
+ WavFile(QObject *parent = 0);
+
+ using QFile::open;
+ bool open(const QString &fileName);
+ const QAudioFormat &fileFormat() const;
+ qint64 headerLength() const;
+
+private:
+ bool readHeader();
+
+private:
+ QAudioFormat m_fileFormat;
+ qint64 m_headerLength;
+};
+
+#endif // WAVFILE_H
diff --git a/examples/multimedia/spectrum/doc/images/spectrum-demo.png b/examples/multimedia/spectrum/doc/images/spectrum-demo.png
new file mode 100644
index 000000000..9ccb489a9
--- /dev/null
+++ b/examples/multimedia/spectrum/doc/images/spectrum-demo.png
Binary files differ
diff --git a/examples/multimedia/spectrum/doc/src/spectrum.qdoc b/examples/multimedia/spectrum/doc/src/spectrum.qdoc
new file mode 100644
index 000000000..64c6f8364
--- /dev/null
+++ b/examples/multimedia/spectrum/doc/src/spectrum.qdoc
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example spectrum
+ \title Spectrum Example
+ \ingroup audio_examples
+ \brief The Spectrum Example uses a combination multimedia APIs to process microphone input.
+
+ The Spectrum Analyzer example shows how the \l{QtMultimedia Module} can be
+ used to record and then play back an audio stream.
+
+ \image spectrum-demo.png
+
+ Because QtMultimedia allows the application to access the raw audio
+ stream, the data can either be inspected or modified by the application.
+ The Spectrum Analyzer example displays three pieces of information while
+ audio is being either captured or played back:
+
+ \list
+ \li Information about the raw audio stream, shown in the uppermost widget:
+ \list
+ \li The amount of data currently in the buffer, shown in blue
+ \li The segment of data which was most recently analysed to compute
+ the frequency spectrum, shown in green
+ \li The raw audio waveform, shown in white and scrolling from right to
+ left
+ \endlist
+ \li A representation of the frequency spectrum, shown at the lower left
+ \li The current RMS level of the audio stream, and the recent 'high
+ watermark' level, shown at the lower right
+ \endlist
+
+ Spectrum analysis is performed by calculating the Fast Fourier Transform
+ (FFT) of a segment of audio data. An open-source library,
+ \l{http://ldesoras.free.fr/prod.html}{FFTReal}, against which the
+ application is dynamically linked, is used to compute the transform.
+*/
+
+
diff --git a/examples/multimedia/spectrum/spectrum.pri b/examples/multimedia/spectrum/spectrum.pri
new file mode 100644
index 000000000..75c011311
--- /dev/null
+++ b/examples/multimedia/spectrum/spectrum.pri
@@ -0,0 +1,49 @@
+# The following macros allow certain features and debugging output
+# to be disabled / enabled at compile time.
+
+# Debug output from spectrum calculation
+DEFINES += LOG_SPECTRUMANALYSER
+
+# Debug output from waveform generation
+#DEFINES += LOG_WAVEFORM
+
+# Debug output from engine
+DEFINES += LOG_ENGINE
+
+# Dump input data to spectrum analyer, plus artefact data files
+#DEFINES += DUMP_SPECTRUMANALYSER
+
+# Dump captured audio data
+#DEFINES += DUMP_CAPTURED_AUDIO
+
+# Disable calculation of level
+#DEFINES += DISABLE_LEVEL
+
+# Disable calculation of frequency spectrum
+# If this macro is defined, the FFTReal DLL will not be built
+#DEFINES += DISABLE_FFT
+
+# Disables rendering of the waveform
+#DEFINES += DISABLE_WAVEFORM
+
+# If defined, superimpose the progress bar on the waveform
+DEFINES += SUPERIMPOSE_PROGRESS_ON_WAVEFORM
+
+# Perform spectrum analysis calculation in a separate thread
+DEFINES += SPECTRUM_ANALYSER_SEPARATE_THREAD
+
+# Suppress warnings about strncpy potentially being unsafe, emitted by MSVC
+win32: DEFINES += _CRT_SECURE_NO_WARNINGS
+
+win32 {
+ # spectrum_build_dir is defined with a leading slash so that it can
+ # be used in contexts such as
+ # ..$${spectrum_build_dir}
+ # without the result having a trailing slash where spectrum_build_dir
+ # is undefined.
+ build_pass {
+ CONFIG(release, release|debug): spectrum_build_dir = /release
+ CONFIG(debug, release|debug): spectrum_build_dir = /debug
+ }
+}
+
diff --git a/examples/multimedia/spectrum/spectrum.pro b/examples/multimedia/spectrum/spectrum.pro
new file mode 100644
index 000000000..164ab69b0
--- /dev/null
+++ b/examples/multimedia/spectrum/spectrum.pro
@@ -0,0 +1,13 @@
+include(spectrum.pri)
+
+TEMPLATE = subdirs
+
+# Ensure that library is built before application
+CONFIG += ordered
+QT += widgets
+
+!contains(DEFINES, DISABLE_FFT): SUBDIRS += 3rdparty/fftreal
+SUBDIRS += app
+
+TARGET = spectrum
+
diff --git a/examples/multimedia/video/doc/images/qmlvideo-menu.png b/examples/multimedia/video/doc/images/qmlvideo-menu.png
new file mode 100644
index 000000000..b2d773319
--- /dev/null
+++ b/examples/multimedia/video/doc/images/qmlvideo-menu.png
Binary files differ
diff --git a/examples/multimedia/video/doc/images/qmlvideo-overlay.png b/examples/multimedia/video/doc/images/qmlvideo-overlay.png
new file mode 100644
index 000000000..f5dc8390d
--- /dev/null
+++ b/examples/multimedia/video/doc/images/qmlvideo-overlay.png
Binary files differ
diff --git a/examples/multimedia/video/doc/images/qmlvideofx-camera-glow.png b/examples/multimedia/video/doc/images/qmlvideofx-camera-glow.png
new file mode 100644
index 000000000..aca874b6c
--- /dev/null
+++ b/examples/multimedia/video/doc/images/qmlvideofx-camera-glow.png
Binary files differ
diff --git a/examples/multimedia/video/doc/images/qmlvideofx-camera-magnify.png b/examples/multimedia/video/doc/images/qmlvideofx-camera-magnify.png
new file mode 100644
index 000000000..c3156ce96
--- /dev/null
+++ b/examples/multimedia/video/doc/images/qmlvideofx-camera-magnify.png
Binary files differ
diff --git a/examples/multimedia/video/doc/images/qmlvideofx-effects-menu.png b/examples/multimedia/video/doc/images/qmlvideofx-effects-menu.png
new file mode 100644
index 000000000..507fd7384
--- /dev/null
+++ b/examples/multimedia/video/doc/images/qmlvideofx-effects-menu.png
Binary files differ
diff --git a/examples/multimedia/video/doc/images/qmlvideofx-source-menu.png b/examples/multimedia/video/doc/images/qmlvideofx-source-menu.png
new file mode 100644
index 000000000..661aaa73f
--- /dev/null
+++ b/examples/multimedia/video/doc/images/qmlvideofx-source-menu.png
Binary files differ
diff --git a/examples/multimedia/video/doc/images/qmlvideofx-video-edgedetection.png b/examples/multimedia/video/doc/images/qmlvideofx-video-edgedetection.png
new file mode 100644
index 000000000..cedb314c5
--- /dev/null
+++ b/examples/multimedia/video/doc/images/qmlvideofx-video-edgedetection.png
Binary files differ
diff --git a/examples/multimedia/video/doc/images/qmlvideofx-video-pagecurl.png b/examples/multimedia/video/doc/images/qmlvideofx-video-pagecurl.png
new file mode 100644
index 000000000..5f5bdfb53
--- /dev/null
+++ b/examples/multimedia/video/doc/images/qmlvideofx-video-pagecurl.png
Binary files differ
diff --git a/examples/multimedia/video/doc/images/video-qml-paint-rate.png b/examples/multimedia/video/doc/images/video-qml-paint-rate.png
new file mode 100644
index 000000000..1519ff64e
--- /dev/null
+++ b/examples/multimedia/video/doc/images/video-qml-paint-rate.png
Binary files differ
diff --git a/examples/multimedia/video/doc/src/qmlvideo.qdoc b/examples/multimedia/video/doc/src/qmlvideo.qdoc
new file mode 100644
index 000000000..c27ca1bce
--- /dev/null
+++ b/examples/multimedia/video/doc/src/qmlvideo.qdoc
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\example video/qmlvideo
+\title QML Video Example
+\ingroup video_examples_qml
+
+\brief The QML Video Example demonstrates the various manipulations (move;
+resize; rotate; change aspect ratio) which can be applied to QML \l{VideoOutput}
+items.
+
+\section1 Overview
+
+This example demonstrates the various manipulations (move; resize; rotate;
+change aspect ratio) which can be applied to QML \l{VideoOutput} items.
+
+It also shows how native code can be combined with QML to implement more
+advanced functionality - in this case, C++ code is used to calculate the QML
+frame rate. This value is rendered in QML in a semi-transparent item
+overlaid on the video content.
+
+The following image shows the application executing the video-overlay scene,
+which creates a dummy overlay item (just a semi-transparent \l{Rectangle}),
+which moves across the \l{VideoOutput} item.
+
+\image qmlvideo-overlay.png
+
+\section1 Application structure
+
+The \l{video/qmlvideo/qml/qmlvideo/main.qml} file creates a UI which includes
+the following items:
+
+\list
+ \li Two \l{video/qmlvideo/qml/qmlvideo/Button.qml}{Button} instances, each
+ of which displays a filename, and can be used to launch a
+ \l{video/qmlvideo/qml/qmlvideo/FileBrowser.qml}{FileBrowser}
+ \li An exit \l{video/qmlvideo/qml/qmlvideo/Button.qml}{Button}
+ \li A \l{video/qmlvideo/qml/qmlvideo/SceneSelectionPanel.qml}{SceneSelectionPanel},
+ which is a flickable list displaying the available scenes
+ \li At the lower left, an item which displays the QML repainting rate - the
+ upper number is the instantaneous frame rate and the lower number is the
+ average over the past second.
+\endlist
+
+\image qmlvideo-menu.png
+
+Each scene in the flickable list is implemented in its own QML file - for
+example the video-basic scene (which just displays a static \l{VideoOutput}
+in the center of the screen) is implemented in the
+\l{video/qmlvideo/qml/qmlvideo/VideoBasic.qml}{VideoBasic.qml} file. As you
+can see from the code, this makes use of a type of inheritance: a
+\l{video/qmlvideo/qml/qmlvideo/VideoBasic.qml}{VideoBasic} item ...
+
+\quotefromfile video/qmlvideo/qml/qmlvideo/VideoBasic.qml
+\skipto import
+\printuntil /^\}/
+
+... is-a
+\l{video/qmlvideo/qml/qmlvideo/SceneBasic.qml}{SceneBasic} ...
+
+\quotefromfile video/qmlvideo/qml/qmlvideo/SceneBasic.qml
+\skipto import
+\printuntil contentType
+\dots
+\skipto Content
+\printuntil content
+\dots
+\skipto }
+\printuntil /^\}/
+
+... which is-a
+\l{video/qmlvideo/qml/qmlvideo/Scene.qml}{Scene}:
+
+\quotefromfile video/qmlvideo/qml/qmlvideo/Scene.qml
+\skipto import
+\printuntil root
+\dots
+\skipto property QtObject content
+\printuntil content
+\dots
+\skipto Button
+\printuntil /^\}/
+
+\l{video/qmlvideo/qml/qmlvideo/SceneBasic.qml}{SceneBasic} describes the
+structure and behaviour of the scene, but is agnostic of the type of content
+which will be displayed - this is abstracted by
+\l{video/qmlvideo/qml/qmlvideo/Content.qml}{Content}.
+
+This pattern allows us to define a particular use case (in this case, simply
+display a static piece of content), and then instantiate that use case for
+both video content
+(\l{video/qmlvideo/qml/qmlvideo/VideoBasic.qml}{VideoBasic}) and cameracontent
+(\l{video/qmlvideo/qml/qmlvideo/CameraBasic.qml}{CameraBasic}). This approach
+is used to implement many of the other scenes - for example, "repeatedly slide
+the content from left to right and back again" is implemented by
+\l{video/qmlvideo/qml/qmlvideo/SceneMove.qml}{SceneMove}, on which
+\l{video/qmlvideo/qml/qmlvideo/VideoMove.qml}{VideoMove} and
+\l{video/qmlvideo/qml/qmlvideo/CameraMove.qml}{CameraMove} are based.
+
+Depending on the value of the contentType property in the top-level scene
+instance, the embedded
+\l{video/qmlvideo/qml/qmlvideo/Content.qml}{Content} item creates either a
+\l{MediaPlayer} or a \l{Camera} item.
+
+\section1 Calculating and displaying QML painting rate
+
+\input examples/video-qml-paint-rate.qdocinc
+
+All that remains is to connect the afterRendering() signal of the QQuickView
+object to a JavaScript function, which will eventually call frequencyItem.notify():
+
+\quotefromfile video/qmlvideo/main.cpp
+\skipto QmlApplicationViewer
+\printuntil ;
+\dots
+\skipto QQuickItem
+\printuntil ;
+\dots
+\skipto QObject::connect
+\printuntil SLOT(qmlFramePainted()));
+
+*/
+
diff --git a/examples/multimedia/video/doc/src/qmlvideofx.qdoc b/examples/multimedia/video/doc/src/qmlvideofx.qdoc
new file mode 100644
index 000000000..f9b324087
--- /dev/null
+++ b/examples/multimedia/video/doc/src/qmlvideofx.qdoc
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\example video/qmlvideofx
+\title QML Video Shader Effects Example
+\ingroup video_examples_qml
+\ingroup camera_examples_qml
+
+\brief The QML Video Shader Effects Example shows how \l {ShaderEffect}
+can be used to apply postprocessing effects, expressed in \c GLSL, to video
+and camera viewfinder content.
+
+\section1 Overview
+
+This example shows how a \l {ShaderEffectItem} can be used to apply
+postprocessing effects, expressed in GLSL, to QML \l {VideoOutput} items.
+
+It also shows how native code can be combined with QML to implement more
+advanced functionality - in this case, C++ code is used to calculate the QML
+frame rate. This value is rendered in QML in a semi-transparent item
+overlaid on the video content.
+
+Finally, this application demonstrates the use of different top-level QML
+files to handle different physical screen sizes. On small-screen devices,
+menus are by default hidden, and only appear when summoned by a gesture.
+Large-screen devices show a more traditional layout in which menus are
+displayed around the video content pane.
+
+The following screenshots show shader effects being applied. In each case,
+the effect is implemented using a fragment shader.
+
+Here we see an edge detection algorithm being applied to a video clip
+(\l{http://orange.blender.org/}{Elephant's Dream from blender.org}).
+\image qmlvideofx-video-edgedetection.png
+
+This image shows a page curl effect, applied to the same video clip.
+\image qmlvideofx-video-pagecurl.png
+
+Here we see a 'glow' effect (edge detection plus colour quantization) being
+applied to the camera viewfinder.
+\image qmlvideofx-camera-glow.png
+
+This image shows a 'lens magnification' effect applied to the viewfinder.
+\image qmlvideofx-camera-magnify.png
+
+The application includes many more effects than the ones shown here - look
+for Effect*.qml files in the list above to see the full range.
+
+\section1 Application structure
+
+Shader effects can be applied to video or viewfinder content using
+\l{ShaderEffectItem}, as shown in the following example, which applies
+a wiggly effect to the content:
+
+\code
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+Rectangle {
+ width: 300
+ height: 300
+ color: "black"
+
+ MediaPlayer {
+ id: mediaPlayer
+ source: "test.mp4"
+ playing: true
+ }
+
+ VideoOutput {
+ id: video
+ anchors.fill: parent
+ source: mediaPlayer
+ }
+
+ ShaderEffect {
+ property variant source: ShaderEffectSource { sourceItem: video; hideSource: true }
+ property real wiggleAmount: 0.005
+ anchors.fill: video
+
+ fragmentShader: "
+ varying highp vec2 qt_TexCoord0;
+ uniform sampler2D source;
+ uniform highp float wiggleAmount;
+ void main(void)
+ {
+ highp vec2 wiggledTexCoord = qt_TexCoord0;
+ wiggledTexCoord.s += sin(4.0 * 3.141592653589 * wiggledTexCoord.t) * wiggleAmount;
+ gl_FragColor = texture2D(source, wiggledTexCoord.st);
+ }
+ "
+ }
+}
+\endcode
+
+In this application, the usage of the \l{ShaderEffect} and \l{VideoOutput}
+types is a bit more complicated, for the following reasons:
+
+\list
+ \li Each effect can be applied to either a \l{VideoOutput} or an
+ \l{Image} item, so the type of the source item must be abstracted away
+ from the effect implementation
+ \li For some effects (such as the edge detection and glow examples shown in
+ the screenshots above), the transformation is applied only to pixels to
+ the left of a dividing line - this allows the effect to be easily
+ compared with the untransformed image on the right
+ \li Most effects have one or more parameters which can be modified by the
+ user - these are controlled by sliders in the UI which are connected
+ to uniform values passed into the GLSL code
+\endlist
+
+The abstraction of source item type is achieved by the
+\l{video/qmlvideofx/qml/qmlvideofx/Content.qml}{Content}, which uses a
+\l{Loader} to create either a \l{MediaPlayer}, \l{Camera} or \l{Image}:
+
+\quotefromfile video/qmlvideofx/qml/qmlvideofx/Content.qml
+\skipto import
+\printuntil {
+\dots
+\skipto Loader {
+\printuntil }
+\dots
+\skipto function openImage
+\printuntil "ContentImage.qml"
+\skipto contentLoader.item.source
+\printuntil path
+\skipto }
+\printuntil }
+\skipto function openVideo
+\printuntil "ContentVideo.qml"
+\skipto contentLoader.item.mediaSource
+\printuntil path
+\skipto }
+\printuntil }
+\skipto function openCamera
+\printuntil "ContentCamera.qml"
+\skipto }
+\printuntil }
+\skipto /^\}/
+\printuntil }
+
+Each effect is implemented as a QML item which is based on the
+\l{video/qmlvideofx/qml/qmlvideofx/Effect.qml}{Effect}, which in turn
+is based on the \l{ShaderEffect}:
+
+\quotefromfile video/qmlvideofx/qml/qmlvideofx/Effect.qml
+\skipto import
+\printuntil /^\}/
+
+The interface of the \l Effect allows for derived effects to specify the
+number of parameters which they support (and therefore the number of sliders
+which should be displayed), and whether a vertical dividing line should be drawn
+between transformed and untransformed image regions. As an example, here is the
+implementation of the pixelation effect. As you can see, the pixelation effect
+supports one parameter (which controls the pixelation granularity), and states
+that the divider should be displayed.
+
+\quotefromfile video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml
+\skipto import
+\printuntil /^\}/
+
+The main.qml file shows a
+\l{video/qmlvideofx/qml/qmlvideofx/FileOpen.qml}{FileOpen}, which allows
+the user to select the input source and an
+\l{video/qmlvideofx/qml/qmlvideofx/EffectSelectionPanel.qml}{EffectSelectionPanel}
+item, which lists each of the available shader effects. As described above, a
+\l{video/qmlvideofx/qml/qmlvideofx/Content.qml}{Content} item is used to load the
+appropriate input and effect type. A
+\l{video/qmlvideofx/qml/qmlvideofx/Divider.qml}{Divider} item draws the
+vertical dividing line, which can be dragged left / right by the user. Finally,
+a \l{video/qmlvideofx/qml/qmlvideofx/ParameterPanel.qml}{ParameterPanel} item
+renders the sliders corresponding to each effect parameter.
+
+Here is the source selection menu:
+\image qmlvideofx-source-menu.png
+
+And here is the effect selection menu:
+\image qmlvideofx-effects-menu.png
+
+\section1 Calculating and displaying QML painting rate
+
+\input examples/video-qml-paint-rate.qdocinc
+
+All that remains is to connect the afterRendering() signal of the QQuickView
+object to a JavaScript function, which will eventually call frequencyItem.notify():
+
+\quotefromfile video/qmlvideofx/main.cpp
+\skipto QmlApplicationViewer
+\printuntil ;
+\dots
+\skipto QQuickItem
+\printuntil ;
+\dots
+\skipto QObject::connect
+\printuntil SLOT(qmlFramePainted()));
+
+*/
+
diff --git a/examples/multimedia/video/doc/src/video-qml-paint-rate.qdocinc b/examples/multimedia/video/doc/src/video-qml-paint-rate.qdocinc
new file mode 100644
index 000000000..84098e241
--- /dev/null
+++ b/examples/multimedia/video/doc/src/video-qml-paint-rate.qdocinc
@@ -0,0 +1,43 @@
+The QML painting rate is calculated by the FrequencyMonitor class, which
+turns a stream of events (received via the notify() slot), into an
+instantaneous and an averaged frequency:
+
+\quotefromfile video/snippets/frequencymonitor/frequencymonitor.h
+\skipto class FrequencyMonitor : public QObject
+\printuntil Q_OBJECT
+\skipto Q_PROPERTY(qreal instantaneousFrequency
+\printuntil averageFrequencyChanged)
+\skipto public
+\printuntil :
+\dots
+\skipto static void qmlRegisterType
+\printuntil ;
+\skipto public slots
+\printuntil notify();
+\skipto };
+\printline };
+
+The FrequencyMonitor class is exposed to QML like this
+
+\quotefromfile video/snippets/frequencymonitor/frequencymonitordeclarative.cpp
+\skipto FrequencyMonitor::qmlRegisterType
+\printuntil }
+
+and its data is displayed by defining a QML item called FrequencyItem, like this:
+
+\quotefromfile video/snippets/frequencymonitor/qml/frequencymonitor/FrequencyItem.qml
+\skipto import FrequencyMonitor
+\printuntil id: root
+\dots
+\skipto function notify
+\printuntil id: monitor
+\skipto onAverageFrequencyChanged
+\printuntil {
+\skipto averageFrequencyText
+\printuntil /^\}/
+
+The result looks like this:
+
+\image video-qml-paint-rate.png
+
+
diff --git a/examples/multimedia/video/qmlvideo/images/close.png b/examples/multimedia/video/qmlvideo/images/close.png
new file mode 100644
index 000000000..6904df0e4
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/images/close.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideo/images/folder.png b/examples/multimedia/video/qmlvideo/images/folder.png
new file mode 100644
index 000000000..e53e2ad46
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/images/folder.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideo/images/leaves.jpg b/examples/multimedia/video/qmlvideo/images/leaves.jpg
new file mode 100644
index 000000000..66533b34a
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/images/leaves.jpg
Binary files differ
diff --git a/examples/multimedia/video/qmlvideo/images/progress_handle.svg b/examples/multimedia/video/qmlvideo/images/progress_handle.svg
new file mode 100644
index 000000000..7ad9014e3
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/images/progress_handle.svg
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="10px"
+ height="46px"
+ version="1.1">
+ <g>
+ <defs>
+ <linearGradient id="MyGradient1" x1="0%" y1="0%" x2="100%" y2="100%">
+ <stop offset="0%" stop-color="lightcyan" />
+ <stop offset="100%" stop-color="dodgerblue" />
+ </linearGradient>
+ </defs>
+ <rect
+ stroke="white"
+ fill="url(#MyGradient1)"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ width="8"
+ height="44"
+ x="1"
+ y="1"
+ rx="4"
+ ry="4"/>
+ </g>
+</svg>
diff --git a/examples/multimedia/video/qmlvideo/images/progress_handle_pressed.svg b/examples/multimedia/video/qmlvideo/images/progress_handle_pressed.svg
new file mode 100644
index 000000000..c9c6c486c
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/images/progress_handle_pressed.svg
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="10px"
+ height="46px"
+ version="1.1">
+ <g>
+ <defs>
+ <linearGradient id="MyGradient1" x1="0%" y1="0%" x2="100%" y2="100%">
+ <stop offset="0%" stop-color="skyblue" />
+ <stop offset="100%" stop-color="darkblue" />
+ </linearGradient>
+ </defs>
+ <rect
+ stroke="white"
+ fill="url(#MyGradient1)"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ width="8"
+ height="44"
+ x="1"
+ y="1"
+ rx="4"
+ ry="4"/>
+ </g>
+</svg>
diff --git a/examples/multimedia/video/qmlvideo/images/titlebar.png b/examples/multimedia/video/qmlvideo/images/titlebar.png
new file mode 100644
index 000000000..51c90082d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/images/titlebar.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideo/images/titlebar.sci b/examples/multimedia/video/qmlvideo/images/titlebar.sci
new file mode 100644
index 000000000..0418d94cd
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/images/titlebar.sci
@@ -0,0 +1,5 @@
+border.left: 10
+border.top: 12
+border.bottom: 12
+border.right: 10
+source: titlebar.png
diff --git a/examples/multimedia/video/qmlvideo/images/up.png b/examples/multimedia/video/qmlvideo/images/up.png
new file mode 100644
index 000000000..b05f8025d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/images/up.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideo/main.cpp b/examples/multimedia/video/qmlvideo/main.cpp
new file mode 100644
index 000000000..149fc7a85
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/main.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QStandardPaths>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtQml/QQmlContext>
+#include <QtGui/QGuiApplication>
+#include <QtQuick/QQuickItem>
+#include "qmlapplicationviewer.h"
+#include "trace.h"
+
+#ifdef PERFORMANCEMONITOR_SUPPORT
+#include "performancemonitordeclarative.h"
+#endif
+
+static const QString DefaultFileName1 = "";
+static const QString DefaultFileName2 = "";
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+#ifdef PERFORMANCEMONITOR_SUPPORT
+ PerformanceMonitor::qmlRegisterTypes();
+#endif
+
+ QString source1, source2;
+ qreal volume = 0.5;
+ QStringList args = app.arguments();
+ PerformanceMonitor::State performanceMonitorState;
+ bool sourceIsUrl = false;
+ for (int i=1; i<args.count(); ++i) {
+ const QString &arg = args.at(i);
+ if (arg.startsWith('-')) {
+ if ("-volume" == arg) {
+ if (i+1 < args.count())
+ volume = 0.01 * args.at(++i).toInt();
+ else
+ qtTrace() << "Option \"-volume\" takes a value";
+ }
+#ifdef PERFORMANCEMONITOR_SUPPORT
+ else if (PerformanceMonitor::parseArgument(arg, performanceMonitorState)) {
+ // Do nothing
+ }
+#endif
+ else if ("-url" == arg) {
+ sourceIsUrl = true;
+ } else {
+ qtTrace() << "Option" << arg << "ignored";
+ }
+ } else {
+ if (source1.isEmpty())
+ source1 = arg;
+ else if (source2.isEmpty())
+ source2 = arg;
+ else
+ qtTrace() << "Argument" << arg << "ignored";
+ }
+ }
+
+ QUrl url1, url2;
+ if (sourceIsUrl) {
+ url1 = source1;
+ url2 = source2;
+ } else {
+ if (!source1.isEmpty())
+ url1 = QUrl::fromLocalFile(source1);
+ if (!source2.isEmpty())
+ url2 = QUrl::fromLocalFile(source2);
+ }
+
+ QmlApplicationViewer viewer;
+
+ viewer.requestOrientation(Qt::LandscapeOrientation);
+ viewer.setMainQmlFile(QLatin1String("qml/qmlvideo/main.qml"));
+ QQuickItem *rootObject = viewer.rootObject();
+ rootObject->setProperty("source1", url1);
+ rootObject->setProperty("source2", url2);
+ rootObject->setProperty("volume", volume);
+
+#ifdef PERFORMANCEMONITOR_SUPPORT
+ if (performanceMonitorState.valid) {
+ rootObject->setProperty("perfMonitorsLogging", performanceMonitorState.logging);
+ rootObject->setProperty("perfMonitorsVisible", performanceMonitorState.visible);
+ }
+ QObject::connect(&viewer, SIGNAL(afterRendering()),
+ rootObject, SLOT(qmlFramePainted()));
+#endif
+
+ QString videoPath;
+ const QStringList moviesLocation = QStandardPaths::standardLocations(QStandardPaths::MoviesLocation);
+ if (!moviesLocation.isEmpty())
+ videoPath = moviesLocation.first();
+ viewer.rootContext()->setContextProperty("videoPath", videoPath);
+
+ QMetaObject::invokeMethod(rootObject, "init");
+
+ viewer.showExpanded();
+
+ return app.exec();
+}
+
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/Button.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/Button.qml
new file mode 100644
index 000000000..f3814b860
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/Button.qml
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ color: textColor
+ radius: 0.25 * height
+
+ property string text
+ property color bgColor: "white"
+ property color bgColorSelected: "red"
+ property color textColor: "black"
+ property alias enabled: mouseArea.enabled
+
+ signal clicked
+
+ Rectangle {
+ anchors { fill: parent; margins: 1 }
+ color: mouseArea.pressed ? bgColorSelected : bgColor
+ radius: 0.25 * height
+
+ Text {
+ id: text
+ anchors.centerIn: parent
+ text: root.text
+ font.pixelSize: 0.5 * parent.height
+ color: mouseArea.pressed ? bgColor : textColor
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked: {
+ root.clicked()
+ }
+ }
+ }
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraBasic.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraBasic.qml
new file mode 100644
index 000000000..bf7cf16a7
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraBasic.qml
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneBasic {
+ contentType: "camera"
+ started: true
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraDrag.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraDrag.qml
new file mode 100644
index 000000000..05cd1b232
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraDrag.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneDrag {
+ contentType: "camera"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraDummy.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraDummy.qml
new file mode 100644
index 000000000..8895f7ac1
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraDummy.qml
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+// Item which is loaded by CameraItem if QtMultimediaKit is not available
+Rectangle {
+ id: root
+ color: "grey"
+ height: width
+
+ signal fatalError
+ signal sizeChanged
+ signal framePainted
+
+ Text {
+ anchors.fill: parent
+ anchors.margins: 10
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ text: "Failed to create Camera item\n\nCheck that QtMultimediaKit is installed"
+ verticalAlignment: Text.AlignVCenter
+ wrapMode: Text.Wrap
+ }
+
+ onWidthChanged: height = width
+ onHeightChanged: root.sizeChanged()
+
+ function start() { }
+ function stop() { }
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraFullScreen.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraFullScreen.qml
new file mode 100644
index 000000000..6b69d1804
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraFullScreen.qml
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneFullScreen {
+ contentType: "camera"
+}
+
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraFullScreenInverted.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraFullScreenInverted.qml
new file mode 100644
index 000000000..519809faf
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraFullScreenInverted.qml
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneFullScreenInverted {
+ contentType: "camera"
+}
+
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraItem.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraItem.qml
new file mode 100644
index 000000000..775f65f12
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraItem.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+VideoOutput {
+ id: root
+ height: width
+ source: camera
+
+ signal fatalError
+ signal sizeChanged
+
+ onHeightChanged: root.sizeChanged()
+
+ Camera {
+ id: camera
+
+ onError: {
+ if (Camera.NoError != error) {
+ console.log("[qmlvideo] CameraItem.onError error " + error + " errorString " + errorString)
+ root.fatalError()
+ }
+ }
+ }
+
+ function start() { camera.start() }
+ function stop() { camera.stop() }
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraMove.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraMove.qml
new file mode 100644
index 000000000..14a418bc9
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraMove.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneMove {
+ contentType: "camera"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraOverlay.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraOverlay.qml
new file mode 100644
index 000000000..5a055de9b
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraOverlay.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneOverlay {
+ contentType: "camera"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraResize.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraResize.qml
new file mode 100644
index 000000000..61758764b
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraResize.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneResize {
+ contentType: "camera"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraRotate.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraRotate.qml
new file mode 100644
index 000000000..a18bf6d10
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraRotate.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneRotate {
+ contentType: "camera"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraSpin.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraSpin.qml
new file mode 100644
index 000000000..2c8b1f720
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/CameraSpin.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneSpin {
+ contentType: "camera"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/Content.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/Content.qml
new file mode 100644
index 000000000..dc1079bf7
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/Content.qml
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ border.color: "white"
+ border.width: showBorder ? 1 : 0
+ color: "transparent"
+ property string contentType // "camera" or "video"
+ property string source
+ property real volume
+ property bool dummy: false
+ property bool autoStart: true
+ property bool started: false
+ property bool showFrameRate: false
+ property bool showBorder: false
+
+ signal initialized
+ signal error
+ signal videoFramePainted
+
+ Loader {
+ id: contentLoader
+ }
+
+ Connections {
+ id: framePaintedConnection
+ onFramePainted: {
+ if (frameRateLoader.item)
+ frameRateLoader.item.notify()
+ root.videoFramePainted()
+ }
+ ignoreUnknownSignals: true
+ }
+
+ Connections {
+ id: errorConnection
+ onFatalError: {
+ console.log("[qmlvideo] Content.onFatalError")
+ stop()
+ root.error()
+ }
+ ignoreUnknownSignals: true
+ }
+
+ Loader {
+ id: frameRateLoader
+ source: root.showFrameRate ? "../frequencymonitor/FrequencyItem.qml" : ""
+ onLoaded: {
+ item.parent = root
+ item.anchors.top = root.top
+ item.anchors.right = root.right
+ item.anchors.margins = 10
+ }
+ }
+
+ onWidthChanged: {
+ if (contentItem())
+ contentItem().width = width
+ }
+
+ onHeightChanged: {
+ if (contentItem())
+ contentItem().height = height
+ }
+
+ function initialize() {
+ console.log("[qmlvideo] Content.initialize: contentType " + contentType)
+ if ("video" == contentType) {
+ console.log("[qmlvideo] Content.initialize: loading VideoItem.qml")
+ contentLoader.source = "VideoItem.qml"
+ if (Loader.Error == contentLoader.status) {
+ console.log("[qmlvideo] Content.initialize: loading VideoDummy.qml")
+ contentLoader.source = "VideoDummy.qml"
+ dummy = true
+ }
+ contentLoader.item.volume = volume
+ } else if ("camera" == contentType) {
+ console.log("[qmlvideo] Content.initialize: loading CameraItem.qml")
+ contentLoader.source = "CameraItem.qml"
+ if (Loader.Error == contentLoader.status) {
+ console.log("[qmlvideo] Content.initialize: loading CameraDummy.qml")
+ contentLoader.source = "CameraDummy.qml"
+ dummy = true
+ }
+ } else {
+ console.log("[qmlvideo] Content.initialize: error: invalid contentType")
+ }
+ if (contentLoader.item) {
+ contentLoader.item.sizeChanged.connect(updateRootSize)
+ contentLoader.item.parent = root
+ contentLoader.item.width = root.width
+ framePaintedConnection.target = contentLoader.item
+ errorConnection.target = contentLoader.item
+ if (root.autoStart)
+ root.start()
+ }
+ console.log("[qmlvideo] Content.initialize: complete")
+ root.initialized()
+ }
+
+ function start() {
+ console.log("[qmlvideo] Content.start")
+ if (contentLoader.item) {
+ if (root.contentType == "video")
+ contentLoader.item.mediaSource = root.source
+ contentLoader.item.start()
+ root.started = true
+ }
+ }
+
+ function stop() {
+ console.log("[qmlvideo] Content.stop")
+ if (contentLoader.item) {
+ contentLoader.item.stop()
+ if (root.contentType == "video")
+ contentLoader.item.mediaSource = ""
+ root.started = false
+ }
+ }
+
+ function contentItem() { return contentLoader.item }
+ function updateRootSize() { root.height = contentItem().height }
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml
new file mode 100644
index 000000000..2325870ba
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtSystemInfo 5.0
+
+Item {
+ ScreenSaver {
+ screenSaverInhibited: true
+ }
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/ErrorDialog.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/ErrorDialog.qml
new file mode 100644
index 000000000..dfe6b4584
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/ErrorDialog.qml
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ color: "transparent"
+ opacity: 0.0
+ property alias enabled: mouseArea.enabled
+ state: enabled ? "on" : "baseState"
+
+ states: [
+ State {
+ name: "on"
+ PropertyChanges {
+ target: root
+ opacity: 1.0
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "*"
+ to: "*"
+ NumberAnimation {
+ properties: "opacity"
+ easing.type: Easing.OutQuart
+ duration: 500
+ }
+ }
+ ]
+
+ Rectangle {
+ anchors.fill: parent
+ color: "black"
+ opacity: 0.75
+ }
+
+ Rectangle {
+ anchors.centerIn: parent
+ width: 300
+ height: 200
+ radius: 10
+ color: "white"
+
+ Text {
+ id: text
+ anchors.fill: parent
+ anchors.margins: 10
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ color: "black"
+ wrapMode: Text.WordWrap
+ }
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked: root.enabled = false
+ }
+
+ function show(msg) {
+ text.text = "<b>Error</b><br><br>" + msg
+ root.enabled = true
+ }
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/FileBrowser.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/FileBrowser.qml
new file mode 100644
index 000000000..dd4cf5908
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/FileBrowser.qml
@@ -0,0 +1,383 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import Qt.labs.folderlistmodel 2.0
+
+Rectangle {
+ id: fileBrowser
+ color: "transparent"
+
+ property string folder
+
+ signal fileSelected(string file)
+
+ function selectFile(file) {
+ if (file != "")
+ folder = loader.item.folders.folder
+ loader.sourceComponent = undefined
+ fileBrowser.fileSelected(file)
+ }
+
+ Loader {
+ id: loader
+ }
+
+ function show() {
+ loader.sourceComponent = fileBrowserComponent
+ loader.item.parent = fileBrowser
+ loader.item.anchors.fill = fileBrowser
+ loader.item.folder = fileBrowser.folder
+ }
+
+ Component {
+ id: fileBrowserComponent
+
+ Rectangle {
+ id: root
+ color: "white"
+ property bool showFocusHighlight: false
+ property variant folders: folders1
+ property variant view: view1
+ property alias folder: folders1.folder
+ property color textColor: "black"
+
+ FolderListModel {
+ id: folders1
+ folder: folder
+ }
+
+ FolderListModel {
+ id: folders2
+ folder: folder
+ }
+
+ SystemPalette {
+ id: palette
+ }
+
+ Component {
+ id: folderDelegate
+
+ Rectangle {
+ id: wrapper
+ function launch() {
+ if (folders.isFolder(index))
+ down(filePath);
+ else
+ fileBrowser.selectFile(filePath)
+ }
+ width: root.width
+ height: 52
+ color: "transparent"
+
+ Rectangle {
+ id: highlight; visible: false
+ anchors.fill: parent
+ color: palette.highlight
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ }
+
+ Item {
+ width: 48; height: 48
+ Image {
+ source: "qrc:/images/folder.png"
+ anchors.centerIn: parent
+ visible: folders.isFolder(index)
+ }
+ }
+
+ Text {
+ id: nameText
+ anchors.fill: parent; verticalAlignment: Text.AlignVCenter
+ text: fileName
+ anchors.leftMargin: 54
+ font.pixelSize: 32
+ color: (wrapper.ListView.isCurrentItem && root.showFocusHighlight) ? palette.highlightedText : textColor
+ elide: Text.ElideRight
+ }
+
+ MouseArea {
+ id: mouseRegion
+ anchors.fill: parent
+ onPressed: {
+ root.showFocusHighlight = false;
+ wrapper.ListView.view.currentIndex = index;
+ }
+ onClicked: { if (folders == wrapper.ListView.view.model) launch() }
+ }
+
+ states: [
+ State {
+ name: "pressed"
+ when: mouseRegion.pressed
+ PropertyChanges { target: highlight; visible: true }
+ PropertyChanges { target: nameText; color: palette.highlightedText }
+ }
+ ]
+ }
+ }
+
+ Rectangle {
+ id: cancelButton
+ width: 100
+ height: titleBar.height - 7
+ color: "black"
+ anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter }
+
+ Text {
+ anchors { fill: parent; margins: 4 }
+ text: "Cancel"
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.pixelSize: 20
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: fileBrowser.selectFile("")
+ }
+ }
+
+ ListView {
+ id: view1
+ anchors.top: titleBar.bottom
+ anchors.bottom: cancelButton.top
+ x: 0
+ width: parent.width
+ model: folders1
+ delegate: folderDelegate
+ highlight: Rectangle {
+ color: palette.highlight
+ visible: root.showFocusHighlight && view1.count != 0
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ width: view1.currentItem == null ? 0 : view1.currentItem.width
+ }
+ highlightMoveVelocity: 1000
+ pressDelay: 100
+ focus: true
+ state: "current"
+ states: [
+ State {
+ name: "current"
+ PropertyChanges { target: view1; x: 0 }
+ },
+ State {
+ name: "exitLeft"
+ PropertyChanges { target: view1; x: -root.width }
+ },
+ State {
+ name: "exitRight"
+ PropertyChanges { target: view1; x: root.width }
+ }
+ ]
+ transitions: [
+ Transition {
+ to: "current"
+ SequentialAnimation {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ },
+ Transition {
+ NumberAnimation { properties: "x"; duration: 250 }
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ ]
+ Keys.onPressed: root.keyPressed(event.key)
+ }
+
+ ListView {
+ id: view2
+ anchors.top: titleBar.bottom
+ anchors.bottom: parent.bottom
+ x: parent.width
+ width: parent.width
+ model: folders2
+ delegate: folderDelegate
+ highlight: Rectangle {
+ color: palette.highlight
+ visible: root.showFocusHighlight && view2.count != 0
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ width: view1.currentItem == null ? 0 : view1.currentItem.width
+ }
+ highlightMoveVelocity: 1000
+ pressDelay: 100
+ states: [
+ State {
+ name: "current"
+ PropertyChanges { target: view2; x: 0 }
+ },
+ State {
+ name: "exitLeft"
+ PropertyChanges { target: view2; x: -root.width }
+ },
+ State {
+ name: "exitRight"
+ PropertyChanges { target: view2; x: root.width }
+ }
+ ]
+ transitions: [
+ Transition {
+ to: "current"
+ SequentialAnimation {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ },
+ Transition {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ ]
+ Keys.onPressed: root.keyPressed(event.key)
+ }
+
+ Keys.onPressed: {
+ root.keyPressed(event.key);
+ if (event.key == Qt.Key_Return || event.key == Qt.Key_Select || event.key == Qt.Key_Right) {
+ view.currentItem.launch();
+ event.accepted = true;
+ } else if (event.key == Qt.Key_Left) {
+ up();
+ }
+ }
+
+ BorderImage {
+ source: "qrc:/images/titlebar.sci";
+ width: parent.width;
+ height: 52
+ y: -7
+ id: titleBar
+
+ Rectangle {
+ id: upButton
+ width: 48
+ height: titleBar.height - 7
+ color: "transparent"
+ Image { anchors.centerIn: parent; source: "qrc:/images/up.png" }
+ MouseArea { id: upRegion; anchors.centerIn: parent
+ width: 56
+ height: 56
+ onClicked: if (folders.parentFolder != "") up()
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: upRegion.pressed
+ PropertyChanges { target: upButton; color: palette.highlight }
+ }
+ ]
+ }
+
+ Rectangle {
+ color: "gray"
+ x: 48
+ width: 1
+ height: 44
+ }
+
+ Text {
+ anchors.left: upButton.right; anchors.right: parent.right; height: parent.height
+ anchors.leftMargin: 4; anchors.rightMargin: 4
+ text: folders.folder
+ color: "white"
+ elide: Text.ElideLeft; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
+ font.pixelSize: 32
+ }
+ }
+
+ function down(path) {
+ if (folders == folders1) {
+ view = view2
+ folders = folders2;
+ view1.state = "exitLeft";
+ } else {
+ view = view1
+ folders = folders1;
+ view2.state = "exitLeft";
+ }
+ view.x = root.width;
+ view.state = "current";
+ view.focus = true;
+ folders.folder = path;
+ }
+
+ function up() {
+ var path = folders.parentFolder;
+ if (folders == folders1) {
+ view = view2
+ folders = folders2;
+ view1.state = "exitRight";
+ } else {
+ view = view1
+ folders = folders1;
+ view2.state = "exitRight";
+ }
+ view.x = -root.width;
+ view.state = "current";
+ view.focus = true;
+ folders.folder = path;
+ }
+
+ function keyPressed(key) {
+ switch (key) {
+ case Qt.Key_Up:
+ case Qt.Key_Down:
+ case Qt.Key_Left:
+ case Qt.Key_Right:
+ root.showFocusHighlight = true;
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/Scene.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/Scene.qml
new file mode 100644
index 000000000..903608346
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/Scene.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ color: "black"
+ property alias buttonHeight: closeButton.height
+ property string source1
+ property string source2
+ property int contentWidth: 250
+ property real volume: 0.25
+ property int margins: 10
+ property QtObject content
+
+ signal close
+ signal videoFramePainted
+
+ Button {
+ id: closeButton
+ anchors {
+ top: parent.top
+ right: parent.right
+ margins: root.margins
+ }
+ width: 50
+ height: 30
+ z: 2.0
+ text: "Back"
+ onClicked: root.close()
+ }
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml
new file mode 100644
index 000000000..afec90392
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneBasic.qml
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+ property string contentType
+ property bool autoStart: false
+ property bool started: false
+
+ Content {
+ id: content
+ autoStart: parent.autoStart
+ started: parent.started
+ anchors.centerIn: parent
+ width: parent.contentWidth
+ contentType: parent.contentType
+ source: parent.source1
+ volume: parent.volume
+ onVideoFramePainted: root.videoFramePainted()
+ }
+
+ Text {
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ bottom: parent.bottom
+ margins: 20
+ }
+ text: content.started ? "Tap the screen to stop content"
+ : "Tap the screen to start content"
+ color: "yellow"
+ font.pixelSize: 20
+ z: 2.0
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ console.log("[qmlvideo] SceneBasic.onClicked, started = " + content.started)
+ if (content.started)
+ content.stop()
+ else
+ content.start()
+ }
+ }
+
+ Component.onCompleted: root.content = content
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneDrag.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneDrag.qml
new file mode 100644
index 000000000..a559ce12a
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneDrag.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+ property int margin: 20
+ property string contentType
+
+ Image {
+ id: background
+ source: "qrc:/images/leaves.jpg"
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+
+ Content {
+ id: content
+ anchors.centerIn: parent
+ width: root.contentWidth
+ contentType: root.contentType
+ source: root.source1
+ volume: root.volume
+ onVideoFramePainted: root.videoFramePainted()
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ drag.target: background
+ }
+
+ Component.onCompleted: root.content = content
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreen.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreen.qml
new file mode 100644
index 000000000..3a94255ad
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreen.qml
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+ property string contentType
+
+ Content {
+ id: content
+ anchors.centerIn: parent
+ width: parent.contentWidth
+ contentType: root.contentType
+ source: parent.source1
+ volume: parent.volume
+ state: "left"
+
+ states: [
+ State {
+ name: "fullScreen"
+ PropertyChanges { target: content; width: content.parent.width }
+ PropertyChanges { target: content; height: content.parent.height }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ ParallelAnimation {
+ PropertyAnimation {
+ property: "width"
+ easing.type: Easing.Linear
+ duration: 250
+ }
+ PropertyAnimation {
+ property: "height"
+ easing.type: Easing.Linear
+ duration: 250
+ }
+ }
+ }
+ ]
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: content.state = (content.state == "fullScreen") ? "baseState" : "fullScreen"
+ }
+
+ onVideoFramePainted: root.videoFramePainted()
+ }
+
+ Text {
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ bottom: parent.bottom
+ margins: 20
+ }
+ text: "Tap on the content to toggle full-screen mode"
+ color: "yellow"
+ font.pixelSize: 20
+ z: 2.0
+ }
+
+ Component.onCompleted: root.content = content
+}
+
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreenInverted.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreenInverted.qml
new file mode 100644
index 000000000..c87d6767d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneFullScreenInverted.qml
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+ property string contentType
+
+ Content {
+ id: content
+ anchors.centerIn: parent
+ width: parent.width
+ height: parent.height
+ contentType: root.contentType
+ source: parent.source1
+ volume: parent.volume
+ state: "left"
+
+ states: [
+ State {
+ name: "nonFullScreen"
+ PropertyChanges { target: content; width: content.parent.contentWidth }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ ParallelAnimation {
+ PropertyAnimation {
+ property: "width"
+ easing.type: Easing.Linear
+ duration: 250
+ }
+ PropertyAnimation {
+ property: "height"
+ easing.type: Easing.Linear
+ duration: 250
+ }
+ }
+ }
+ ]
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: content.state = (content.state == "nonFullScreen") ? "baseState" : "nonFullScreen"
+ }
+
+ onVideoFramePainted: root.videoFramePainted()
+
+ onInitialized: {
+ width = parent.width
+ height = parent.height
+ }
+ }
+
+ Text {
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ bottom: parent.bottom
+ margins: 20
+ }
+ text: "Tap on the content to toggle full-screen mode"
+ color: "yellow"
+ font.pixelSize: 20
+ z: 2.0
+ }
+
+ Component.onCompleted: root.content = content
+}
+
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMove.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMove.qml
new file mode 100644
index 000000000..6a91c770b
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMove.qml
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+ property int margin: 20
+ property string contentType
+
+ Content {
+ id: content
+ anchors.verticalCenter: parent.verticalCenter
+ width: parent.contentWidth
+ contentType: root.contentType
+ source: parent.source1
+ volume: parent.volume
+
+ SequentialAnimation on x {
+ id: animation
+ loops: Animation.Infinite
+ property int from: margin
+ property int to: 100
+ property int duration: 1500
+ running: false
+ PropertyAnimation {
+ from: animation.from
+ to: animation.to
+ duration: animation.duration
+ easing.type: Easing.InOutCubic
+ }
+ PropertyAnimation {
+ from: animation.to
+ to: animation.from
+ duration: animation.duration
+ easing.type: Easing.InOutCubic
+ }
+ }
+
+ onVideoFramePainted: root.videoFramePainted()
+ }
+
+ onWidthChanged: {
+ animation.to = root.width - content.width - margin
+ animation.start()
+ }
+
+ Component.onCompleted: root.content = content
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMulti.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMulti.qml
new file mode 100644
index 000000000..0895cb5b2
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneMulti.qml
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+
+ property real itemWidth: (width / 3) - 40
+ property real itemTopMargin: 50
+
+ QtObject {
+ id: contentProxy
+ function initialize() {
+ video1.initialize()
+ video2.initialize()
+ }
+ }
+
+ Component {
+ id: startStopComponent
+
+ Rectangle {
+ id: root
+ color: "transparent"
+
+ function content() {
+ return root.parent
+ }
+
+ Text {
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ bottom: parent.bottom
+ margins: 20
+ }
+ text: content() ? content().started ? "Tap to stop" : "Tap to start" : ""
+ color: "yellow"
+ font.pixelSize: 20
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (content().started)
+ content().stop()
+ else
+ content().start()
+ }
+ }
+ }
+ }
+
+ Content {
+ id: video1
+ anchors {
+ left: parent.left
+ leftMargin: 10
+ top: parent.top
+ topMargin: root.itemTopMargin
+ }
+ autoStart: false
+ contentType: "video"
+ showBorder: true
+ showFrameRate: started
+ source: parent.source1
+ width: itemWidth
+ volume: parent.volume
+
+ Loader {
+ id: video1StartStopLoader
+ onLoaded: {
+ item.parent = video1
+ item.anchors.fill = video1
+ }
+ }
+
+ onInitialized: video1StartStopLoader.sourceComponent = startStopComponent
+ }
+
+ Rectangle {
+ id: cameraHolder
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ top: parent.top
+ topMargin: root.itemTopMargin
+ }
+ border.width: 1
+ border.color: "white"
+ color: "transparent"
+ width: itemWidth
+ height: width
+ property bool started: false
+
+ Loader {
+ id: cameraLoader
+ onLoaded: {
+ item.parent = cameraHolder
+ item.centerIn = cameraHolder
+ item.contentType = "camera"
+ item.showFrameRate = true
+ item.width = itemWidth
+ item.z = 1.0
+ cameraErrorConnection.target = item
+ item.initialize()
+ }
+ }
+
+ Loader {
+ id: cameraStartStopLoader
+ sourceComponent: startStopComponent
+ onLoaded: {
+ item.parent = cameraHolder
+ item.anchors.fill = cameraHolder
+ item.z = 2.0
+ }
+ }
+
+ Connections {
+ id: cameraErrorConnection
+ onError: {
+ console.log("[qmlvideo] SceneMulti.camera.onError")
+ cameraHolder.stop()
+ }
+ }
+
+ function start() {
+ cameraLoader.source = "Content.qml"
+ cameraHolder.started = true
+ }
+
+ function stop() {
+ cameraLoader.source = ""
+ cameraHolder.started = false
+ }
+ }
+
+ Content {
+ id: video2
+ anchors {
+ right: parent.right
+ rightMargin: 10
+ top: parent.top
+ topMargin: root.itemTopMargin
+ }
+ autoStart: false
+ contentType: "video"
+ showBorder: true
+ showFrameRate: started
+ source: parent.source2
+ width: itemWidth
+ volume: parent.volume
+
+ Loader {
+ id: video2StartStopLoader
+ onLoaded: {
+ item.parent = video2
+ item.anchors.fill = video2
+ }
+ }
+
+ onInitialized: video2StartStopLoader.sourceComponent = startStopComponent
+ }
+
+ Component.onCompleted: root.content = contentProxy
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneOverlay.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneOverlay.qml
new file mode 100644
index 000000000..d1c09270d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneOverlay.qml
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+ property int margin: 20
+ property string contentType
+
+ Content {
+ id: content
+ anchors.centerIn: parent
+ width: parent.contentWidth
+ contentType: root.contentType
+ source: parent.source1
+ volume: parent.volume
+ onVideoFramePainted: root.videoFramePainted()
+ }
+
+ Rectangle {
+ id: overlay
+ y: 0.5 * parent.height
+ width: content.width
+ height: content.height
+ color: "yellow"
+ opacity: 0.5
+
+ SequentialAnimation on x {
+ id: xAnimation
+ loops: Animation.Infinite
+ property int from: margin
+ property int to: 100
+ property int duration: 1500
+ running: false
+ PropertyAnimation {
+ from: xAnimation.from
+ to: xAnimation.to
+ duration: xAnimation.duration
+ easing.type: Easing.InOutCubic
+ }
+ PropertyAnimation {
+ from: xAnimation.to
+ to: xAnimation.from
+ duration: xAnimation.duration
+ easing.type: Easing.InOutCubic
+ }
+ }
+
+ SequentialAnimation on y {
+ id: yAnimation
+ loops: Animation.Infinite
+ property int from: margin
+ property int to: 180
+ property int duration: 1500
+ running: false
+ PropertyAnimation {
+ from: yAnimation.from
+ to: yAnimation.to
+ duration: yAnimation.duration
+ easing.type: Easing.InOutCubic
+ }
+ PropertyAnimation {
+ from: yAnimation.to
+ to: yAnimation.from
+ duration: yAnimation.duration
+ easing.type: Easing.InOutCubic
+ }
+ }
+ }
+
+ onWidthChanged: {
+ xAnimation.to = root.width - content.width - margin
+ xAnimation.start()
+ }
+
+ onHeightChanged: {
+ //yAnimation.to = root.height - content.height - margin
+ yAnimation.start()
+ }
+
+ Component.onCompleted: root.content = content
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneResize.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneResize.qml
new file mode 100644
index 000000000..690dcfcd0
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneResize.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+ property string contentType
+
+ Content {
+ id: content
+ anchors.centerIn: parent
+ width: parent.contentWidth
+ contentType: root.contentType
+ source: parent.source1
+ volume: parent.volume
+
+ SequentialAnimation on scale {
+ id: animation
+ loops: Animation.Infinite
+ property int duration: 1500
+ running: true
+ PropertyAnimation {
+ from: 1.5
+ to: 0.5
+ duration: animation.duration
+ easing.type: Easing.InOutCubic
+ }
+ PropertyAnimation {
+ from: 0.5
+ to: 1.5
+ duration: animation.duration
+ easing.type: Easing.InOutCubic
+ }
+ }
+
+ onVideoFramePainted: root.videoFramePainted()
+ }
+
+ Component.onCompleted: root.content = content
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneRotate.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneRotate.qml
new file mode 100644
index 000000000..a9d39217d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneRotate.qml
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+ property int margin: 20
+ property int delta: 30
+ property string contentType
+
+ Content {
+ id: content
+ anchors.centerIn: parent
+ width: parent.contentWidth
+ contentType: root.contentType
+ source: parent.source1
+ volume: parent.volume
+ onVideoFramePainted: root.videoFramePainted()
+ }
+
+ Button {
+ id: rotatePositiveButton
+ anchors {
+ right: parent.right
+ bottom: rotateNegativeButton.top
+ margins: parent.margins
+ }
+ width: 90
+ height: root.buttonHeight
+ text: "Rotate +" + delta
+ onClicked: content.rotation = content.rotation + delta
+ }
+
+ Button {
+ id: rotateNegativeButton
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ margins: parent.margins
+ }
+ width: 90
+ height: root.buttonHeight
+ text: "Rotate -" + delta
+ onClicked: content.rotation = content.rotation - delta
+ }
+
+ Button {
+ id: rotateValueButton
+ anchors {
+ left: parent.left
+ verticalCenter: parent.verticalCenter
+ margins: parent.margins
+ }
+ width: 30
+ height: root.buttonHeight
+ enabled: false
+ text: content.rotation % 360
+ }
+
+ Component.onCompleted: root.content = content
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSelectionPanel.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSelectionPanel.qml
new file mode 100644
index 000000000..6ec93dd85
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSelectionPanel.qml
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ property int itemHeight: 25
+ property string sceneSource: ""
+
+ ListModel {
+ id: list
+ ListElement { name: "multi"; source: "SceneMulti.qml" }
+ ListElement { name: "video"; source: "VideoBasic.qml" }
+ ListElement { name: "video-drag"; source: "VideoDrag.qml" }
+ ListElement { name: "video-fillmode"; source: "VideoFillMode.qml" }
+ ListElement { name: "video-fullscreen"; source: "VideoFullScreen.qml" }
+ ListElement { name: "video-fullscreen-inverted"; source: "VideoFullScreenInverted.qml" }
+ ListElement { name: "video-metadata"; source: "VideoMetadata.qml" }
+ ListElement { name: "video-move"; source: "VideoMove.qml" }
+ ListElement { name: "video-overlay"; source: "VideoOverlay.qml" }
+ ListElement { name: "video-playbackrate"; source: "VideoPlaybackRate.qml" }
+ ListElement { name: "video-resize"; source: "VideoResize.qml" }
+ ListElement { name: "video-rotate"; source: "VideoRotate.qml" }
+ ListElement { name: "video-spin"; source: "VideoSpin.qml" }
+ ListElement { name: "video-seek"; source: "VideoSeek.qml" }
+ ListElement { name: "camera"; source: "CameraBasic.qml" }
+ ListElement { name: "camera-drag"; source: "CameraDrag.qml" }
+ ListElement { name: "camera-fullscreen"; source: "CameraFullScreen.qml" }
+ ListElement { name: "camera-fullscreen-inverted"; source: "CameraFullScreenInverted.qml" }
+ ListElement { name: "camera-move"; source: "CameraMove.qml" }
+ ListElement { name: "camera-overlay"; source: "CameraOverlay.qml" }
+ ListElement { name: "camera-resize"; source: "CameraResize.qml" }
+ ListElement { name: "camera-rotate"; source: "CameraRotate.qml" }
+ ListElement { name: "camera-spin"; source: "CameraSpin.qml" }
+ }
+
+ Component {
+ id: delegate
+ Item {
+ id: delegateItem
+ width: root.width
+ height: itemHeight
+
+ Button {
+ id: selectorItem
+ anchors.centerIn: parent
+ width: 0.9 * parent.width
+ height: 0.8 * itemHeight
+ text: name
+ onClicked: root.sceneSource = source
+ }
+ }
+ }
+
+ Flickable {
+ anchors.fill: parent
+ contentHeight: (itemHeight * list.count) + layout.anchors.topMargin + layout.spacing
+ clip: true
+
+ Column {
+ id: layout
+
+ anchors {
+ fill: parent
+ topMargin: 10
+ }
+
+ Repeater {
+ model: list
+ delegate: delegate
+ }
+ }
+ }
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSpin.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSpin.qml
new file mode 100644
index 000000000..b8a1804c8
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SceneSpin.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+ property int margin: 20
+ property string contentType
+
+ Content {
+ id: content
+ anchors.centerIn: parent
+ width: parent.contentWidth
+ contentType: root.contentType
+ source: parent.source1
+ volume: parent.volume
+
+ PropertyAnimation on rotation {
+ id: animation
+ loops: Animation.Infinite
+ running: true
+ from: 0
+ to: 360
+ duration: 3000
+ easing.type: Easing.Linear
+ }
+
+ onVideoFramePainted: root.videoFramePainted()
+ }
+
+
+ Component.onCompleted: root.content = content
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/SeekControl.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SeekControl.qml
new file mode 100644
index 000000000..d286c6811
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/SeekControl.qml
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: seekControl
+ height: 46
+ property int duration: 0
+ property int playPosition: 0
+ property int seekPosition: 0
+ property bool enabled: true
+ property bool seeking: false
+
+ Rectangle {
+ id: background
+ anchors.fill: parent
+ color: "black"
+ opacity: 0.3
+ }
+
+ Rectangle {
+ id: progressBar
+ anchors { left: parent.left; top: parent.top; bottom: parent.bottom }
+ width: seekControl.duration == 0 ? 0 : background.width * seekControl.playPosition / seekControl.duration
+ color: "black"
+ opacity: 0.7
+ }
+
+ Text {
+ width: 90
+ anchors { left: parent.left; top: parent.top; bottom: parent.bottom; leftMargin: 10 }
+ font { family: "Nokia Sans S60"; pixelSize: 24 }
+ horizontalAlignment: Text.AlignLeft
+ verticalAlignment: Text.AlignVCenter
+ color: "white"
+ smooth: true
+ text: formatTime(playPosition)
+ }
+
+ Text {
+ width: 90
+ anchors { right: parent.right; top: parent.top; bottom: parent.bottom; rightMargin: 10 }
+ font { family: "Nokia Sans S60"; pixelSize: 24 }
+ horizontalAlignment: Text.AlignRight
+ verticalAlignment: Text.AlignVCenter
+ color: "white"
+ smooth: true
+ text: formatTime(duration)
+ }
+
+ Image {
+ id: progressHandle
+ height: 46
+ width: 10
+ source: mouseArea.pressed ? "qrc:/images/progress_handle_pressed.svg" : "qrc:/images/progress_handle.svg"
+ anchors.verticalCenter: progressBar.verticalCenter
+ x: seekControl.duration == 0 ? 0 : seekControl.playPosition / seekControl.duration * 630
+
+ MouseArea {
+ id: mouseArea
+ anchors { horizontalCenter: parent.horizontalCenter; bottom: parent.bottom }
+ height: 46+16
+ width: height
+ enabled: seekControl.enabled
+ drag {
+ target: progressHandle
+ axis: Drag.XAxis
+ minimumX: 0
+ maximumX: 631
+ }
+ onPressed: {
+ seekControl.seeking = true;
+ }
+ onCanceled: {
+ seekControl.seekPosition = progressHandle.x * seekControl.duration / 630
+ seekControl.seeking = false
+ }
+ onReleased: {
+ seekControl.seekPosition = progressHandle.x * seekControl.duration / 630
+ seekControl.seeking = false
+ mouse.accepted = true
+ }
+ }
+ }
+
+ Timer { // Update position also while user is dragging the progress handle
+ id: seekTimer
+ repeat: true
+ interval: 300
+ running: seekControl.seeking
+ onTriggered: {
+ seekControl.seekPosition = progressHandle.x*seekControl.duration/630
+ }
+ }
+
+ function formatTime(timeInMs) {
+ if (!timeInMs || timeInMs <= 0) return "0:00"
+ var seconds = timeInMs / 1000;
+ var minutes = Math.floor(seconds / 60)
+ seconds = Math.floor(seconds % 60)
+ if (seconds < 10) seconds = "0" + seconds;
+ return minutes + ":" + seconds
+ }
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoBasic.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoBasic.qml
new file mode 100644
index 000000000..93d0f7c4f
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoBasic.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneBasic {
+ contentType: "video"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoDrag.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoDrag.qml
new file mode 100644
index 000000000..85bc9a078
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoDrag.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneDrag {
+ contentType: "video"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoDummy.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoDummy.qml
new file mode 100644
index 000000000..e7d320ff8
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoDummy.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+// Item which is loaded by VideoItem if QtMultimediaKit is not available
+Rectangle {
+ id: root
+ color: "grey"
+ height: width
+ property int duration: 0
+ property int position: 0
+ property string source
+ property real volume: 1.0
+ property real playbackRate: 1.0
+
+ signal fatalError
+ signal sizeChanged
+ signal framePainted
+
+ Text {
+ anchors.fill: parent
+ anchors.margins: 10
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ text: "Failed to create Video item\n\nCheck that QtMultimediaKit is installed"
+ verticalAlignment: Text.AlignVCenter
+ wrapMode: Text.Wrap
+ }
+
+ onWidthChanged: height = width
+ onHeightChanged: root.sizeChanged()
+
+ function start() { }
+ function stop() { }
+ function seek() { }
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFillMode.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFillMode.qml
new file mode 100644
index 000000000..6e853e5b1
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFillMode.qml
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+Scene {
+ id: root
+
+ Content {
+ id: content
+ anchors.centerIn: parent
+ width: parent.contentWidth
+ contentType: "video"
+ source: parent.source1
+ volume: parent.volume
+ onVideoFramePainted: root.videoFramePainted()
+ }
+
+ Button {
+ id: button
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ margins: parent.margins
+ }
+ width: 150
+ height: root.buttonHeight
+ text: "PreserveAspectFit"
+ onClicked: {
+ if (!content.dummy) {
+ var video = content.contentItem()
+ if (video.fillMode == VideoOutput.Stretch) {
+ video.fillMode = VideoOutput.PreserveAspectFit
+ text = "PreserveAspectFit"
+ } else if (video.fillMode == VideoOutput.PreserveAspectFit) {
+ video.fillMode = VideoOutput.PreserveAspectCrop
+ text = "PreserveAspectCrop"
+ } else {
+ video.fillMode = VideoOutput.Stretch
+ text = "Stretch"
+ }
+ }
+ }
+ }
+
+ Component.onCompleted: root.content = content
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFullScreen.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFullScreen.qml
new file mode 100644
index 000000000..f7aee0ce6
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFullScreen.qml
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneFullScreen {
+ contentType: "video"
+}
+
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFullScreenInverted.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFullScreenInverted.qml
new file mode 100644
index 000000000..c468a0ed0
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoFullScreenInverted.qml
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneFullScreenInverted {
+ contentType: "video"
+}
+
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoItem.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoItem.qml
new file mode 100644
index 000000000..bcd39cb73
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoItem.qml
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+VideoOutput {
+ id: root
+ height: width
+ source: mediaPlayer
+
+ property alias duration: mediaPlayer.duration
+ property alias mediaSource: mediaPlayer.source
+ property alias metaData: mediaPlayer.metaData
+ property alias playbackRate: mediaPlayer.playbackRate
+ property alias position: mediaPlayer.position
+ property alias volume: mediaPlayer.volume
+
+ signal sizeChanged
+ signal fatalError
+
+ onHeightChanged: root.sizeChanged()
+
+ MediaPlayer {
+ id: mediaPlayer
+ autoLoad: false
+
+ onError: {
+ if (MediaPlayer.NoError != error) {
+ console.log("[qmlvideo] VideoItem.onError error " + error + " errorString " + errorString)
+ root.fatalError()
+ }
+ }
+ }
+
+ function start() { mediaPlayer.play() }
+ function stop() { mediaPlayer.stop() }
+ function seek(position) { mediaPlayer.seek(position); }
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMetadata.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMetadata.qml
new file mode 100644
index 000000000..3d29a150c
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMetadata.qml
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+ property string contentType: "video"
+
+ Content {
+ id: content
+ anchors.centerIn: parent
+ width: parent.contentWidth
+ contentType: "video"
+ source: parent.source1
+ volume: parent.volume
+ onInitialized: {
+ if (!dummy)
+ metadata.createObject(root)
+ }
+ onVideoFramePainted: root.videoFramePainted()
+ }
+
+ Component {
+ id: metadata
+ Column {
+ anchors.fill: parent
+ Text {
+ color: "yellow"
+ text: "Title:" + content.contentItem().metaData.title
+ }
+ Text {
+ color: "yellow"
+ text: "Size:" + content.contentItem().metaData.size
+ }
+ Text {
+ color: "yellow"
+ text: "Resolution:" + content.contentItem().metaData.resolution
+ }
+ Text {
+ color: "yellow"
+ text: "Media type:" + content.contentItem().metaData.mediaType
+ }
+ Text {
+ color: "yellow"
+ text: "Video codec:" + content.contentItem().metaData.videoCodec
+ }
+ Text {
+ color: "yellow"
+ text: "Video bit rate:" + content.contentItem().metaData.videoBitRate
+ }
+ Text {
+ color: "yellow"
+ text: "Video frame rate:" +content.contentItem().metaData.videoFrameRate
+ }
+ Text {
+ color: "yellow"
+ text: "Audio codec:" + content.contentItem().metaData.audioCodec
+ }
+ Text {
+ color: "yellow"
+ text: "Audio bit rate:" + content.contentItem().metaData.audioBitRate
+ }
+ Text {
+ color: "yellow"
+ text: "Date:" + content.contentItem().metaData.date
+ }
+ Text {
+ color: "yellow"
+ text: "Description:" + content.contentItem().metaData.description
+ }
+ Text {
+ color: "yellow"
+ text: "Copyright:" + content.contentItem().metaData.copyright
+ }
+ Text {
+ color: "yellow"
+ text: "Seekable:" + content.contentItem().metaData.seekable
+ }
+ }
+ }
+
+ Component.onCompleted: root.content = content
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMove.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMove.qml
new file mode 100644
index 000000000..4c04534b1
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoMove.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneMove {
+ contentType: "video"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoOverlay.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoOverlay.qml
new file mode 100644
index 000000000..aeca9961f
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoOverlay.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneOverlay {
+ contentType: "video"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoPlaybackRate.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoPlaybackRate.qml
new file mode 100644
index 000000000..bdbbbc5ae
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoPlaybackRate.qml
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+ property int margin: 20
+ property real delta: 0.1
+ property string contentType: "video"
+
+ Content {
+ id: content
+ anchors.centerIn: parent
+ width: parent.contentWidth
+ contentType: "video"
+ source: parent.source1
+ volume: parent.volume
+ onVideoFramePainted: root.videoFramePainted()
+ }
+
+ Button {
+ id: increaseButton
+ anchors {
+ right: parent.right
+ bottom: decreaseButton.top
+ margins: parent.margins
+ }
+ width: 90
+ height: root.buttonHeight
+ text: "Increase"
+ onClicked: {
+ var video = content.contentItem()
+ video.playbackRate = video.playbackRate + delta
+ }
+ }
+
+ Button {
+ id: decreaseButton
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ margins: parent.margins
+ }
+ width: 90
+ height: root.buttonHeight
+ text: "Decrease"
+ onClicked: {
+ var video = content.contentItem()
+ video.playbackRate = video.playbackRate - delta
+ }
+ }
+
+ Button {
+ id: valueButton
+ anchors {
+ left: parent.left
+ verticalCenter: parent.verticalCenter
+ margins: parent.margins
+ }
+ width: 50
+ height: root.buttonHeight
+ enabled: false
+ text: Math.round(10 * content.contentItem().playbackRate) / 10
+ }
+
+ Component.onCompleted: root.content = content
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoResize.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoResize.qml
new file mode 100644
index 000000000..13ef7c98d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoResize.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneResize {
+ contentType: "video"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoRotate.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoRotate.qml
new file mode 100644
index 000000000..b5e3ed4ba
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoRotate.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneRotate {
+ contentType: "video"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSeek.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSeek.qml
new file mode 100644
index 000000000..35b45ffdc
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSeek.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Scene {
+ id: root
+ property string contentType: "video"
+
+ Content {
+ id: content
+ anchors.centerIn: parent
+ width: parent.contentWidth
+ contentType: "video"
+ source: parent.source1
+ volume: parent.volume
+ onVideoFramePainted: root.videoFramePainted()
+ }
+
+ SeekControl {
+ anchors {
+ left: parent.left
+ right: parent.right
+ leftMargin: 100
+ rightMargin: 140
+ bottom: parent.bottom
+ }
+ duration: content.contentItem() ? content.contentItem().duration : 0
+ playPosition: content.contentItem() ? content.contentItem().position : 0
+ onSeekPositionChanged: { content.contentItem().seek(seekPosition); }
+ }
+
+ Component.onCompleted: root.content = content
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSpin.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSpin.qml
new file mode 100644
index 000000000..fed44e294
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoSpin.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SceneSpin {
+ contentType: "video"
+}
diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/main.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/main.qml
new file mode 100644
index 000000000..e5353cab7
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/main.qml
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ width: 640
+ height: 360
+ color: "black"
+
+ property string source1
+ property string source2
+ property color bgColor: "#002244"
+ property real volume: 0.25
+ property bool perfMonitorsLogging: false
+ property bool perfMonitorsVisible: false
+
+ QtObject {
+ id: d
+ property int itemHeight: 40
+ property int buttonHeight: 0.8 * itemHeight
+ property int margins: 10
+ }
+
+ // Create ScreenSaver element via Loader, so this app will still run if the
+ // SystemInfo module is not available
+ Loader {
+ source: "DisableScreenSaver.qml"
+ }
+
+ Loader {
+ id: performanceLoader
+
+ Connections {
+ target: inner
+ onVisibleChanged:
+ if (performanceLoader.item)
+ performanceLoader.item.enabled = !inner.visible
+ ignoreUnknownSignals: true
+ }
+
+ function init() {
+ console.log("[qmlvideo] performanceLoader.init logging " + root.perfMonitorsLogging + " visible " + root.perfMonitorsVisible)
+ var enabled = root.perfMonitorsLogging || root.perfMonitorsVisible
+ source = enabled ? "../performancemonitor/PerformanceItem.qml" : ""
+ }
+
+ onLoaded: {
+ item.parent = root
+ item.anchors.fill = root
+ item.logging = root.perfMonitorsLogging
+ item.displayed = root.perfMonitorsVisible
+ item.enabled = false
+ item.init()
+ }
+ }
+
+ Rectangle {
+ id: inner
+ anchors.fill: parent
+ color: root.bgColor
+
+ Button {
+ id: openFile1Button
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: exitButton.left
+ margins: d.margins
+ }
+ height: d.buttonHeight
+ text: (root.source1 == "") ? "Select file 1" : root.source1
+ onClicked: fileBrowser1.show()
+ }
+
+ Button {
+ id: openFile2Button
+ anchors {
+ top: openFile1Button.bottom
+ left: parent.left
+ right: exitButton.left
+ margins: d.margins
+ }
+ height: d.buttonHeight
+ text: (root.source2 == "") ? "Select file 2" : root.source2
+ onClicked: fileBrowser2.show()
+ }
+
+ Button {
+ id: exitButton
+ anchors {
+ top: parent.top
+ right: parent.right
+ margins: d.margins
+ }
+ width: 50
+ height: d.buttonHeight
+ text: "Exit"
+ onClicked: Qt.quit()
+ }
+
+ SceneSelectionPanel {
+ id: sceneSelectionPanel
+ itemHeight: d.itemHeight
+ color: "#004444"
+ anchors {
+ top: openFile2Button.bottom
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ margins: d.margins
+ }
+ radius: 10
+ onSceneSourceChanged: {
+ console.log("[qmlvideo] main.onSceneSourceChanged source " + sceneSource)
+ sceneLoader.source = sceneSource
+ var scene = null
+ var innerVisible = true
+ if (sceneSource == "") {
+ if (performanceLoader.item)
+ performanceLoader.item.videoActive = false
+ } else {
+ scene = sceneLoader.item
+ if (scene) {
+ if (scene.contentType === "video" && source1 === "") {
+ errorDialog.show("You must first select a video file")
+ sceneSource = ""
+ } else {
+ scene.parent = root
+ scene.color = root.bgColor
+ scene.buttonHeight = d.buttonHeight
+ scene.source1 = source1
+ scene.source2 = source2
+ scene.volume = volume
+ scene.anchors.fill = root
+ scene.close.connect(closeScene)
+ scene.content.initialize()
+ innerVisible = false
+ }
+ }
+ }
+ videoFramePaintedConnection.target = scene
+ inner.visible = innerVisible
+ }
+ }
+ }
+
+ Loader {
+ id: sceneLoader
+ }
+
+ Connections {
+ id: videoFramePaintedConnection
+ onVideoFramePainted: {
+ if (performanceLoader.item)
+ performanceLoader.item.videoFramePainted()
+ }
+ ignoreUnknownSignals: true
+ }
+
+ FileBrowser {
+ id: fileBrowser1
+ anchors.fill: root
+ onFolderChanged: fileBrowser2.folder = folder
+ Component.onCompleted: fileSelected.connect(root.openFile1)
+ }
+
+ FileBrowser {
+ id: fileBrowser2
+ anchors.fill: root
+ onFolderChanged: fileBrowser1.folder = folder
+ Component.onCompleted: fileSelected.connect(root.openFile2)
+ }
+
+ function openFile1(path) {
+ root.source1 = path
+ }
+
+ function openFile2(path) {
+ root.source2 = path
+ }
+
+ ErrorDialog {
+ id: errorDialog
+ anchors.fill: parent
+ enabled: false
+ }
+
+ // Called from main() once root properties have been set
+ function init() {
+ performanceLoader.init()
+ fileBrowser1.folder = videoPath
+ fileBrowser2.folder = videoPath
+ }
+
+ function qmlFramePainted() {
+ if (performanceLoader.item)
+ performanceLoader.item.qmlFramePainted()
+ }
+
+ function closeScene() {
+ console.log("[qmlvideo] main.closeScene")
+ sceneSelectionPanel.sceneSource = ""
+ }
+}
diff --git a/examples/multimedia/video/qmlvideo/qmlapplicationviewer/qmlapplicationviewer.cpp b/examples/multimedia/video/qmlvideo/qmlapplicationviewer/qmlapplicationviewer.cpp
new file mode 100644
index 000000000..2ffc0b219
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qmlapplicationviewer/qmlapplicationviewer.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlapplicationviewer.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtQml/QQmlComponent>
+#include <QtQml/QQmlEngine>
+#include <QtQml/QQmlContext>
+#include <QtGui/QGuiApplication>
+
+class QmlApplicationViewerPrivate
+{
+ QmlApplicationViewerPrivate(QQuickView *view_) : view(view_) {}
+
+ QString mainQmlFile;
+ QQuickView *view;
+ friend class QmlApplicationViewer;
+ QString adjustPath(const QString &path);
+};
+
+QString QmlApplicationViewerPrivate::adjustPath(const QString &path)
+{
+#ifdef Q_OS_UNIX
+#ifdef Q_OS_MAC
+ if (!QDir::isAbsolutePath(path))
+ return QCoreApplication::applicationDirPath()
+ + QLatin1String("/../Resources/") + path;
+#else
+ QString pathInInstallDir;
+ const QString applicationDirPath = QCoreApplication::applicationDirPath();
+ pathInInstallDir = QString::fromLatin1("%1/../%2").arg(applicationDirPath, path);
+
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+#endif
+#endif
+ return path;
+}
+
+QmlApplicationViewer::QmlApplicationViewer(QWindow *parent)
+ : QQuickView(parent)
+ , d(new QmlApplicationViewerPrivate(this))
+{
+ connect(engine(), SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
+ setResizeMode(QQuickView::SizeRootObjectToView);
+}
+
+QmlApplicationViewer::QmlApplicationViewer(QQuickView *view, QWindow *parent)
+ : QQuickView(parent)
+ , d(new QmlApplicationViewerPrivate(view))
+{
+ connect(view->engine(), SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
+ view->setResizeMode(QQuickView::SizeRootObjectToView);
+}
+
+QmlApplicationViewer::~QmlApplicationViewer()
+{
+ delete d;
+}
+
+QmlApplicationViewer *QmlApplicationViewer::create()
+{
+ return new QmlApplicationViewer();
+}
+
+void QmlApplicationViewer::setMainQmlFile(const QString &file)
+{
+ d->mainQmlFile = d->adjustPath(file);
+ d->view->setSource(QUrl::fromLocalFile(d->mainQmlFile));
+}
+
+void QmlApplicationViewer::addImportPath(const QString &path)
+{
+ d->view->engine()->addImportPath(d->adjustPath(path));
+}
+
+void QmlApplicationViewer::showExpanded()
+{
+#if defined(Q_WS_SIMULATOR)
+ d->view->showFullScreen();
+#else
+ d->view->show();
+#endif
+}
+
+QGuiApplication *createApplication(int &argc, char **argv)
+{
+ return new QGuiApplication(argc, argv);
+}
diff --git a/examples/multimedia/video/qmlvideo/qmlapplicationviewer/qmlapplicationviewer.h b/examples/multimedia/video/qmlvideo/qmlapplicationviewer/qmlapplicationviewer.h
new file mode 100644
index 000000000..a4eabdba8
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qmlapplicationviewer/qmlapplicationviewer.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLAPPLICATIONVIEWER_H
+#define QMLAPPLICATIONVIEWER_H
+
+#include <QtQuick/QQuickView>
+#include <QtGui/QGuiApplication>
+
+class QmlApplicationViewer : public QQuickView
+{
+ Q_OBJECT
+
+public:
+ explicit QmlApplicationViewer(QWindow *parent = 0);
+ virtual ~QmlApplicationViewer();
+
+ static QmlApplicationViewer *create();
+
+ void setMainQmlFile(const QString &file);
+ void addImportPath(const QString &path);
+
+ void showExpanded();
+
+private:
+ explicit QmlApplicationViewer(QQuickView *view, QWindow *parent);
+ class QmlApplicationViewerPrivate *d;
+};
+
+QGuiApplication *createApplication(int &argc, char **argv);
+
+#endif // QMLAPPLICATIONVIEWER_H
diff --git a/examples/multimedia/video/qmlvideo/qmlapplicationviewer/qmlapplicationviewer.pri b/examples/multimedia/video/qmlvideo/qmlapplicationviewer/qmlapplicationviewer.pri
new file mode 100644
index 000000000..75d66c36b
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qmlapplicationviewer/qmlapplicationviewer.pri
@@ -0,0 +1,5 @@
+QT += qml quick
+
+SOURCES += $$PWD/qmlapplicationviewer.cpp
+HEADERS += $$PWD/qmlapplicationviewer.h
+INCLUDEPATH += $$PWD
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo.png b/examples/multimedia/video/qmlvideo/qmlvideo.png
new file mode 100644
index 000000000..707d5c4e8
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qmlvideo.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo.pro b/examples/multimedia/video/qmlvideo/qmlvideo.pro
new file mode 100644
index 000000000..78c6f0540
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qmlvideo.pro
@@ -0,0 +1,18 @@
+TEMPLATE = app
+TARGET = qmlvideo
+
+LOCAL_SOURCES = main.cpp
+LOCAL_HEADERS = trace.h
+
+SOURCES += $$LOCAL_SOURCES
+HEADERS += $$LOCAL_HEADERS
+RESOURCES += qmlvideo.qrc
+
+SNIPPETS_PATH = ../snippets
+include($$SNIPPETS_PATH/performancemonitor/performancemonitordeclarative.pri)
+
+include(qmlapplicationviewer/qmlapplicationviewer.pri)
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/video/qmlvideo
+INSTALLS += target
+
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo.qrc b/examples/multimedia/video/qmlvideo/qmlvideo.qrc
new file mode 100644
index 000000000..4896b336f
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qmlvideo.qrc
@@ -0,0 +1,12 @@
+<RCC>
+ <qresource prefix="/images">
+ <file alias="leaves.jpg">images/leaves.jpg</file>
+ <file alias="close.png">images/close.png</file>
+ <file alias="folder.png">images/folder.png</file>
+ <file alias="titlebar.png">images/titlebar.png</file>
+ <file alias="titlebar.sci">images/titlebar.sci</file>
+ <file alias="up.png">images/up.png</file>
+ <file alias="progress_handle.svg">images/progress_handle.svg</file>
+ <file alias="progress_handle_pressed.svg">images/progress_handle_pressed.svg</file>
+ </qresource>
+</RCC>
diff --git a/examples/multimedia/video/qmlvideo/qmlvideo.svg b/examples/multimedia/video/qmlvideo/qmlvideo.svg
new file mode 100644
index 000000000..566acfada
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/qmlvideo.svg
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="44px"
+ version="1.1"
+ viewBox="0 0 44 44"
+ width="44px"
+ x="0px"
+ y="0px"
+ id="svg2"
+ inkscape:version="0.47 r22583"
+ sodipodi:docname="qt.svg">
+ <metadata
+ id="metadata18">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs16">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 22 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="44 : 22 : 1"
+ inkscape:persp3d-origin="22 : 14.666667 : 1"
+ id="perspective2836" />
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1020"
+ id="namedview14"
+ showgrid="false"
+ inkscape:zoom="21.454545"
+ inkscape:cx="49.412871"
+ inkscape:cy="21.894358"
+ inkscape:window-x="-4"
+ inkscape:window-y="-4"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g3" />
+ <g
+ transform="matrix(0.18308778,0,0,0.18308778,6.6100946,3.2385199)"
+ id="g3">
+ <path
+ d="M 43.09,0.3586 C 40.94,0.0036 38.84,-0.0824 36.81,0.0776 31.968136,0.39505671 27.122677,0.73638425 22.28,1.0696 9.62,2.0816 0,12.4996 0,26.8896 l 0,169.7 14.19,13.2 28.87,-209.42 0.03,-0.011 z"
+ style="fill:#006225"
+ id="path5"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ d="m 174.4,160 c 0,12.5 -7.75,24.07 -17.57,25.77 L 14.23,209.73 V 25.93 C 14.23,9.21 27.57,-2.27 43.12,0.3 l 131.3,21.52 v 138.2 z"
+ style="fill:#80c342"
+ id="path7" />
+ <path
+ d="m 154.9,80.96 -12.96,-0.598 0,0.278 6.945,0.32 6.016,0 z"
+ style="fill:#006225"
+ id="path11" />
+ <path
+ d="m 144.6,135.6 c 0.66,0.328 1.43,0.476 2.351,0.476 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 h -6.015 c -1.821,0.832 -3.532,1.457 -5.176,1.848 z"
+ style="fill:#006225"
+ id="path13" />
+ <path
+ id="path17"
+ style="fill:#ffffff"
+ d="m 91.15,132.4 c 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -4.34,0 -7.68,2.535 -10.01,7.625 -2.52,5.543 -3.793,17.04 -3.793,34.44 0,16.82 1.238,28.75 3.734,35.75 2.356,6.672 5.879,9.976 10.5,9.976 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 m 17.98,3.75 c -4.117,9.707 -10.39,16.06 -18.99,19 0.867,4.449 2.176,7.441 3.922,9.019 1.351,1.211 3.433,1.821 6.222,1.821 0.805,0 1.668,-0.055 2.59,-0.157 v 13.12 l -5.961,0.782 c -1.758,0.23 -3.426,0.343 -5.004,0.343 -5.218,0 -9.445,-1.265 -12.62,-3.824 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 1.629,0 3.309,0.102 5.043,0.305 11.95,1.375 20.62,7.016 26.26,16.79 5.535,9.562 8.254,23.27 8.254,41.26 0,16.48 -2,29.45 -6.043,39.02 z M 130.4,45.91 l 11.52,1.238 0,20.21 12.96,0.914 0,12.68 -12.96,-0.598 0,46.33 c 0,4.032 0.445,6.625 1.34,7.789 0.8,1.067 2.046,1.594 3.71,1.594 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 v 11.65 c -5.136,2.258 -10.18,3.598 -15.12,4.02 -0.718,0.055 -1.41,0.086 -2.078,0.086 -4.48,0 -7.906,-1.301 -10.25,-3.934 -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.535 L 118.046,79.25 V 65.66 l 7.586,0.547 4.773,-20.3 z" />
+ <path
+ d="m 100.3,166 c 0.809,0 1.672,-0.055 2.59,-0.157 H 98.054 C 98.73,165.949 99.507,166 100.3,166 z"
+ style="fill:#006225"
+ id="path19" />
+ <path
+ id="path21"
+ style="fill:#006225"
+ d="m 84.85,63.98 c 2.336,5.997 3.484,16.92 3.484,32.81 0,17.7 -1.16,29.57 -3.512,35.62 -1.894,4.879 -4.527,7.902 -7.863,9.07 0.965,0.368 1.992,0.551 3.078,0.551 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -1.09,0 -2.117,0.16 -3.082,0.481 h -0.004 c 3.601,1.121 6.379,4.215 8.336,9.261 z m -2.344,114.3 c -0.113,-0.05 -0.227,-0.105 -0.336,-0.16 -0.012,-0.004 -0.023,-0.012 -0.035,-0.015 -0.102,-0.051 -0.207,-0.106 -0.309,-0.157 -0.019,-0.011 -0.039,-0.019 -0.058,-0.031 -0.09,-0.051 -0.184,-0.098 -0.278,-0.148 -0.027,-0.016 -0.054,-0.036 -0.086,-0.051 -0.082,-0.043 -0.164,-0.09 -0.242,-0.137 -0.039,-0.023 -0.078,-0.047 -0.113,-0.07 -0.07,-0.039 -0.145,-0.082 -0.215,-0.125 -0.047,-0.031 -0.094,-0.059 -0.14,-0.09 -0.059,-0.039 -0.118,-0.074 -0.176,-0.113 -0.059,-0.039 -0.114,-0.075 -0.168,-0.114 -0.051,-0.031 -0.102,-0.066 -0.149,-0.097 -0.066,-0.047 -0.132,-0.094 -0.195,-0.137 -0.039,-0.027 -0.078,-0.055 -0.113,-0.082 -0.078,-0.055 -0.153,-0.113 -0.231,-0.172 -0.023,-0.016 -0.05,-0.035 -0.078,-0.055 -0.098,-0.078 -0.199,-0.156 -0.297,-0.234 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 h -6.351 c -10.15,0.008 -18.22,3.977 -24,12.04 -6.855,9.563 -10.34,24.64 -10.34,45.07 0,18.95 2.547,33.44 7.551,43.34 4.934,9.75 12.05,15.56 21.19,17.5 1.989,9.641 5.09,16.16 9.297,19.54 3.176,2.559 7.403,3.824 12.62,3.824 0.098,0 0.199,0 0.297,-0.004 h 5.539 c -3.406,-0.05 -6.383,-0.66 -8.906,-1.828 L 82.498,178.28 z M 128.4,145.6 c -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.57 l -6.226,-0.285 v -13.59 h -6.016 v 3.035 c 0.871,3.273 1.555,6.82 2.063,10.64 l 4.164,0.192 v 51.36 c 0,6.723 1.367,11.62 4.09,14.67 2.343,2.633 5.765,3.934 10.25,3.934 h 6.015 c -4.48,0 -7.906,-1.301 -10.25,-3.934 z m 2.043,-99.66 -6.016,0 -4.668,19.88 5.911,0.422 4.773,-20.3 z" />
+ </g>
+</svg>
diff --git a/examples/multimedia/video/qmlvideo/trace.h b/examples/multimedia/video/qmlvideo/trace.h
new file mode 100644
index 000000000..e6083f439
--- /dev/null
+++ b/examples/multimedia/video/qmlvideo/trace.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRACE_H
+#define TRACE_H
+
+#include <QtCore/QDebug>
+
+#define ENABLE_TRACE
+//#define VERBOSE_TRACE
+
+namespace Trace {
+
+class NullDebug
+{
+public:
+ template <typename T>
+ NullDebug& operator<<(const T&) { return *this; }
+};
+
+inline NullDebug nullDebug() { return NullDebug(); }
+
+template <typename T>
+struct PtrWrapper
+{
+ PtrWrapper(const T *ptr) : m_ptr(ptr) { }
+ const T *const m_ptr;
+};
+
+} // namespace Trace
+
+template <typename T>
+inline QDebug& operator<<(QDebug &debug, const Trace::PtrWrapper<T> &wrapper)
+{
+ debug.nospace() << "[" << (void*)wrapper.m_ptr << "]";
+ return debug.space();
+}
+
+template<typename T>
+inline const void *qtVoidPtr(const T *ptr)
+{ return static_cast<const void *>(ptr); }
+
+#define qtThisPtr() qtVoidPtr(this)
+
+#ifdef ENABLE_TRACE
+ inline QDebug qtTrace() { return qDebug() << "[qmlvideo]"; }
+# ifdef VERBOSE_TRACE
+ inline QDebug qtVerboseTrace() { return qtTrace(); }
+# else
+ inline Trace::NullDebug qtVerboseTrace() { return Trace::nullDebug(); }
+# endif
+#else
+ inline Trace::NullDebug qtTrace() { return Trace::nullDebug(); }
+ inline Trace::NullDebug qtVerboseTrace() { return Trace::nullDebug(); }
+#endif
+
+#endif // TRACE_H
diff --git a/examples/multimedia/video/qmlvideofx/filereader.cpp b/examples/multimedia/video/qmlvideofx/filereader.cpp
new file mode 100644
index 000000000..065766323
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/filereader.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "filereader.h"
+#include "trace.h"
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTextStream>
+
+QString adjustPath(const QString &path)
+{
+#ifdef Q_OS_UNIX
+#ifdef Q_OS_MAC
+ if (!QDir::isAbsolutePath(path))
+ return QCoreApplication::applicationDirPath()
+ + QLatin1String("/../Resources/") + path;
+#else
+ QString pathInInstallDir;
+ const QString applicationDirPath = QCoreApplication::applicationDirPath();
+ pathInInstallDir = QString::fromLatin1("%1/../%2").arg(applicationDirPath, path);
+
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+#endif
+#endif
+ return path;
+}
+
+QString FileReader::readFile(const QString &fileName)
+{
+ qtTrace() << "FileReader::readFile" << "fileName" << fileName;
+ QString content;
+ QFile file(adjustPath(fileName));
+ if (file.open(QIODevice::ReadOnly)) {
+ QTextStream stream(&file);
+ content = stream.readAll();
+ }
+ return content;
+}
+
diff --git a/examples/multimedia/video/qmlvideofx/filereader.h b/examples/multimedia/video/qmlvideofx/filereader.h
new file mode 100644
index 000000000..44393b1c7
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/filereader.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QObject>
+
+class FileReader : public QObject
+{
+ Q_OBJECT
+public:
+ Q_INVOKABLE QString readFile(const QString &fileName);
+};
+
diff --git a/examples/multimedia/video/qmlvideofx/images/close.png b/examples/multimedia/video/qmlvideofx/images/close.png
new file mode 100644
index 000000000..6904df0e4
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/images/close.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideofx/images/folder.png b/examples/multimedia/video/qmlvideofx/images/folder.png
new file mode 100644
index 000000000..e53e2ad46
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/images/folder.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideofx/images/qt-logo.png b/examples/multimedia/video/qmlvideofx/images/qt-logo.png
new file mode 100644
index 000000000..7d3e97eb3
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/images/qt-logo.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideofx/images/titlebar.png b/examples/multimedia/video/qmlvideofx/images/titlebar.png
new file mode 100644
index 000000000..51c90082d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/images/titlebar.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideofx/images/titlebar.sci b/examples/multimedia/video/qmlvideofx/images/titlebar.sci
new file mode 100644
index 000000000..0418d94cd
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/images/titlebar.sci
@@ -0,0 +1,5 @@
+border.left: 10
+border.top: 12
+border.bottom: 12
+border.right: 10
+source: titlebar.png
diff --git a/examples/multimedia/video/qmlvideofx/images/up.png b/examples/multimedia/video/qmlvideofx/images/up.png
new file mode 100644
index 000000000..b05f8025d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/images/up.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideofx/main.cpp b/examples/multimedia/video/qmlvideofx/main.cpp
new file mode 100644
index 000000000..dff51776a
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/main.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QStandardPaths>
+#include <QtCore/QStringList>
+#include <QtQml/QQmlContext>
+#include <QtGui/QGuiApplication>
+#include <QtQuick/QQuickItem>
+#include "filereader.h"
+#include "qmlapplicationviewer.h"
+#include "trace.h"
+
+#ifdef SMALL_SCREEN_LAYOUT
+ static const QLatin1String MainQmlFile("main-smallscreen.qml");
+#else
+ static const QLatin1String MainQmlFile("main-largescreen.qml");
+#endif
+
+#ifdef PERFORMANCEMONITOR_SUPPORT
+#include "performancemonitordeclarative.h"
+#endif
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+#ifdef PERFORMANCEMONITOR_SUPPORT
+ PerformanceMonitor::qmlRegisterTypes();
+#endif
+
+ QUrl fileName;
+ qreal volume = 0.5;
+ QStringList args = app.arguments();
+#ifdef PERFORMANCEMONITOR_SUPPORT
+ PerformanceMonitor::State performanceMonitorState;
+#endif
+ for (int i=1; i<args.count(); ++i) {
+ const QString &arg = args.at(i);
+ if (arg.startsWith('-')) {
+ if ("-volume" == arg) {
+ if (i+1 < args.count())
+ volume = 0.01 * args.at(++i).toInt();
+ else
+ qtTrace() << "Option \"-volume\" takes a value";
+ }
+#ifdef PERFORMANCEMONITOR_SUPPORT
+ else if (PerformanceMonitor::parseArgument(arg, performanceMonitorState)) {
+ // Do nothing
+ }
+#endif
+ else {
+ qtTrace() << "Option" << arg << "ignored";
+ }
+ } else {
+ if (fileName.isEmpty())
+ fileName = QUrl::fromLocalFile(arg);
+ else
+ qtTrace() << "Argument" << arg << "ignored";
+ }
+ }
+
+ QmlApplicationViewer viewer;
+
+ viewer.requestOrientation(Qt::LandscapeOrientation);
+ viewer.setMainQmlFile(QLatin1String("qml/qmlvideofx/") + MainQmlFile);
+ QQuickItem *rootObject = viewer.rootObject();
+ rootObject->setProperty("fileName", fileName);
+ viewer.rootObject()->setProperty("volume", volume);
+
+#ifdef PERFORMANCEMONITOR_SUPPORT
+ if (performanceMonitorState.valid) {
+ rootObject->setProperty("perfMonitorsLogging", performanceMonitorState.logging);
+ rootObject->setProperty("perfMonitorsVisible", performanceMonitorState.visible);
+ }
+ QObject::connect(&viewer, SIGNAL(afterRendering()),
+ rootObject, SLOT(qmlFramePainted()));
+#endif
+
+ FileReader fileReader;
+ viewer.rootContext()->setContextProperty("fileReader", &fileReader);
+
+ QString imagePath = "../../images";
+ const QStringList picturesLocation = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
+ if (!picturesLocation.isEmpty())
+ imagePath = picturesLocation.first();
+ viewer.rootContext()->setContextProperty("imagePath", imagePath);
+
+ QString videoPath;
+ const QStringList moviesLocation = QStandardPaths::standardLocations(QStandardPaths::MoviesLocation);
+ if (!moviesLocation.isEmpty())
+ videoPath = moviesLocation.first();
+ viewer.rootContext()->setContextProperty("videoPath", videoPath);
+
+ viewer.setTitle("qmlvideofx");
+ viewer.setFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowTitleHint |
+ Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
+ viewer.setMinimumSize(QSize(600, 400));
+
+#ifdef SMALL_SCREEN_PHYSICAL
+ viewer.showFullScreen();
+#else
+ viewer.showExpanded();
+#endif
+
+ // Delay invocation of init until the event loop has started, to work around
+ // a GL context issue on Harmattan: without this, we get the following error
+ // when the first ShaderEffectItem is created:
+ // "QGLShaderProgram::addShader: Program and shader are not associated with same context"
+ QMetaObject::invokeMethod(viewer.rootObject(), "init", Qt::QueuedConnection);
+
+ return app.exec();
+}
+
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Button.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Button.qml
new file mode 100644
index 000000000..f3814b860
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Button.qml
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ color: textColor
+ radius: 0.25 * height
+
+ property string text
+ property color bgColor: "white"
+ property color bgColorSelected: "red"
+ property color textColor: "black"
+ property alias enabled: mouseArea.enabled
+
+ signal clicked
+
+ Rectangle {
+ anchors { fill: parent; margins: 1 }
+ color: mouseArea.pressed ? bgColorSelected : bgColor
+ radius: 0.25 * height
+
+ Text {
+ id: text
+ anchors.centerIn: parent
+ text: root.text
+ font.pixelSize: 0.5 * parent.height
+ color: mouseArea.pressed ? bgColor : textColor
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked: {
+ root.clicked()
+ }
+ }
+ }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml
new file mode 100644
index 000000000..e2ae9cda8
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ color: "black"
+ property alias effect: effectLoader.item
+ property alias gripSize: divider.gripSize
+ property string effectSource
+ property real volume: 0.5
+
+ signal videoFramePainted
+
+ Divider {
+ id: divider
+ visible: false
+ z: 1.0
+ onValueChanged: updateDivider()
+ }
+
+ ShaderEffectSource {
+ id: theSource
+ smooth: true
+ hideSource: true
+ }
+
+ Loader {
+ id: contentLoader
+ }
+
+ Loader {
+ id: effectLoader
+ source: effectSource
+ }
+
+ Connections {
+ id: videoFramePaintedConnection
+ onFramePainted: {
+ if (performanceLoader.item)
+ root.videoFramePainted()
+ }
+ ignoreUnknownSignals: true
+ }
+
+ onWidthChanged: {
+ if (effectLoader.item)
+ effectLoader.item.targetWidth = root.width
+ }
+
+ onHeightChanged: {
+ if (effectLoader.item)
+ effectLoader.item.targetHeight = root.height
+ }
+
+ onEffectSourceChanged: {
+ console.log("[qmlvideofx] Content.onEffectSourceChanged " + effectSource)
+ effectLoader.source = effectSource
+ effectLoader.item.parent = root
+ effectLoader.item.targetWidth = root.width
+ effectLoader.item.targetHeight = root.height
+ updateSource()
+ effectLoader.item.source = theSource
+ divider.visible = effectLoader.item.divider
+ updateDivider()
+ }
+
+ function init() {
+ console.log("[qmlvideofx] Content.init")
+ openImage("qrc:/images/qt-logo.png")
+ root.effectSource = "EffectPassThrough.qml"
+ }
+
+ function updateDivider() {
+ if (effectLoader.item && effectLoader.item.divider)
+ effectLoader.item.dividerValue = divider.value
+ }
+
+ function updateSource() {
+ console.log("[qmlvideofx] Content.updateSource")
+ if (contentLoader.item) {
+ contentLoader.item.parent = root
+ contentLoader.item.anchors.fill = root
+ theSource.sourceItem = contentLoader.item
+ if (effectLoader.item)
+ effectLoader.item.anchors.fill = contentLoader.item
+ }
+ }
+
+ function openImage(path) {
+ console.log("[qmlvideofx] Content.openImage \"" + path + "\"")
+ stop()
+ contentLoader.source = "ContentImage.qml"
+ videoFramePaintedConnection.target = null
+ contentLoader.item.source = path
+ updateSource()
+ }
+
+ function openVideo(path) {
+ console.log("[qmlvideofx] Content.openVideo \"" + path + "\"")
+ stop()
+ contentLoader.source = "ContentVideo.qml"
+ videoFramePaintedConnection.target = contentLoader.item
+ contentLoader.item.mediaSource = path
+ contentLoader.item.volume = volume
+ contentLoader.item.play()
+ updateSource()
+ }
+
+ function openCamera() {
+ console.log("[qmlvideofx] Content.openCamera")
+ stop()
+ contentLoader.source = "ContentCamera.qml"
+ videoFramePaintedConnection.target = contentLoader.item
+ updateSource()
+ }
+
+ function stop() {
+ console.log("[qmlvideofx] Content.stop")
+ if (contentLoader.source == "ContentVideo.qml")
+ contentLoader.item.stop()
+ theSource.sourceItem = null
+ }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentCamera.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentCamera.qml
new file mode 100644
index 000000000..fb146a3cc
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentCamera.qml
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+VideoOutput {
+ source: camera
+
+ Camera {
+ id: camera
+ }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentImage.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentImage.qml
new file mode 100644
index 000000000..36c9a2b24
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentImage.qml
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Image {
+ fillMode: Image.PreserveAspectFit
+ smooth: true
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentVideo.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentVideo.qml
new file mode 100644
index 000000000..76c9025a9
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentVideo.qml
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+VideoOutput {
+ source: mediaPlayer
+ property alias mediaSource: mediaPlayer.source
+ property alias volume: mediaPlayer.volume
+
+ MediaPlayer {
+ id: mediaPlayer
+ autoPlay: true
+ volume: 0.5
+ }
+
+ function play() { mediaPlayer.play() }
+ function stop() { mediaPlayer.stop() }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml
new file mode 100644
index 000000000..309b289b0
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMobility.systeminfo 1.1
+
+Item {
+ ScreenSaver {
+ screenSaverInhibited: true
+ }
+}
+
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Divider.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Divider.qml
new file mode 100644
index 000000000..e6d937dad
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Divider.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ anchors.fill: parent
+ color: "transparent"
+ property alias value: slider.value
+ property alias lineWidth: line.width
+ property alias gripSize: slider.gripSize
+
+ Rectangle {
+ id: line
+ anchors { top: parent.top; bottom: parent.bottom }
+ x: parent.value * parent.width - (width / 2)
+ width: 2
+ color: "red"
+ }
+
+ Slider {
+ id: slider
+ increment: 0.0
+ lineColor: "transparent"
+ fillColor: "transparent"
+ gripColor: "red"
+ anchors {
+ top: parent.top
+ topMargin: gripSize / 2
+ left: parent.left
+ right: parent.right
+ }
+ }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Effect.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Effect.qml
new file mode 100644
index 000000000..535ab106b
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Effect.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+ShaderEffect {
+ property variant source
+ property ListModel parameters: ListModel { }
+ property bool divider: true
+ property real dividerValue: 0.5
+ property real targetWidth: 0
+ property real targetHeight: 0
+ property string fragmentShaderFilename
+ property string vertexShaderFilename
+
+ QtObject {
+ id: d
+ property string fragmentShaderCommon: "
+ #ifdef GL_ES
+ precision mediump float;
+ #else
+ # define lowp
+ # define mediump
+ # define highp
+ #endif // GL_ES
+ "
+ }
+
+ // The following is a workaround for the fact that ShaderEffect
+ // doesn't provide a way for shader programs to be read from a file,
+ // rather than being inline in the QML file
+
+ onFragmentShaderFilenameChanged:
+ fragmentShader = d.fragmentShaderCommon + fileReader.readFile(fragmentShaderFilename)
+ onVertexShaderFilenameChanged:
+ vertexShader = fileReader.readFile(vertexShaderFilename)
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBillboard.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBillboard.qml
new file mode 100644
index 000000000..124a2a17e
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBillboard.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "grid spacing"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real grid: parameters.get(0).value * 10
+
+ property real step_x: 0.0015625
+ property real step_y: targetHeight ? (step_x * targetWidth / targetHeight) : 0.0
+
+ fragmentShaderFilename: "shaders/billboard.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBlackAndWhite.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBlackAndWhite.qml
new file mode 100644
index 000000000..37a3b6e0d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBlackAndWhite.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "threshold"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real threshold: parameters.get(0).value
+
+ fragmentShaderFilename: "shaders/blackandwhite.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectEmboss.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectEmboss.qml
new file mode 100644
index 000000000..4bf57718d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectEmboss.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ fragmentShaderFilename: "shaders/emboss.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGaussianBlur.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGaussianBlur.qml
new file mode 100644
index 000000000..b804e903b
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGaussianBlur.qml
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://www.geeks3d.com/20100909/shader-library-gaussian-blur-post-processing-filter-in-glsl/
+
+import QtQuick 2.0
+
+Item {
+ id: root
+ property bool divider: true
+ property real dividerValue: 0.5
+ property ListModel parameters: ListModel {
+ ListElement {
+ name: "radius"
+ value: 0.5
+ }
+ }
+
+ property alias targetWidth: verticalShader.targetWidth
+ property alias targetHeight: verticalShader.targetHeight
+ property alias source: verticalShader.source
+
+ Effect {
+ id: verticalShader
+ anchors.fill: parent
+ dividerValue: parent.dividerValue
+ property real blurSize: 4.0 * parent.parameters.get(0).value / targetHeight
+ fragmentShaderFilename: "shaders/gaussianblur_v.fsh"
+ }
+
+ Effect {
+ id: horizontalShader
+ anchors.fill: parent
+ dividerValue: parent.dividerValue
+ property real blurSize: 4.0 * parent.parameters.get(0).value / parent.targetWidth
+ fragmentShaderFilename: "shaders/gaussianblur_h.fsh"
+ source: horizontalShaderSource
+
+ ShaderEffectSource {
+ id: horizontalShaderSource
+ sourceItem: verticalShader
+ smooth: true
+ hideSource: true
+ }
+ }
+}
+
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGlow.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGlow.qml
new file mode 100644
index 000000000..d6e987db2
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGlow.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ fragmentShaderFilename: "shaders/glow.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectIsolate.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectIsolate.qml
new file mode 100644
index 000000000..2425a2580
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectIsolate.qml
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "hue"
+ value: 0.5
+ }
+ ListElement {
+ name: "width"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real targetHue: parameters.get(0).value * 360
+ property real windowWidth: parameters.get(1).value * 60
+
+ fragmentShaderFilename: "shaders/isolate.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml
new file mode 100644
index 000000000..5a207f95e
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ id: root
+ divider: false
+ parameters: ListModel {
+ ListElement {
+ name: "radius"
+ value: 0.5
+ }
+ ListElement {
+ name: "diffraction"
+ value: 0.5
+ }
+ }
+
+ property real posX: -1
+ property real posY: -1
+
+ QtObject {
+ id: d
+ property real oldTargetWidth: root.targetWidth
+ property real oldTargetHeight: root.targetHeight
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real radius: parameters.get(0).value * 100
+ property real diffractionIndex: parameters.get(1).value
+
+ onTargetWidthChanged: {
+ if (posX == -1)
+ posX = targetWidth / 2
+ else if (d.oldTargetWidth != 0)
+ posX *= (targetWidth / d.oldTargetWidth)
+ d.oldTargetWidth = targetWidth
+ }
+
+ onTargetHeightChanged: {
+ if (posY == -1)
+ posY = targetHeight / 2
+ else if (d.oldTargetHeight != 0)
+ posY *= (targetHeight / d.oldTargetHeight)
+ d.oldTargetHeight = targetHeight
+ }
+
+ fragmentShaderFilename: "shaders/magnify.fsh"
+
+ MouseArea {
+ anchors.fill: parent
+ onPositionChanged: { root.posX = mouse.x; root.posY = root.targetHeight - mouse.y }
+ }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml
new file mode 100644
index 000000000..7724bfa9b
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ divider: false
+ parameters: ListModel {
+ ListElement {
+ name: "extent"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real curlExtent: 1.0 - parameters.get(0).value
+
+ fragmentShaderFilename: "shaders/pagecurl.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPassThrough.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPassThrough.qml
new file mode 100644
index 000000000..1f259bebb
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPassThrough.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ divider: false
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml
new file mode 100644
index 000000000..71f7da965
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "granularity"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real granularity: parameters.get(0).value * 20
+
+ fragmentShaderFilename: "shaders/pixelate.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPosterize.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPosterize.qml
new file mode 100644
index 000000000..0cf16a0dc
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPosterize.qml
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "gamma"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real gamma: parameters.get(0).value
+
+ property real numColors: 8.0
+
+ fragmentShaderFilename: "shaders/posterize.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml
new file mode 100644
index 000000000..0b7c48cbc
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "amplitude"
+ value: 0.5
+ }
+ ListElement {
+ name: "frequency"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real amplitude: parameters.get(0).value * 0.03
+ property real n: parameters.get(1).value * 7
+
+ property real time: 0
+ NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 600 }
+
+ fragmentShaderFilename: "shaders/ripple.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionPanel.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionPanel.qml
new file mode 100644
index 000000000..78cf965e1
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionPanel.qml
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ property int itemHeight: 25
+ property string effectSource: ""
+
+ signal clicked
+
+ QtObject {
+ id: d
+ property Item selectedItem
+ }
+
+ ListModel {
+ id: sources
+ ListElement { name: "No effect"; source: "EffectPassThrough.qml" }
+ ListElement { name: "Billboard"; source: "EffectBillboard.qml" }
+ ListElement { name: "Black & white"; source: "EffectBlackAndWhite.qml" }
+ ListElement { name: "Blur"; source: "EffectGaussianBlur.qml" }
+ ListElement { name: "Edge detection"; source: "EffectSobelEdgeDetection1.qml" }
+ //ListElement { name: "Edge detection (Sobel, #2)"; source: "EffectSobelEdgeDetection2.qml" }
+ ListElement { name: "Emboss"; source: "EffectEmboss.qml" }
+ ListElement { name: "Glow"; source: "EffectGlow.qml" }
+ ListElement { name: "Isolate"; source: "EffectIsolate.qml" }
+ ListElement { name: "Magnify"; source: "EffectMagnify.qml" }
+ ListElement { name: "Page curl"; source: "EffectPageCurl.qml" }
+ ListElement { name: "Pixelate"; source: "EffectPixelate.qml" }
+ ListElement { name: "Posterize"; source: "EffectPosterize.qml" }
+ ListElement { name: "Ripple"; source: "EffectRipple.qml" }
+ ListElement { name: "Sepia"; source: "EffectSepia.qml" }
+ ListElement { name: "Sharpen"; source: "EffectSharpen.qml" }
+ ListElement { name: "Shockwave"; source: "EffectShockwave.qml" }
+ ListElement { name: "Tilt shift"; source: "EffectTiltShift.qml" }
+ ListElement { name: "Toon"; source: "EffectToon.qml" }
+ ListElement { name: "Warhol"; source: "EffectWarhol.qml" }
+ ListElement { name: "Wobble"; source: "EffectWobble.qml" }
+ ListElement { name: "Vignette"; source: "EffectVignette.qml" }
+ }
+
+ Component {
+ id: sourceDelegate
+ Item {
+ id: sourceDelegateItem
+ width: root.width
+ height: itemHeight
+
+ Button {
+ id: sourceSelectorItem
+ anchors.centerIn: parent
+ width: 0.9 * parent.width
+ height: 0.8 * itemHeight
+ text: name
+ onClicked: {
+ if (d.selectedItem)
+ d.selectedItem.state = "baseState"
+ d.selectedItem = sourceDelegateItem
+ d.selectedItem.state = "selected"
+ effectSource = source
+ root.clicked()
+ }
+ }
+
+ states: [
+ State {
+ name: "selected"
+ PropertyChanges {
+ target: sourceSelectorItem
+ bgColor: "#ff8888"
+ }
+ }
+ ]
+
+ Component.onCompleted: {
+ if (name == "No effect") {
+ state = "selected"
+ d.selectedItem = sourceDelegateItem
+ }
+ }
+
+ transitions: [
+ Transition {
+ from: "*"
+ to: "*"
+ ColorAnimation {
+ properties: "color"
+ easing.type: Easing.OutQuart
+ duration: 500
+ }
+ }
+ ]
+ }
+ }
+
+ Flickable {
+ anchors.fill: parent
+ contentHeight: (itemHeight * sources.count) + layout.anchors.topMargin + layout.spacing
+ clip: true
+
+ Column {
+ id: layout
+
+ anchors {
+ fill: parent
+ topMargin: 10
+ }
+
+ Repeater {
+ model: sources
+ delegate: sourceDelegate
+ }
+ }
+ }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSepia.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSepia.qml
new file mode 100644
index 000000000..446e7790b
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSepia.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ fragmentShaderFilename: "shaders/sepia.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSharpen.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSharpen.qml
new file mode 100644
index 000000000..99ece3cd8
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSharpen.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "sharpness"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real amount: parameters.get(0).value * 18
+
+ fragmentShaderFilename: "shaders/sharpen.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectShockwave.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectShockwave.qml
new file mode 100644
index 000000000..fe91781ba
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectShockwave.qml
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ id: root
+ parameters: ListModel {
+ ListElement {
+ name: "amplitude"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real granularity: parameters.get(0).value * 20
+ property real weight: parameters.get(0).value
+
+ property real centerX
+ property real centerY
+ property real time
+
+ SequentialAnimation {
+ running: true
+ loops: Animation.Infinite
+ ScriptAction {
+ script: {
+ centerX = Math.random()
+ centerY = Math.random()
+ }
+ }
+ NumberAnimation {
+ target: root
+ property: "time"
+ from: 0
+ to: 1
+ duration: 1000
+ }
+ }
+
+ fragmentShaderFilename: "shaders/shockwave.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection1.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection1.qml
new file mode 100644
index 000000000..189d5d385
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection1.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "threshold"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real mixLevel: parameters.get(0).value
+ property real targetSize: 250 - (200 * mixLevel) // TODO: fix ...
+ property real resS: targetSize
+ property real resT: targetSize
+
+ fragmentShaderFilename: "shaders/sobeledgedetection1.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection2.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection2.qml
new file mode 100644
index 000000000..4bcc6efaa
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection2.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "threshold"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real weight: parameters.get(0).value
+
+ fragmentShaderFilename: "shaders/sobeledgedetection2.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectTiltShift.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectTiltShift.qml
new file mode 100644
index 000000000..b1f214b07
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectTiltShift.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ fragmentShaderFilename: "shaders/tiltshift.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectToon.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectToon.qml
new file mode 100644
index 000000000..08f184997
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectToon.qml
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "threshold"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real threshold: parameters.get(0).value
+ property real targetSize: 250 - (200 * threshold) // TODO: fix ...
+ property real resS: targetSize
+ property real resT: targetSize
+
+ // TODO
+ property real magTol: 0.3
+ property real quantize: 8.0
+
+ fragmentShaderFilename: "shaders/toon.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectVignette.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectVignette.qml
new file mode 100644
index 000000000..11201616c
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectVignette.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ fragmentShaderFilename: "shaders/vignette.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectWarhol.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectWarhol.qml
new file mode 100644
index 000000000..e96d0524d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectWarhol.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ fragmentShaderFilename: "shaders/warhol.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectWobble.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectWobble.qml
new file mode 100644
index 000000000..4cccf48b8
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectWobble.qml
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "amplitude"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real amplitude: parameters.get(0).value * 0.05
+
+ property real frequency: 20
+ property real time: 0
+
+ NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 600 }
+
+ fragmentShaderFilename: "shaders/wobble.fsh"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml
new file mode 100644
index 000000000..9abbb294d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml
@@ -0,0 +1,384 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import Qt.labs.folderlistmodel 2.0
+
+Rectangle {
+ id: fileBrowser
+ color: "transparent"
+
+ property string folder
+ property bool shown: loader.sourceComponent
+
+ signal fileSelected(string file)
+
+ function selectFile(file) {
+ if (file != "")
+ folder = loader.item.folders.folder
+ loader.sourceComponent = undefined
+ fileBrowser.fileSelected(file)
+ }
+
+ Loader {
+ id: loader
+ }
+
+ function show() {
+ loader.sourceComponent = fileBrowserComponent
+ loader.item.parent = fileBrowser
+ loader.item.anchors.fill = fileBrowser
+ loader.item.folder = fileBrowser.folder
+ }
+
+ Component {
+ id: fileBrowserComponent
+
+ Rectangle {
+ id: root
+ color: "white"
+ property bool showFocusHighlight: false
+ property variant folders: folders1
+ property variant view: view1
+ property alias folder: folders1.folder
+ property color textColor: "black"
+
+ FolderListModel {
+ id: folders1
+ folder: folder
+ }
+
+ FolderListModel {
+ id: folders2
+ folder: folder
+ }
+
+ SystemPalette {
+ id: palette
+ }
+
+ Component {
+ id: folderDelegate
+
+ Rectangle {
+ id: wrapper
+ function launch() {
+ if (folders.isFolder(index))
+ down(filePath);
+ else
+ fileBrowser.selectFile(filePath)
+ }
+ width: root.width
+ height: 52
+ color: "transparent"
+
+ Rectangle {
+ id: highlight; visible: false
+ anchors.fill: parent
+ color: palette.highlight
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ }
+
+ Item {
+ width: 48; height: 48
+ Image {
+ source: "qrc:/images/folder.png"
+ anchors.centerIn: parent
+ visible: folders.isFolder(index)
+ }
+ }
+
+ Text {
+ id: nameText
+ anchors.fill: parent; verticalAlignment: Text.AlignVCenter
+ text: fileName
+ anchors.leftMargin: 54
+ font.pixelSize: 32
+ color: (wrapper.ListView.isCurrentItem && root.showFocusHighlight) ? palette.highlightedText : textColor
+ elide: Text.ElideRight
+ }
+
+ MouseArea {
+ id: mouseRegion
+ anchors.fill: parent
+ onPressed: {
+ root.showFocusHighlight = false;
+ wrapper.ListView.view.currentIndex = index;
+ }
+ onClicked: { if (folders == wrapper.ListView.view.model) launch() }
+ }
+
+ states: [
+ State {
+ name: "pressed"
+ when: mouseRegion.pressed
+ PropertyChanges { target: highlight; visible: true }
+ PropertyChanges { target: nameText; color: palette.highlightedText }
+ }
+ ]
+ }
+ }
+
+ Rectangle {
+ id: cancelButton
+ width: 100
+ height: titleBar.height - 7
+ color: "black"
+ anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter }
+
+ Text {
+ anchors { fill: parent; margins: 4 }
+ text: "Cancel"
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.pixelSize: 20
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: fileBrowser.selectFile("")
+ }
+ }
+
+ ListView {
+ id: view1
+ anchors.top: titleBar.bottom
+ anchors.bottom: cancelButton.top
+ x: 0
+ width: parent.width
+ model: folders1
+ delegate: folderDelegate
+ highlight: Rectangle {
+ color: palette.highlight
+ visible: root.showFocusHighlight && view1.count != 0
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ width: view1.currentItem == null ? 0 : view1.currentItem.width
+ }
+ highlightMoveVelocity: 1000
+ pressDelay: 100
+ focus: true
+ state: "current"
+ states: [
+ State {
+ name: "current"
+ PropertyChanges { target: view1; x: 0 }
+ },
+ State {
+ name: "exitLeft"
+ PropertyChanges { target: view1; x: -root.width }
+ },
+ State {
+ name: "exitRight"
+ PropertyChanges { target: view1; x: root.width }
+ }
+ ]
+ transitions: [
+ Transition {
+ to: "current"
+ SequentialAnimation {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ },
+ Transition {
+ NumberAnimation { properties: "x"; duration: 250 }
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ ]
+ Keys.onPressed: root.keyPressed(event.key)
+ }
+
+ ListView {
+ id: view2
+ anchors.top: titleBar.bottom
+ anchors.bottom: parent.bottom
+ x: parent.width
+ width: parent.width
+ model: folders2
+ delegate: folderDelegate
+ highlight: Rectangle {
+ color: palette.highlight
+ visible: root.showFocusHighlight && view2.count != 0
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ width: view1.currentItem == null ? 0 : view1.currentItem.width
+ }
+ highlightMoveVelocity: 1000
+ pressDelay: 100
+ states: [
+ State {
+ name: "current"
+ PropertyChanges { target: view2; x: 0 }
+ },
+ State {
+ name: "exitLeft"
+ PropertyChanges { target: view2; x: -root.width }
+ },
+ State {
+ name: "exitRight"
+ PropertyChanges { target: view2; x: root.width }
+ }
+ ]
+ transitions: [
+ Transition {
+ to: "current"
+ SequentialAnimation {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ },
+ Transition {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ ]
+ Keys.onPressed: root.keyPressed(event.key)
+ }
+
+ Keys.onPressed: {
+ root.keyPressed(event.key);
+ if (event.key == Qt.Key_Return || event.key == Qt.Key_Select || event.key == Qt.Key_Right) {
+ view.currentItem.launch();
+ event.accepted = true;
+ } else if (event.key == Qt.Key_Left) {
+ up();
+ }
+ }
+
+ BorderImage {
+ source: "qrc:/images/titlebar.sci";
+ width: parent.width;
+ height: 52
+ y: -7
+ id: titleBar
+
+ Rectangle {
+ id: upButton
+ width: 48
+ height: titleBar.height - 7
+ color: "transparent"
+ Image { anchors.centerIn: parent; source: "qrc:/images/up.png" }
+ MouseArea { id: upRegion; anchors.centerIn: parent
+ width: 56
+ height: 56
+ onClicked: if (folders.parentFolder != "") up()
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: upRegion.pressed
+ PropertyChanges { target: upButton; color: palette.highlight }
+ }
+ ]
+ }
+
+ Rectangle {
+ color: "gray"
+ x: 48
+ width: 1
+ height: 44
+ }
+
+ Text {
+ anchors.left: upButton.right; anchors.right: parent.right; height: parent.height
+ anchors.leftMargin: 4; anchors.rightMargin: 4
+ text: folders.folder
+ color: "white"
+ elide: Text.ElideLeft; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
+ font.pixelSize: 32
+ }
+ }
+
+ function down(path) {
+ if (folders == folders1) {
+ view = view2
+ folders = folders2;
+ view1.state = "exitLeft";
+ } else {
+ view = view1
+ folders = folders1;
+ view2.state = "exitLeft";
+ }
+ view.x = root.width;
+ view.state = "current";
+ view.focus = true;
+ folders.folder = path;
+ }
+
+ function up() {
+ var path = folders.parentFolder;
+ if (folders == folders1) {
+ view = view2
+ folders = folders2;
+ view1.state = "exitRight";
+ } else {
+ view = view1
+ folders = folders1;
+ view2.state = "exitRight";
+ }
+ view.x = -root.width;
+ view.state = "current";
+ view.focus = true;
+ folders.folder = path;
+ }
+
+ function keyPressed(key) {
+ switch (key) {
+ case Qt.Key_Up:
+ case Qt.Key_Down:
+ case Qt.Key_Left:
+ case Qt.Key_Right:
+ root.showFocusHighlight = true;
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileOpen.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileOpen.qml
new file mode 100644
index 000000000..d05ccea52
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileOpen.qml
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ color: "white"
+ property int buttonHeight: 35
+ property int topMargin: 0
+
+ signal openImage
+ signal openVideo
+ signal openCamera
+ signal close
+
+ Rectangle {
+ anchors {
+ top: parent.top;
+ topMargin: root.topMargin
+ bottom: parent.bottom;
+ horizontalCenter: parent.horizontalCenter
+ }
+ width: 0.9 * parent.width
+ color: "transparent"
+
+ Column {
+ anchors.fill: parent
+ spacing: 5
+ Button {
+ text: "Open image"
+ height: buttonHeight
+ width: parent.width
+ onClicked: root.openImage()
+ }
+ Button {
+ text: "Open video"
+ height: buttonHeight
+ width: parent.width
+ onClicked: root.openVideo()
+ }
+ Button {
+ text: "Start camera"
+ height: buttonHeight
+ width: parent.width
+ onClicked: root.openCamera()
+ }
+ Button {
+ text: "Reset"
+ height: buttonHeight
+ width: parent.width
+ onClicked: root.close()
+ }
+ }
+ }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/HintedMouseArea.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/HintedMouseArea.qml
new file mode 100644
index 000000000..22d28caf4
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/HintedMouseArea.qml
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Mouse area which flashes to indicate its location on the screen
+
+import QtQuick 2.0
+
+MouseArea {
+ property alias hintColor: hintRect.color
+ property bool hintEnabled: true
+
+ Rectangle {
+ id: hintRect
+ anchors.fill: parent
+ color: "yellow"
+ opacity: 0
+
+ states: [
+ State {
+ name: "high"
+ PropertyChanges {
+ target: hintRect
+ opacity: 0.8
+ }
+ },
+ State {
+ name: "low"
+ PropertyChanges {
+ target: hintRect
+ opacity: 0.4
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "low"
+ to: "high"
+ SequentialAnimation {
+ NumberAnimation {
+ properties: "opacity"
+ easing.type: Easing.InOutSine
+ duration: 500
+ }
+ ScriptAction { script: hintRect.state = "low" }
+ }
+ },
+ Transition {
+ from: "*"
+ to: "low"
+ SequentialAnimation {
+ NumberAnimation {
+ properties: "opacity"
+ easing.type: Easing.InOutSine
+ duration: 500
+ }
+ ScriptAction { script: hintRect.state = "high" }
+ }
+ },
+ Transition {
+ from: "*"
+ to: "baseState"
+ NumberAnimation {
+ properties: "opacity"
+ easing.type: Easing.InOutSine
+ duration: 500
+ }
+ }
+ ]
+ }
+
+ onHintEnabledChanged: hintRect.state = hintEnabled ? "low" : "baseState"
+
+ Component.onCompleted: hintRect.state = "low"
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ParameterPanel.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ParameterPanel.qml
new file mode 100644
index 000000000..1ce0c87ba
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ParameterPanel.qml
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ color: "transparent"
+ height: view.model.count * sliderHeight
+ property color lineColor: "black"
+ property real gripSize: 25
+ property real spacing: 10
+ property real sliderHeight: 40
+
+ property ListModel model: ListModel { }
+
+ Rectangle {
+ anchors.fill: parent
+ color: "black"
+ opacity: 0.5
+ radius: 10
+ }
+
+ Component {
+ id: editDelegate
+
+ Rectangle {
+ id: delegate
+ width: parent.width
+ height: root.sliderHeight
+ color: "transparent"
+
+ Text {
+ id: text
+ text: name
+ color: "white"
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ left: parent.left
+ }
+ font.pixelSize: 0.5 * parent.height
+ horizontalAlignment: Text.AlignRight
+ verticalAlignment: Text.AlignVCenter
+ width: 150
+ }
+
+ Slider {
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ left: text.right
+ leftMargin: 20
+ right: parent.right
+ rightMargin: 20
+ }
+ gripSize: root.gripSize
+ value: model.value
+ onValueChanged: view.model.setProperty(index, "value", value)
+ }
+ }
+ }
+
+ ListView {
+ id: view
+ anchors.fill: parent
+ model: root.model
+ delegate: editDelegate
+ interactive: false
+ }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Slider.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Slider.qml
new file mode 100644
index 000000000..f3a7acd08
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Slider.qml
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ color: "transparent"
+ radius: 5
+ property alias value: grip.value
+ property color fillColor: "white"
+ property color lineColor: "black"
+ property color gripColor: "white"
+ property real gripSize: 20
+ property real gripTolerance: 3.0
+ property real increment: 0.1
+ property bool enabled: true
+
+ Rectangle {
+ anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter }
+ height: 3
+ color: displayedColor(root.lineColor)
+
+ Rectangle {
+ anchors { fill: parent; margins: 1 }
+ color: root.fillColor
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ enabled: root.enabled
+ onClicked: {
+ if (parent.width) {
+ var newValue = mouse.x / parent.width
+ if (Math.abs(newValue - parent.value) > parent.increment) {
+ if (newValue > parent.value)
+ parent.value = Math.min(1.0, parent.value + parent.increment)
+ else
+ parent.value = Math.max(0.0, parent.value - parent.increment)
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ id: grip
+ property real value: 0.5
+ x: (value * parent.width) - width/2
+ anchors.verticalCenter: parent.verticalCenter
+ width: root.gripTolerance * root.gripSize
+ height: width
+ radius: width/2
+ color: "transparent"
+
+ MouseArea {
+ id: mouseArea
+ enabled: root.enabled
+ anchors.fill: parent
+ drag {
+ target: grip
+ axis: Drag.XAxis
+ minimumX: -parent.width/2
+ maximumX: root.width - parent.width/2
+ }
+ onPositionChanged: {
+ if (drag.active)
+ updatePosition()
+ }
+ onReleased: {
+ updatePosition()
+ }
+ function updatePosition() {
+ value = (grip.x + grip.width/2) / grip.parent.width
+ }
+ }
+
+ Rectangle {
+ anchors.centerIn: parent
+ width: root.gripSize
+ height: width
+ radius: width/2
+ color: root.gripColor
+ }
+ }
+
+ function displayedColor(c) {
+ var tint = Qt.rgba(c.r, c.g, c.b, 0.25)
+ return enabled ? c : Qt.tint(c, tint)
+ }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-largescreen.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-largescreen.qml
new file mode 100644
index 000000000..772a86908
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-largescreen.qml
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ width: 900
+ height: 600
+ color: "grey"
+ property string fileName
+ property alias volume: content.volume
+ property bool perfMonitorsLogging: false
+ property bool perfMonitorsVisible: false
+
+ QtObject {
+ id: d
+ property real gripSize: 20
+ }
+
+ Rectangle {
+ id: inner
+ anchors.fill: parent
+ color: "grey"
+
+ Content {
+ id: content
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ left: parent.left
+ right: effectSelectionPanel.left
+ margins: 5
+ }
+ gripSize: d.gripSize
+ width: 600
+ height: 600
+ }
+
+ Loader {
+ id: performanceLoader
+ function init() {
+ console.log("[qmlvideofx] performanceLoader.init logging " + root.perfMonitorsLogging + " visible " + root.perfMonitorsVisible)
+ var enabled = root.perfMonitorsLogging || root.perfMonitorsVisible
+ source = enabled ? "../performancemonitor/PerformanceItem.qml" : ""
+ }
+ onLoaded: {
+ item.parent = content
+ item.anchors.top = content.top
+ item.anchors.left = content.left
+ item.anchors.right = content.right
+ item.logging = root.perfMonitorsLogging
+ item.displayed = root.perfMonitorsVisible
+ item.init()
+ }
+ }
+
+ ParameterPanel {
+ id: parameterPanel
+ anchors {
+ left: parent.left
+ bottom: parent.bottom
+ right: effectSelectionPanel.left
+ margins: 20
+ }
+ gripSize: d.gripSize
+ }
+
+ EffectSelectionPanel {
+ id: effectSelectionPanel
+ anchors {
+ top: parent.top
+ bottom: fileOpen.top
+ right: parent.right
+ margins: 5
+ }
+ width: 300
+ itemHeight: 40
+ onEffectSourceChanged: {
+ content.effectSource = effectSource
+ parameterPanel.model = content.effect.parameters
+ }
+ }
+
+ FileOpen {
+ id: fileOpen
+ anchors {
+ right: parent.right
+ bottom: parent.bottom
+ margins: 5
+ }
+ width: effectSelectionPanel.width
+ height: 165
+ buttonHeight: 32
+ topMargin: 10
+ }
+ }
+
+ FileBrowser {
+ id: imageFileBrowser
+ anchors.fill: root
+ Component.onCompleted: fileSelected.connect(content.openImage)
+ }
+
+ FileBrowser {
+ id: videoFileBrowser
+ anchors.fill: root
+ Component.onCompleted: fileSelected.connect(content.openVideo)
+ }
+
+ Component.onCompleted: {
+ fileOpen.openImage.connect(openImage)
+ fileOpen.openVideo.connect(openVideo)
+ fileOpen.openCamera.connect(openCamera)
+ fileOpen.close.connect(close)
+ }
+
+ function init() {
+ console.log("[qmlvideofx] main.init")
+ imageFileBrowser.folder = imagePath
+ videoFileBrowser.folder = videoPath
+ content.init()
+ performanceLoader.init()
+ if (fileName != "")
+ content.openVideo(fileName)
+ }
+
+ function qmlFramePainted() {
+ if (performanceLoader.item)
+ performanceLoader.item.qmlFramePainted()
+ }
+
+ function openImage() {
+ imageFileBrowser.show()
+ }
+
+ function openVideo() {
+ videoFileBrowser.show()
+ }
+
+ function openCamera() {
+ content.openCamera()
+ }
+
+ function close() {
+ content.openImage("qrc:/images/qt-logo.png")
+ }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-smallscreen.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-smallscreen.qml
new file mode 100644
index 000000000..59a0c994c
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-smallscreen.qml
@@ -0,0 +1,408 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ width: 640
+ height: 360
+ color: "grey"
+ property string fileName
+ property alias volume: content.volume
+ property bool perfMonitorsLogging: false
+ property bool perfMonitorsVisible: false
+
+ QtObject {
+ id: d
+ property bool dialogShown: (fileOpenContainer.state == "shown" ||
+ effectSelectionPanel.state == "shown" ||
+ videoFileBrowser.shown ||
+ imageFileBrowser.shown)
+ property real gripSize: 40
+ }
+
+ // Create ScreenSaver element via Loader, so this app will still run if the
+ // SystemInfo module is not available
+ Loader {
+ source: "DisableScreenSaver.qml"
+ }
+
+ Loader {
+ id: performanceLoader
+
+ Connections {
+ target: d
+ onDialogShownChanged:
+ if (performanceLoader.item)
+ performanceLoader.item.enabled = !d.dialogShown
+ ignoreUnknownSignals: true
+ }
+
+ function init() {
+ console.log("[qmlvideofx] performanceLoader.init logging " + root.perfMonitorsLogging + " visible " + root.perfMonitorsVisible)
+ var enabled = root.perfMonitorsLogging || root.perfMonitorsVisible
+ source = enabled ? "../performancemonitor/PerformanceItem.qml" : ""
+ }
+
+ onLoaded: {
+ item.parent = root
+ item.anchors.top = root.top
+ item.anchors.left = root.left
+ item.logging = root.perfMonitorsLogging
+ item.displayed = root.perfMonitorsVisible
+ item.init()
+ }
+ }
+
+ Rectangle {
+ id: inner
+ anchors.fill: parent
+ color: "grey"
+
+ Content {
+ id: content
+ anchors.fill: parent
+ gripSize: d.gripSize
+ onVideoFramePainted: performanceLoader.item.videoFramePainted()
+ }
+
+ ParameterPanel {
+ id: parameterPanel
+ anchors {
+ left: parent.left;
+ right: parent.right;
+ margins: 10
+ }
+ y: parent.height
+ gripSize: d.gripSize
+
+ states: [
+ State {
+ name: "shown"
+ PropertyChanges {
+ target: parameterPanel
+ y: parent.height - (parameterPanel.height + 10)
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "*"
+ to: "*"
+ NumberAnimation {
+ properties: "y"
+ easing.type: Easing.OutQuart
+ duration: 500
+ }
+ }
+ ]
+
+ state: (enabled && !d.dialogShown) ? "shown" : "baseState"
+ }
+
+ EffectSelectionPanel {
+ id: effectSelectionPanel
+ anchors {
+ top: parent.top;
+ bottom: parameterPanel.top;
+ margins: 10
+ }
+ x: parent.width
+ width: parent.width - 40
+ opacity: 0.75
+ radius: 20
+ itemHeight: 50
+
+ states: [
+ State {
+ name: "shown"
+ PropertyChanges {
+ target: effectSelectionPanel
+ x: 20
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "*"
+ to: "*"
+ NumberAnimation {
+ properties: "x"
+ easing.type: Easing.OutQuart
+ duration: 500
+ }
+ }
+ ]
+
+ onEffectSourceChanged: {
+ content.effectSource = effectSource
+ if (content.effect.parameters.count) {
+ parameterPanel.model = content.effect.parameters
+ parameterPanel.enabled = true
+ } else {
+ parameterPanel.enabled = false
+ }
+ }
+
+ onClicked: state = "baseState"
+ }
+
+ Rectangle {
+ id: fileOpenContainer
+ anchors {
+ top: parent.top
+ bottom: parameterPanel.top
+ margins: 10
+ }
+ x: -width
+ width: parent.width - 40
+ color: "transparent"
+
+ Column {
+ anchors.fill: parent
+
+ FileOpen {
+ id: fileOpen
+ color: "transparent"
+ width: parent.width
+ height: 200
+ opacity: 0.75
+ radius: 20
+ buttonHeight: 40
+ }
+
+ MouseArea {
+ width: parent.width
+ height: 250
+ onClicked: fileOpenContainer.state = "baseState"
+ }
+ }
+
+ states: [
+ State {
+ name: "shown"
+ PropertyChanges {
+ target: fileOpenContainer
+ x: 20
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "*"
+ to: "*"
+ NumberAnimation {
+ properties: "x"
+ easing.type: Easing.OutQuart
+ duration: 500
+ }
+ }
+ ]
+ }
+
+ Rectangle {
+ id: splashScreen
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ verticalCenter: parent.verticalCenter
+ }
+ width: 300
+ height: 200
+ radius: 0.1 * height
+ color: "white"
+ opacity: 0.9
+ border { color: "black"; width: 2 }
+
+ Text {
+ anchors {
+ fill: parent
+ margins: 5
+ }
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.pixelSize: 24
+ text: "Tap on left side to switch between sources.\n\nTap on right side to switch between effects."
+ wrapMode: Text.WordWrap
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: parent.state = "hidden"
+ }
+
+ states: [
+ State {
+ name: "hidden"
+ PropertyChanges {
+ target: splashScreen
+ opacity: 0.0
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "*"
+ to: "*"
+ NumberAnimation {
+ properties: "opacity"
+ easing.type: Easing.OutQuart
+ duration: 500
+ }
+ }
+ ]
+ }
+
+ HintedMouseArea {
+ id: fileOpenMouseArea
+ anchors {
+ left: parent.left;
+ top: parent.top;
+ bottom: parameterPanel.top;
+ topMargin: 75
+ }
+ width: 100
+ onClicked: {
+ fileOpenMouseArea.hintEnabled = false
+ effectSelectionPanelMouseArea.hintEnabled = false
+ splashScreen.state = "hidden"
+ fileOpenContainer.state = "shown"
+ }
+ enabled: !d.dialogShown
+ }
+
+ HintedMouseArea {
+ id: effectSelectionPanelMouseArea
+ anchors {
+ right: parent.right;
+ top: parent.top;
+ bottom: parameterPanel.top;
+ topMargin: 75
+ }
+ width: 100
+ onClicked: {
+ fileOpenMouseArea.hintEnabled = false
+ effectSelectionPanelMouseArea.hintEnabled = false
+ splashScreen.state = "hidden"
+ effectSelectionPanel.state = "shown"
+ }
+ enabled: !d.dialogShown
+ }
+
+ Image {
+ source: "qrc:/images/close.png"
+
+ anchors {
+ top: parent.top
+ right: parent.right
+ margins: 5
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: Qt.quit()
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ fileOpen.openImage.connect(openImage)
+ fileOpen.openVideo.connect(openVideo)
+ fileOpen.openCamera.connect(openCamera)
+ fileOpen.close.connect(close)
+ }
+
+ FileBrowser {
+ id: imageFileBrowser
+ anchors.fill: root
+ Component.onCompleted: fileSelected.connect(content.openImage)
+ }
+
+ FileBrowser {
+ id: videoFileBrowser
+ anchors.fill: root
+ Component.onCompleted: fileSelected.connect(content.openVideo)
+ }
+
+ // Called from main() once root properties have been set
+ function init() {
+ console.log("[qmlvideofx] main.init")
+ imageFileBrowser.folder = imagePath
+ videoFileBrowser.folder = videoPath
+ content.init()
+ performanceLoader.init()
+ if (fileName != "") {
+ fileOpenMouseArea.hintEnabled = false
+ effectSelectionPanelMouseArea.hintEnabled = false
+ splashScreen.state = "hidden"
+ content.openVideo(fileName)
+ }
+ }
+
+ function qmlFramePainted() {
+ if (performanceLoader.item)
+ performanceLoader.item.qmlFramePainted()
+ }
+
+ function openImage() {
+ fileOpenContainer.state = "baseState"
+ imageFileBrowser.show()
+ }
+
+ function openVideo() {
+ fileOpenContainer.state = "baseState"
+ videoFileBrowser.show()
+ }
+
+ function openCamera() {
+ fileOpenContainer.state = "baseState"
+ content.openCamera()
+ }
+
+ function close() {
+ fileOpenContainer.state = "baseState"
+ content.openImage("qrc:/images/qt-logo.png")
+ }
+}
diff --git a/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.cpp b/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.cpp
new file mode 100644
index 000000000..2ffc0b219
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlapplicationviewer.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtQml/QQmlComponent>
+#include <QtQml/QQmlEngine>
+#include <QtQml/QQmlContext>
+#include <QtGui/QGuiApplication>
+
+class QmlApplicationViewerPrivate
+{
+ QmlApplicationViewerPrivate(QQuickView *view_) : view(view_) {}
+
+ QString mainQmlFile;
+ QQuickView *view;
+ friend class QmlApplicationViewer;
+ QString adjustPath(const QString &path);
+};
+
+QString QmlApplicationViewerPrivate::adjustPath(const QString &path)
+{
+#ifdef Q_OS_UNIX
+#ifdef Q_OS_MAC
+ if (!QDir::isAbsolutePath(path))
+ return QCoreApplication::applicationDirPath()
+ + QLatin1String("/../Resources/") + path;
+#else
+ QString pathInInstallDir;
+ const QString applicationDirPath = QCoreApplication::applicationDirPath();
+ pathInInstallDir = QString::fromLatin1("%1/../%2").arg(applicationDirPath, path);
+
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+#endif
+#endif
+ return path;
+}
+
+QmlApplicationViewer::QmlApplicationViewer(QWindow *parent)
+ : QQuickView(parent)
+ , d(new QmlApplicationViewerPrivate(this))
+{
+ connect(engine(), SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
+ setResizeMode(QQuickView::SizeRootObjectToView);
+}
+
+QmlApplicationViewer::QmlApplicationViewer(QQuickView *view, QWindow *parent)
+ : QQuickView(parent)
+ , d(new QmlApplicationViewerPrivate(view))
+{
+ connect(view->engine(), SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
+ view->setResizeMode(QQuickView::SizeRootObjectToView);
+}
+
+QmlApplicationViewer::~QmlApplicationViewer()
+{
+ delete d;
+}
+
+QmlApplicationViewer *QmlApplicationViewer::create()
+{
+ return new QmlApplicationViewer();
+}
+
+void QmlApplicationViewer::setMainQmlFile(const QString &file)
+{
+ d->mainQmlFile = d->adjustPath(file);
+ d->view->setSource(QUrl::fromLocalFile(d->mainQmlFile));
+}
+
+void QmlApplicationViewer::addImportPath(const QString &path)
+{
+ d->view->engine()->addImportPath(d->adjustPath(path));
+}
+
+void QmlApplicationViewer::showExpanded()
+{
+#if defined(Q_WS_SIMULATOR)
+ d->view->showFullScreen();
+#else
+ d->view->show();
+#endif
+}
+
+QGuiApplication *createApplication(int &argc, char **argv)
+{
+ return new QGuiApplication(argc, argv);
+}
diff --git a/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.h b/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.h
new file mode 100644
index 000000000..a4eabdba8
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLAPPLICATIONVIEWER_H
+#define QMLAPPLICATIONVIEWER_H
+
+#include <QtQuick/QQuickView>
+#include <QtGui/QGuiApplication>
+
+class QmlApplicationViewer : public QQuickView
+{
+ Q_OBJECT
+
+public:
+ explicit QmlApplicationViewer(QWindow *parent = 0);
+ virtual ~QmlApplicationViewer();
+
+ static QmlApplicationViewer *create();
+
+ void setMainQmlFile(const QString &file);
+ void addImportPath(const QString &path);
+
+ void showExpanded();
+
+private:
+ explicit QmlApplicationViewer(QQuickView *view, QWindow *parent);
+ class QmlApplicationViewerPrivate *d;
+};
+
+QGuiApplication *createApplication(int &argc, char **argv);
+
+#endif // QMLAPPLICATIONVIEWER_H
diff --git a/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.pri b/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.pri
new file mode 100644
index 000000000..d9807943e
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.pri
@@ -0,0 +1,7 @@
+QT += quick
+
+SOURCES += $$PWD/qmlapplicationviewer.cpp
+HEADERS += $$PWD/qmlapplicationviewer.h
+INCLUDEPATH += $$PWD
+
+
diff --git a/examples/multimedia/video/qmlvideofx/qmlvideofx.png b/examples/multimedia/video/qmlvideofx/qmlvideofx.png
new file mode 100644
index 000000000..707d5c4e8
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qmlvideofx.png
Binary files differ
diff --git a/examples/multimedia/video/qmlvideofx/qmlvideofx.pro b/examples/multimedia/video/qmlvideofx/qmlvideofx.pro
new file mode 100644
index 000000000..7779565f5
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qmlvideofx.pro
@@ -0,0 +1,23 @@
+TEMPLATE = app
+TARGET = qmlvideofx
+
+LOCAL_SOURCES = filereader.cpp main.cpp
+LOCAL_HEADERS = filereader.h trace.h
+
+SOURCES += $$LOCAL_SOURCES
+HEADERS += $$LOCAL_HEADERS
+
+RESOURCES += qmlvideofx.qrc
+
+SNIPPETS_PATH = ../snippets
+include($$SNIPPETS_PATH/performancemonitor/performancemonitordeclarative.pri)
+
+maemo6: {
+ DEFINES += SMALL_SCREEN_LAYOUT
+ DEFINES += SMALL_SCREEN_PHYSICAL
+}
+
+include(qmlapplicationviewer/qmlapplicationviewer.pri)
+
+target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/video/qmlvideofx
+INSTALLS += target
diff --git a/examples/multimedia/video/qmlvideofx/qmlvideofx.qrc b/examples/multimedia/video/qmlvideofx/qmlvideofx.qrc
new file mode 100644
index 000000000..6ca4ef54b
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qmlvideofx.qrc
@@ -0,0 +1,10 @@
+<RCC>
+ <qresource prefix="/images">
+ <file alias="close.png">images/close.png</file>
+ <file alias="folder.png">images/folder.png</file>
+ <file alias="titlebar.png">images/titlebar.png</file>
+ <file alias="titlebar.sci">images/titlebar.sci</file>
+ <file alias="up.png">images/up.png</file>
+ <file alias="qt-logo.png">images/qt-logo.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/multimedia/video/qmlvideofx/qmlvideofx.svg b/examples/multimedia/video/qmlvideofx/qmlvideofx.svg
new file mode 100644
index 000000000..566acfada
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/qmlvideofx.svg
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="44px"
+ version="1.1"
+ viewBox="0 0 44 44"
+ width="44px"
+ x="0px"
+ y="0px"
+ id="svg2"
+ inkscape:version="0.47 r22583"
+ sodipodi:docname="qt.svg">
+ <metadata
+ id="metadata18">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs16">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 22 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="44 : 22 : 1"
+ inkscape:persp3d-origin="22 : 14.666667 : 1"
+ id="perspective2836" />
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1020"
+ id="namedview14"
+ showgrid="false"
+ inkscape:zoom="21.454545"
+ inkscape:cx="49.412871"
+ inkscape:cy="21.894358"
+ inkscape:window-x="-4"
+ inkscape:window-y="-4"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g3" />
+ <g
+ transform="matrix(0.18308778,0,0,0.18308778,6.6100946,3.2385199)"
+ id="g3">
+ <path
+ d="M 43.09,0.3586 C 40.94,0.0036 38.84,-0.0824 36.81,0.0776 31.968136,0.39505671 27.122677,0.73638425 22.28,1.0696 9.62,2.0816 0,12.4996 0,26.8896 l 0,169.7 14.19,13.2 28.87,-209.42 0.03,-0.011 z"
+ style="fill:#006225"
+ id="path5"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ d="m 174.4,160 c 0,12.5 -7.75,24.07 -17.57,25.77 L 14.23,209.73 V 25.93 C 14.23,9.21 27.57,-2.27 43.12,0.3 l 131.3,21.52 v 138.2 z"
+ style="fill:#80c342"
+ id="path7" />
+ <path
+ d="m 154.9,80.96 -12.96,-0.598 0,0.278 6.945,0.32 6.016,0 z"
+ style="fill:#006225"
+ id="path11" />
+ <path
+ d="m 144.6,135.6 c 0.66,0.328 1.43,0.476 2.351,0.476 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 h -6.015 c -1.821,0.832 -3.532,1.457 -5.176,1.848 z"
+ style="fill:#006225"
+ id="path13" />
+ <path
+ id="path17"
+ style="fill:#ffffff"
+ d="m 91.15,132.4 c 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -4.34,0 -7.68,2.535 -10.01,7.625 -2.52,5.543 -3.793,17.04 -3.793,34.44 0,16.82 1.238,28.75 3.734,35.75 2.356,6.672 5.879,9.976 10.5,9.976 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 m 17.98,3.75 c -4.117,9.707 -10.39,16.06 -18.99,19 0.867,4.449 2.176,7.441 3.922,9.019 1.351,1.211 3.433,1.821 6.222,1.821 0.805,0 1.668,-0.055 2.59,-0.157 v 13.12 l -5.961,0.782 c -1.758,0.23 -3.426,0.343 -5.004,0.343 -5.218,0 -9.445,-1.265 -12.62,-3.824 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 1.629,0 3.309,0.102 5.043,0.305 11.95,1.375 20.62,7.016 26.26,16.79 5.535,9.562 8.254,23.27 8.254,41.26 0,16.48 -2,29.45 -6.043,39.02 z M 130.4,45.91 l 11.52,1.238 0,20.21 12.96,0.914 0,12.68 -12.96,-0.598 0,46.33 c 0,4.032 0.445,6.625 1.34,7.789 0.8,1.067 2.046,1.594 3.71,1.594 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 v 11.65 c -5.136,2.258 -10.18,3.598 -15.12,4.02 -0.718,0.055 -1.41,0.086 -2.078,0.086 -4.48,0 -7.906,-1.301 -10.25,-3.934 -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.535 L 118.046,79.25 V 65.66 l 7.586,0.547 4.773,-20.3 z" />
+ <path
+ d="m 100.3,166 c 0.809,0 1.672,-0.055 2.59,-0.157 H 98.054 C 98.73,165.949 99.507,166 100.3,166 z"
+ style="fill:#006225"
+ id="path19" />
+ <path
+ id="path21"
+ style="fill:#006225"
+ d="m 84.85,63.98 c 2.336,5.997 3.484,16.92 3.484,32.81 0,17.7 -1.16,29.57 -3.512,35.62 -1.894,4.879 -4.527,7.902 -7.863,9.07 0.965,0.368 1.992,0.551 3.078,0.551 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -1.09,0 -2.117,0.16 -3.082,0.481 h -0.004 c 3.601,1.121 6.379,4.215 8.336,9.261 z m -2.344,114.3 c -0.113,-0.05 -0.227,-0.105 -0.336,-0.16 -0.012,-0.004 -0.023,-0.012 -0.035,-0.015 -0.102,-0.051 -0.207,-0.106 -0.309,-0.157 -0.019,-0.011 -0.039,-0.019 -0.058,-0.031 -0.09,-0.051 -0.184,-0.098 -0.278,-0.148 -0.027,-0.016 -0.054,-0.036 -0.086,-0.051 -0.082,-0.043 -0.164,-0.09 -0.242,-0.137 -0.039,-0.023 -0.078,-0.047 -0.113,-0.07 -0.07,-0.039 -0.145,-0.082 -0.215,-0.125 -0.047,-0.031 -0.094,-0.059 -0.14,-0.09 -0.059,-0.039 -0.118,-0.074 -0.176,-0.113 -0.059,-0.039 -0.114,-0.075 -0.168,-0.114 -0.051,-0.031 -0.102,-0.066 -0.149,-0.097 -0.066,-0.047 -0.132,-0.094 -0.195,-0.137 -0.039,-0.027 -0.078,-0.055 -0.113,-0.082 -0.078,-0.055 -0.153,-0.113 -0.231,-0.172 -0.023,-0.016 -0.05,-0.035 -0.078,-0.055 -0.098,-0.078 -0.199,-0.156 -0.297,-0.234 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 h -6.351 c -10.15,0.008 -18.22,3.977 -24,12.04 -6.855,9.563 -10.34,24.64 -10.34,45.07 0,18.95 2.547,33.44 7.551,43.34 4.934,9.75 12.05,15.56 21.19,17.5 1.989,9.641 5.09,16.16 9.297,19.54 3.176,2.559 7.403,3.824 12.62,3.824 0.098,0 0.199,0 0.297,-0.004 h 5.539 c -3.406,-0.05 -6.383,-0.66 -8.906,-1.828 L 82.498,178.28 z M 128.4,145.6 c -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.57 l -6.226,-0.285 v -13.59 h -6.016 v 3.035 c 0.871,3.273 1.555,6.82 2.063,10.64 l 4.164,0.192 v 51.36 c 0,6.723 1.367,11.62 4.09,14.67 2.343,2.633 5.765,3.934 10.25,3.934 h 6.015 c -4.48,0 -7.906,-1.301 -10.25,-3.934 z m 2.043,-99.66 -6.016,0 -4.668,19.88 5.911,0.422 4.773,-20.3 z" />
+ </g>
+</svg>
diff --git a/examples/multimedia/video/qmlvideofx/shaders/billboard.fsh b/examples/multimedia/video/qmlvideofx/shaders/billboard.fsh
new file mode 100644
index 000000000..baa955432
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/billboard.fsh
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://kodemongki.blogspot.com/2011/06/kameraku-custom-shader-effects-example.html
+
+uniform float grid;
+uniform float dividerValue;
+uniform float step_x;
+uniform float step_y;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ float offx = floor(uv.x / (grid * step_x));
+ float offy = floor(uv.y / (grid * step_y));
+ vec3 res = texture2D(source, vec2(offx * grid * step_x , offy * grid * step_y)).rgb;
+ vec2 prc = fract(uv / vec2(grid * step_x, grid * step_y));
+ vec2 pw = pow(abs(prc - 0.5), vec2(2.0));
+ float rs = pow(0.45, 2.0);
+ float gr = smoothstep(rs - 0.1, rs + 0.1, pw.x + pw.y);
+ float y = (res.r + res.g + res.b) / 3.0;
+ vec3 ra = res / y;
+ float ls = 0.3;
+ float lb = ceil(y / ls);
+ float lf = ls * lb + 0.3;
+ res = lf * res;
+ vec3 col = mix(res, vec3(0.1, 0.1, 0.1), gr);
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ else
+ gl_FragColor = qt_Opacity * texture2D(source, uv);
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/blackandwhite.fsh b/examples/multimedia/video/qmlvideofx/shaders/blackandwhite.fsh
new file mode 100644
index 000000000..40756c42f
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/blackandwhite.fsh
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://kodemongki.blogspot.com/2011/06/kameraku-custom-shader-effects-example.html
+
+uniform float threshold;
+uniform float dividerValue;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 orig = texture2D(source, uv);
+ vec3 col = orig.rgb;
+ float y = 0.3 *col.r + 0.59 * col.g + 0.11 * col.b;
+ y = y < threshold ? 0.0 : 1.0;
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(y, y, y, 1.0);
+ else
+ gl_FragColor = qt_Opacity * orig;
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/emboss.fsh b/examples/multimedia/video/qmlvideofx/shaders/emboss.fsh
new file mode 100644
index 000000000..bd13a0b5e
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/emboss.fsh
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://kodemongki.blogspot.com/2011/06/kameraku-custom-shader-effects-example.html
+
+uniform float dividerValue;
+const float step_w = 0.0015625;
+const float step_h = 0.0027778;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec3 t1 = texture2D(source, vec2(uv.x - step_w, uv.y - step_h)).rgb;
+ vec3 t2 = texture2D(source, vec2(uv.x, uv.y - step_h)).rgb;
+ vec3 t3 = texture2D(source, vec2(uv.x + step_w, uv.y - step_h)).rgb;
+ vec3 t4 = texture2D(source, vec2(uv.x - step_w, uv.y)).rgb;
+ vec3 t5 = texture2D(source, uv).rgb;
+ vec3 t6 = texture2D(source, vec2(uv.x + step_w, uv.y)).rgb;
+ vec3 t7 = texture2D(source, vec2(uv.x - step_w, uv.y + step_h)).rgb;
+ vec3 t8 = texture2D(source, vec2(uv.x, uv.y + step_h)).rgb;
+ vec3 t9 = texture2D(source, vec2(uv.x + step_w, uv.y + step_h)).rgb;
+ vec3 rr = -4.0 * t1 - 4.0 * t2 - 4.0 * t4 + 12.0 * t5;
+ float y = (rr.r + rr.g + rr.b) / 3.0;
+ vec3 col = vec3(y, y, y) + 0.3;
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ else
+ gl_FragColor = qt_Opacity * texture2D(source, uv);
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/gaussianblur_h.fsh b/examples/multimedia/video/qmlvideofx/shaders/gaussianblur_h.fsh
new file mode 100644
index 000000000..96ae8e43c
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/gaussianblur_h.fsh
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+uniform float dividerValue;
+uniform float blurSize;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 c = vec4(0.0);
+ if (uv.x < dividerValue) {
+ c += texture2D(source, uv - vec2(4.0*blurSize, 0.0)) * 0.05;
+ c += texture2D(source, uv - vec2(3.0*blurSize, 0.0)) * 0.09;
+ c += texture2D(source, uv - vec2(2.0*blurSize, 0.0)) * 0.12;
+ c += texture2D(source, uv - vec2(1.0*blurSize, 0.0)) * 0.15;
+ c += texture2D(source, uv) * 0.18;
+ c += texture2D(source, uv + vec2(1.0*blurSize, 0.0)) * 0.15;
+ c += texture2D(source, uv + vec2(2.0*blurSize, 0.0)) * 0.12;
+ c += texture2D(source, uv + vec2(3.0*blurSize, 0.0)) * 0.09;
+ c += texture2D(source, uv + vec2(4.0*blurSize, 0.0)) * 0.05;
+ } else {
+ c = texture2D(source, qt_TexCoord0);
+ }
+ gl_FragColor = qt_Opacity * c;
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/gaussianblur_v.fsh b/examples/multimedia/video/qmlvideofx/shaders/gaussianblur_v.fsh
new file mode 100644
index 000000000..6bc7b8b74
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/gaussianblur_v.fsh
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+uniform float dividerValue;
+uniform float blurSize;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 c = vec4(0.0);
+ if (uv.x < dividerValue) {
+ c += texture2D(source, uv - vec2(0.0, 4.0*blurSize)) * 0.05;
+ c += texture2D(source, uv - vec2(0.0, 3.0*blurSize)) * 0.09;
+ c += texture2D(source, uv - vec2(0.0, 2.0*blurSize)) * 0.12;
+ c += texture2D(source, uv - vec2(0.0, 1.0*blurSize)) * 0.15;
+ c += texture2D(source, uv) * 0.18;
+ c += texture2D(source, uv + vec2(0.0, 1.0*blurSize)) * 0.15;
+ c += texture2D(source, uv + vec2(0.0, 2.0*blurSize)) * 0.12;
+ c += texture2D(source, uv + vec2(0.0, 3.0*blurSize)) * 0.09;
+ c += texture2D(source, uv + vec2(0.0, 4.0*blurSize)) * 0.05;
+ } else {
+ c = texture2D(source, qt_TexCoord0);
+ }
+ // First pass we don't apply opacity
+ gl_FragColor = c;
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/glow.fsh b/examples/multimedia/video/qmlvideofx/shaders/glow.fsh
new file mode 100644
index 000000000..e0adcfd65
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/glow.fsh
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://kodemongki.blogspot.com/2011/06/kameraku-custom-shader-effects-example.html
+
+uniform float dividerValue;
+const float step_w = 0.0015625;
+const float step_h = 0.0027778;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec3 t1 = texture2D(source, vec2(uv.x - step_w, uv.y - step_h)).rgb;
+ vec3 t2 = texture2D(source, vec2(uv.x, uv.y - step_h)).rgb;
+ vec3 t3 = texture2D(source, vec2(uv.x + step_w, uv.y - step_h)).rgb;
+ vec3 t4 = texture2D(source, vec2(uv.x - step_w, uv.y)).rgb;
+ vec3 t5 = texture2D(source, uv).rgb;
+ vec3 t6 = texture2D(source, vec2(uv.x + step_w, uv.y)).rgb;
+ vec3 t7 = texture2D(source, vec2(uv.x - step_w, uv.y + step_h)).rgb;
+ vec3 t8 = texture2D(source, vec2(uv.x, uv.y + step_h)).rgb;
+ vec3 t9 = texture2D(source, vec2(uv.x + step_w, uv.y + step_h)).rgb;
+ vec3 xx = t1 + 2.0*t2 + t3 - t7 - 2.0*t8 - t9;
+ vec3 yy = t1 - t3 + 2.0*t4 - 2.0*t6 + t7 - t9;
+ vec3 rr = sqrt(xx * xx + yy * yy);
+ vec3 col = rr * 2.0 * t5;
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ else
+ gl_FragColor = qt_Opacity * texture2D(source, uv);
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/isolate.fsh b/examples/multimedia/video/qmlvideofx/shaders/isolate.fsh
new file mode 100644
index 000000000..0f25bfab3
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/isolate.fsh
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://kodemongki.blogspot.com/2011/06/kameraku-custom-shader-effects-example.html
+
+uniform float targetHue;
+uniform float windowWidth;
+uniform float dividerValue;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void rgb2hsl(vec3 rgb, out float h, out float s, float l)
+{
+ float maxval = max(rgb.r, max(rgb.g, rgb.b));
+ float minval = min(rgb.r, min(rgb.g, rgb.b));
+ float delta = maxval - minval;
+ l = (minval + maxval) / 2.0;
+ s = 0.0;
+ if (l > 0.0 && l < 1.0)
+ s = delta / (l < 0.5 ? 2.0 * l : 2.0 - 2.0 * l);
+ h = 0.0;
+ if (delta > 0.0)
+ {
+ if (rgb.r == maxval && rgb.g != maxval)
+ h += (rgb.g - rgb.b ) / delta;
+ if (rgb.g == maxval && rgb.b != maxval)
+ h += 2.0 + (rgb.b - rgb.r) / delta;
+ if (rgb.b == maxval && rgb.r != maxval)
+ h += 4.0 + (rgb.r - rgb.g) / delta;
+ h *= 60.0;
+ }
+}
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec3 col = texture2D(source, uv).rgb;
+ float h, s, l;
+ rgb2hsl(col, h, s, l);
+ float h2 = (h > targetHue) ? h - 360.0 : h + 360.0;
+ float y = 0.3 * col.r + 0.59 * col.g + 0.11 * col.b;
+ vec3 result;
+ if (uv.x > dividerValue || (abs(h - targetHue) < windowWidth) || (abs(h2 - targetHue) < windowWidth))
+ result = col;
+ else
+ result = vec3(y, y, y);
+ gl_FragColor = qt_Opacity * vec4(result, 1.0);
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/magnify.fsh b/examples/multimedia/video/qmlvideofx/shaders/magnify.fsh
new file mode 100644
index 000000000..638254934
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/magnify.fsh
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://www.reddit.com/r/programming/comments/losip/shader_toy/c2upn1e
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+uniform float radius;
+uniform float diffractionIndex;
+uniform float targetWidth;
+uniform float targetHeight;
+uniform float posX;
+uniform float posY;
+
+void main()
+{
+ vec2 tc = qt_TexCoord0;
+ vec2 center = vec2(posX, posY);
+ vec2 xy = gl_FragCoord.xy - center.xy;
+ float r = sqrt(xy.x * xy.x + xy.y * xy.y);
+ if (r < radius) {
+ float h = diffractionIndex * 0.5 * radius;
+ vec2 new_xy = r < radius ? xy * (radius - h) / sqrt(radius * radius - r * r) : xy;
+ vec2 targetSize = vec2(targetWidth, targetHeight);
+ tc = (new_xy + center) / targetSize;
+ tc.y = 1.0 - tc.y;
+ }
+ gl_FragColor = qt_Opacity * texture2D(source, tc);
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/pagecurl.fsh b/examples/multimedia/video/qmlvideofx/shaders/pagecurl.fsh
new file mode 100644
index 000000000..08e4f4cf1
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/pagecurl.fsh
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://rectalogic.github.com/webvfx/examples_2transition-shader-pagecurl_8html-example.html
+
+uniform float dividerValue;
+uniform float curlExtent;
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+const float minAmount = -0.16;
+const float maxAmount = 1.3;
+const float PI = 3.141592653589793;
+const float scale = 512.0;
+const float sharpness = 3.0;
+const vec4 bgColor = vec4(1.0, 1.0, 0.8, 1.0);
+
+float amount = curlExtent * (maxAmount - minAmount) + minAmount;
+float cylinderCenter = amount;
+// 360 degrees * amount
+float cylinderAngle = 2.0 * PI * amount;
+const float cylinderRadius = 1.0 / PI / 2.0;
+
+vec3 hitPoint(float hitAngle, float yc, vec3 point, mat3 rrotation)
+{
+ float hitPoint = hitAngle / (2.0 * PI);
+ point.y = hitPoint;
+ return rrotation * point;
+}
+
+vec4 antiAlias(vec4 color1, vec4 color2, float distance)
+{
+ distance *= scale;
+ if (distance < 0.0) return color2;
+ if (distance > 2.0) return color1;
+ float dd = pow(1.0 - distance / 2.0, sharpness);
+ return ((color2 - color1) * dd) + color1;
+}
+
+float distanceToEdge(vec3 point)
+{
+ float dx = abs(point.x > 0.5 ? 1.0 - point.x : point.x);
+ float dy = abs(point.y > 0.5 ? 1.0 - point.y : point.y);
+ if (point.x < 0.0) dx = -point.x;
+ if (point.x > 1.0) dx = point.x - 1.0;
+ if (point.y < 0.0) dy = -point.y;
+ if (point.y > 1.0) dy = point.y - 1.0;
+ if ((point.x < 0.0 || point.x > 1.0) && (point.y < 0.0 || point.y > 1.0)) return sqrt(dx * dx + dy * dy);
+ return min(dx, dy);
+}
+
+vec4 seeThrough(float yc, vec2 p, mat3 rotation, mat3 rrotation)
+{
+ float hitAngle = PI - (acos(yc / cylinderRadius) - cylinderAngle);
+ vec3 point = hitPoint(hitAngle, yc, rotation * vec3(p, 1.0), rrotation);
+ if (yc <= 0.0 && (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0))
+ return bgColor;
+ if (yc > 0.0)
+ return texture2D(source, p);
+ vec4 color = texture2D(source, point.xy);
+ vec4 tcolor = vec4(0.0);
+ return antiAlias(color, tcolor, distanceToEdge(point));
+}
+
+vec4 seeThroughWithShadow(float yc, vec2 p, vec3 point, mat3 rotation, mat3 rrotation)
+{
+ float shadow = distanceToEdge(point) * 30.0;
+ shadow = (1.0 - shadow) / 3.0;
+ if (shadow < 0.0)
+ shadow = 0.0;
+ else
+ shadow *= amount;
+ vec4 shadowColor = seeThrough(yc, p, rotation, rrotation);
+ shadowColor.r -= shadow;
+ shadowColor.g -= shadow;
+ shadowColor.b -= shadow;
+ return shadowColor;
+}
+
+vec4 backside(float yc, vec3 point)
+{
+ vec4 color = texture2D(source, point.xy);
+ float gray = (color.r + color.b + color.g) / 15.0;
+ gray += (8.0 / 10.0) * (pow(1.0 - abs(yc / cylinderRadius), 2.0 / 10.0) / 2.0 + (5.0 / 10.0));
+ color.rgb = vec3(gray);
+ return color;
+}
+
+void main(void)
+{
+ const float angle = 30.0 * PI / 180.0;
+ float c = cos(-angle);
+ float s = sin(-angle);
+ mat3 rotation = mat3(
+ c, s, 0,
+ -s, c, 0,
+ 0.12, 0.258, 1
+ );
+ c = cos(angle);
+ s = sin(angle);
+ mat3 rrotation = mat3(
+ c, s, 0,
+ -s, c, 0,
+ 0.15, -0.5, 1
+ );
+ vec3 point = rotation * vec3(qt_TexCoord0, 1.0);
+ float yc = point.y - cylinderCenter;
+ vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
+ if (yc < -cylinderRadius) {
+ // See through to background
+ color = bgColor;
+ } else if (yc > cylinderRadius) {
+ // Flat surface
+ color = texture2D(source, qt_TexCoord0);
+ } else {
+ float hitAngle = (acos(yc / cylinderRadius) + cylinderAngle) - PI;
+ float hitAngleMod = mod(hitAngle, 2.0 * PI);
+ if ((hitAngleMod > PI && amount < 0.5) || (hitAngleMod > PI/2.0 && amount < 0.0)) {
+ color = seeThrough(yc, qt_TexCoord0, rotation, rrotation);
+ } else {
+ point = hitPoint(hitAngle, yc, point, rrotation);
+ if (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0) {
+ color = seeThroughWithShadow(yc, qt_TexCoord0, point, rotation, rrotation);
+ } else {
+ color = backside(yc, point);
+ vec4 otherColor;
+ if (yc < 0.0) {
+ float shado = 1.0 - (sqrt(pow(point.x - 0.5, 2.0) + pow(point.y - 0.5, 2.0)) / 0.71);
+ shado *= pow(-yc / cylinderRadius, 3.0);
+ shado *= 0.5;
+ otherColor = vec4(0.0, 0.0, 0.0, shado);
+ } else {
+ otherColor = texture2D(source, qt_TexCoord0);
+ }
+ color = antiAlias(color, otherColor, cylinderRadius - abs(yc));
+
+ // This second antialiasing step causes the shader to fail to render, on
+ // Symbian devices (tested so far using IVE3.5). Running out of scratch
+ // memory?
+ }
+ }
+ }
+ gl_FragColor = qt_Opacity * color;
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/pixelate.fsh b/examples/multimedia/video/qmlvideofx/shaders/pixelate.fsh
new file mode 100644
index 000000000..922d79b6f
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/pixelate.fsh
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://www.geeks3d.com/20101029/shader-library-pixelation-post-processing-effect-glsl/
+
+uniform float dividerValue;
+uniform float granularity;
+uniform float targetWidth;
+uniform float targetHeight;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec2 tc = qt_TexCoord0;
+ if (uv.x < dividerValue && granularity > 0.0) {
+ float dx = granularity / targetWidth;
+ float dy = granularity / targetHeight;
+ tc = vec2(dx*(floor(uv.x/dx) + 0.5),
+ dy*(floor(uv.y/dy) + 0.5));
+ }
+ gl_FragColor = qt_Opacity * texture2D(source, tc);
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/posterize.fsh b/examples/multimedia/video/qmlvideofx/shaders/posterize.fsh
new file mode 100644
index 000000000..e5c77ce14
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/posterize.fsh
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://www.geeks3d.com/20091027/shader-library-posterization-post-processing-effect-glsl/
+
+uniform float dividerValue;
+uniform float gamma;
+uniform float numColors;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 c = vec4(0.0);
+ if (uv.x < dividerValue) {
+ vec3 x = texture2D(source, uv).rgb;
+ x = pow(x, vec3(gamma, gamma, gamma));
+ x = x * numColors;
+ x = floor(x);
+ x = x / numColors;
+ x = pow(x, vec3(1.0/gamma));
+ c = vec4(x, 1.0);
+ } else {
+ c = texture2D(source, uv);
+ }
+ gl_FragColor = qt_Opacity * c;
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/ripple.fsh b/examples/multimedia/video/qmlvideofx/shaders/ripple.fsh
new file mode 100644
index 000000000..bb07fc263
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/ripple.fsh
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://blog.qt.digia.com/blog/2011/03/22/the-convenient-power-of-qml-scene-graph/
+
+uniform float dividerValue;
+uniform float targetWidth;
+uniform float targetHeight;
+uniform float time;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+const float PI = 3.1415926535;
+const int ITER = 7;
+const float RATE = 0.1;
+uniform float amplitude;
+uniform float n;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec2 tc = uv;
+ vec2 p = vec2(-1.0 + 2.0 * gl_FragCoord.x / targetWidth, -(-1.0 + 2.0 * gl_FragCoord.y / targetHeight));
+ float diffx = 0.0;
+ float diffy = 0.0;
+ vec4 col;
+ if (uv.x < dividerValue) {
+ for (int i=0; i<ITER; ++i) {
+ float theta = float(i) * PI / float(ITER);
+ vec2 r = vec2(cos(theta) * p.x + sin(theta) * p.y, -1.0 * sin(theta) * p.x + cos(theta) * p.y);
+ float diff = (sin(2.0 * PI * n * (r.y + time * RATE)) + 1.0) / 2.0;
+ diffx += diff * sin(theta);
+ diffy += diff * cos(theta);
+ }
+ tc = 0.5*(vec2(1.0,1.0) + p) + amplitude * vec2(diffx, diffy);
+ }
+ gl_FragColor = qt_Opacity * texture2D(source, tc);
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/selectionpanel.fsh b/examples/multimedia/video/qmlvideofx/shaders/selectionpanel.fsh
new file mode 100644
index 000000000..89d570e35
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/selectionpanel.fsh
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
diff --git a/examples/multimedia/video/qmlvideofx/shaders/sepia.fsh b/examples/multimedia/video/qmlvideofx/shaders/sepia.fsh
new file mode 100644
index 000000000..196c51782
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/sepia.fsh
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://kodemongki.blogspot.com/2011/06/kameraku-custom-shader-effects-example.html
+
+uniform float dividerValue;
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 orig = texture2D(source, uv);
+ vec3 col = orig.rgb;
+ float y = 0.3 * col.r + 0.59 * col.g + 0.11 * col.b;
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(y + 0.15, y + 0.07, y - 0.12, 1.0);
+ else
+ gl_FragColor = qt_Opacity * orig;
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/sharpen.fsh b/examples/multimedia/video/qmlvideofx/shaders/sharpen.fsh
new file mode 100644
index 000000000..39076375b
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/sharpen.fsh
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://kodemongki.blogspot.com/2011/06/kameraku-custom-shader-effects-example.html
+
+uniform float dividerValue;
+uniform float amount;
+const float step_w = 0.0015625;
+const float step_h = 0.0027778;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+vec3 sharpen(vec3 t1, vec3 t2, vec3 t3, vec3 t4, vec3 t5, vec3 t6, vec3 t7, vec3 t8, vec3 t9)
+{
+ return -t1 - t2 - t3 - t4 + amount * t5 - t6 - t7 - t8 - t9;
+}
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec3 t1 = texture2D(source, vec2(uv.x - step_w, uv.y - step_h)).rgb;
+ vec3 t2 = texture2D(source, vec2(uv.x, uv.y - step_h)).rgb;
+ vec3 t3 = texture2D(source, vec2(uv.x + step_w, uv.y - step_h)).rgb;
+ vec3 t4 = texture2D(source, vec2(uv.x - step_w, uv.y)).rgb;
+ vec3 t5 = texture2D(source, uv).rgb;
+ vec3 t6 = texture2D(source, vec2(uv.x + step_w, uv.y)).rgb;
+ vec3 t7 = texture2D(source, vec2(uv.x - step_w, uv.y + step_h)).rgb;
+ vec3 t8 = texture2D(source, vec2(uv.x, uv.y + step_h)).rgb;
+ vec3 t9 = texture2D(source, vec2(uv.x + step_w, uv.y + step_h)).rgb;
+ vec3 col = sharpen(t1, t2, t3, t4, t5, t6, t7, t8, t9);
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ else
+ gl_FragColor = qt_Opacity * texture2D(source, uv);
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/shockwave.fsh b/examples/multimedia/video/qmlvideofx/shaders/shockwave.fsh
new file mode 100644
index 000000000..64f33c8a1
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/shockwave.fsh
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://www.geeks3d.com/20091116/shader-library-2d-shockwave-post-processing-filter-glsl/
+
+uniform float centerX;
+uniform float centerY;
+uniform float dividerValue;
+uniform float granularity;
+uniform float time;
+uniform float weight;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec2 tc = qt_TexCoord0;
+ vec2 center = vec2(centerX, centerY);
+ const vec3 shock = vec3(10.0, 1.5, 0.1);
+ if (uv.x < dividerValue) {
+ float distance = distance(uv, center);
+ if ((distance <= (time + shock.z)) &&
+ (distance >= (time - shock.z))) {
+ float diff = (distance - time);
+ float powDiff = 1.0 - pow(abs(diff*shock.x), shock.y*weight);
+ float diffTime = diff * powDiff;
+ vec2 diffUV = normalize(uv - center);
+ tc += (diffUV * diffTime);
+ }
+ }
+ gl_FragColor = qt_Opacity * texture2D(source, tc);
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/sobeledgedetection1.fsh b/examples/multimedia/video/qmlvideofx/shaders/sobeledgedetection1.fsh
new file mode 100644
index 000000000..96732fa30
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/sobeledgedetection1.fsh
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on "Graphics Shaders: Theory and Practice" (http://cgeducation.org/ShadersBook/)
+
+uniform float dividerValue;
+uniform float mixLevel;
+uniform float resS;
+uniform float resT;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 c = vec4(0.0);
+ if (uv.x < dividerValue) {
+ vec2 st = qt_TexCoord0.st;
+ vec3 irgb = texture2D(source, st).rgb;
+ vec2 stp0 = vec2(1.0 / resS, 0.0);
+ vec2 st0p = vec2(0.0 , 1.0 / resT);
+ vec2 stpp = vec2(1.0 / resS, 1.0 / resT);
+ vec2 stpm = vec2(1.0 / resS, -1.0 / resT);
+ const vec3 W = vec3(0.2125, 0.7154, 0.0721);
+ float i00 = dot(texture2D(source, st).rgb, W);
+ float im1m1 = dot(texture2D(source, st-stpp).rgb, W);
+ float ip1p1 = dot(texture2D(source, st+stpp).rgb, W);
+ float im1p1 = dot(texture2D(source, st-stpm).rgb, W);
+ float ip1m1 = dot(texture2D(source, st+stpm).rgb, W);
+ float im10 = dot(texture2D(source, st-stp0).rgb, W);
+ float ip10 = dot(texture2D(source, st+stp0).rgb, W);
+ float i0m1 = dot(texture2D(source, st-st0p).rgb, W);
+ float i0p1 = dot(texture2D(source, st+st0p).rgb, W);
+ float h = -1.0*im1p1 - 2.0*i0p1 - 1.0*ip1p1 + 1.0*im1m1 + 2.0*i0m1 + 1.0*ip1m1;
+ float v = -1.0*im1m1 - 2.0*im10 - 1.0*im1p1 + 1.0*ip1m1 + 2.0*ip10 + 1.0*ip1p1;
+ float mag = 1.0 - length(vec2(h, v));
+ vec3 target = vec3(mag, mag, mag);
+ c = vec4(target, 1.0);
+ } else {
+ c = texture2D(source, qt_TexCoord0);
+ }
+ gl_FragColor = qt_Opacity * c;
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/sobeledgedetection2.fsh b/examples/multimedia/video/qmlvideofx/shaders/sobeledgedetection2.fsh
new file mode 100644
index 000000000..aa836ca2c
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/sobeledgedetection2.fsh
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://rastergrid.com/blog/downloads/frei-chen-edge-detector/
+
+#version 130
+uniform sampler2D source;
+uniform float dividerValue;
+uniform float weight;
+mat3 G[2] = mat3[](
+ mat3( 1.0, 2.0, 1.0, 0.0, 0.0, 0.0, -1.0, -2.0, -1.0 ),
+ mat3( 1.0, 0.0, -1.0, 2.0, 0.0, -2.0, 1.0, 0.0, -1.0 )
+);
+uniform lowp float qt_Opacity;
+in vec2 qt_TexCoord0;
+out vec4 FragmentColor;
+void main() {
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 c = vec4(0.0);
+ if (uv.x < dividerValue) {
+ mat3 intensity;
+ float conv[2];
+ vec3 sample;
+ for (int i=0; i<3; ++i) {
+ for (int j=0; j<3; ++j) {
+ sample = texelFetch(source, ivec2(gl_FragCoord) + ivec2(i-1, j-1), 0).rgb;
+ intensity[i][j] = length(sample) * weight;
+ }
+ }
+ for (int i=0; i<2; ++i) {
+ float dp3 = dot(G[i][0], intensity[0]) + dot(G[i][1], intensity[1]) + dot(G[i][2], intensity[2]);
+ conv[i] = dp3 * dp3;
+ }
+ c = vec4(0.5 * sqrt(conv[0]*conv[0] + conv[1]*conv[1]));
+ } else {
+ c = texture2D(source, qt_TexCoord0);
+ }
+ FragmentColor = qt_Opacity * c;
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/tiltshift.fsh b/examples/multimedia/video/qmlvideofx/shaders/tiltshift.fsh
new file mode 100644
index 000000000..becd9fe5d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/tiltshift.fsh
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://kodemongki.blogspot.com/2011/06/kameraku-custom-shader-effects-example.html
+
+uniform float dividerValue;
+const float step_w = 0.0015625;
+const float step_h = 0.0027778;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+vec3 blur()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ float y = uv.y < 0.4 ? uv.y : 1.0 - uv.y;
+ float dist = 8.0 - 20.0 * y;
+ vec3 acc = vec3(0.0, 0.0, 0.0);
+ for (float y=-2.0; y<=2.0; ++y) {
+ for (float x=-2.0; x<=2.0; ++x) {
+ acc += texture2D(source, vec2(uv.x + dist * x * step_w, uv.y + 0.5 * dist * y * step_h)).rgb;
+ }
+ }
+ return acc / 25.0;
+}
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec3 col;
+ if (uv.x > dividerValue || (uv.y >= 0.4 && uv.y <= 0.6))
+ col = texture2D(source, uv).rgb;
+ else
+ col = blur();
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/toon.fsh b/examples/multimedia/video/qmlvideofx/shaders/toon.fsh
new file mode 100644
index 000000000..2814dfbc8
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/toon.fsh
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://www.geeks3d.com/20101029/shader-library-pixelation-post-processing-effect-glsl/
+
+uniform float dividerValue;
+uniform float threshold;
+uniform float resS;
+uniform float resT;
+uniform float magTol;
+uniform float quantize;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec4 color = vec4(1.0, 0.0, 0.0, 1.1);
+ vec2 uv = qt_TexCoord0.xy;
+ if (uv.x < dividerValue) {
+ vec2 st = qt_TexCoord0.st;
+ vec3 rgb = texture2D(source, st).rgb;
+ vec2 stp0 = vec2(1.0/resS, 0.0);
+ vec2 st0p = vec2(0.0 , 1.0/resT);
+ vec2 stpp = vec2(1.0/resS, 1.0/resT);
+ vec2 stpm = vec2(1.0/resS, -1.0/resT);
+ float i00 = dot( texture2D(source, st).rgb, vec3(0.2125,0.7154,0.0721));
+ float im1m1 = dot( texture2D(source, st-stpp).rgb, vec3(0.2125,0.7154,0.0721));
+ float ip1p1 = dot( texture2D(source, st+stpp).rgb, vec3(0.2125,0.7154,0.0721));
+ float im1p1 = dot( texture2D(source, st-stpm).rgb, vec3(0.2125,0.7154,0.0721));
+ float ip1m1 = dot( texture2D(source, st+stpm).rgb, vec3(0.2125,0.7154,0.0721));
+ float im10 = dot( texture2D(source, st-stp0).rgb, vec3(0.2125,0.7154,0.0721));
+ float ip10 = dot( texture2D(source, st+stp0).rgb, vec3(0.2125,0.7154,0.0721));
+ float i0m1 = dot( texture2D(source, st-st0p).rgb, vec3(0.2125,0.7154,0.0721));
+ float i0p1 = dot( texture2D(source, st+st0p).rgb, vec3(0.2125,0.7154,0.0721));
+ float h = -1.*im1p1 - 2.*i0p1 - 1.*ip1p1 + 1.*im1m1 + 2.*i0m1 + 1.*ip1m1;
+ float v = -1.*im1m1 - 2.*im10 - 1.*im1p1 + 1.*ip1m1 + 2.*ip10 + 1.*ip1p1;
+ float mag = sqrt(h*h + v*v);
+ if (mag > magTol) {
+ color = vec4(0.0, 0.0, 0.0, 1.0);
+ }
+ else {
+ rgb.rgb *= quantize;
+ rgb.rgb += vec3(0.5, 0.5, 0.5);
+ ivec3 irgb = ivec3(rgb.rgb);
+ rgb.rgb = vec3(irgb) / quantize;
+ color = vec4(rgb, 1.0);
+ }
+ } else {
+ color = texture2D(source, uv);
+ }
+ gl_FragColor = qt_Opacity * color;
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/vignette.fsh b/examples/multimedia/video/qmlvideofx/shaders/vignette.fsh
new file mode 100644
index 000000000..bd20c8e8a
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/vignette.fsh
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://kodemongki.blogspot.com/2011/06/kameraku-custom-shader-effects-example.html
+
+uniform float dividerValue;
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 orig = texture2D(source, uv);
+ float cr = pow(0.1, 2.0);
+ float pt = pow(uv.x - 0.5, 2.0) + pow(uv.y - 0.5, 2.0);
+ float d = pt - cr;
+ float cf = 1.0;
+ if (d > 0.0)
+ cf = 1.0 - 2.0 * d;
+ vec3 col = cf * orig.rgb;
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ else
+ gl_FragColor = qt_Opacity * orig;
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/warhol.fsh b/examples/multimedia/video/qmlvideofx/shaders/warhol.fsh
new file mode 100644
index 000000000..6852495a5
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/warhol.fsh
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://kodemongki.blogspot.com/2011/06/kameraku-custom-shader-effects-example.html
+
+uniform float dividerValue;
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 orig = texture2D(source, uv);
+ vec3 col = orig.rgb;
+ float y = 0.3 *col.r + 0.59 * col.g + 0.11 * col.b;
+ y = y < 0.3 ? 0.0 : (y < 0.6 ? 0.5 : 1.0);
+ if (y == 0.5)
+ col = vec3(0.8, 0.0, 0.0);
+ else if (y == 1.0)
+ col = vec3(0.9, 0.9, 0.0);
+ else
+ col = vec3(0.0, 0.0, 0.0);
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ else
+ gl_FragColor = qt_Opacity * orig;
+}
diff --git a/examples/multimedia/video/qmlvideofx/shaders/wobble.fsh b/examples/multimedia/video/qmlvideofx/shaders/wobble.fsh
new file mode 100644
index 000000000..9f42d715d
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/shaders/wobble.fsh
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://blog.qt.digia.com/blog/2011/03/22/the-convenient-power-of-qml-scene-graph/
+
+uniform float amplitude;
+uniform float dividerValue;
+uniform float frequency;
+uniform float time;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+varying vec2 qt_TexCoord0;
+
+void main()
+{
+ vec2 uv = qt_TexCoord0.xy;
+ vec2 tc = qt_TexCoord0;
+ if (uv.x < dividerValue) {
+ vec2 p = sin(time + frequency * qt_TexCoord0);
+ tc += amplitude * vec2(p.y, -p.x);
+ }
+ gl_FragColor = qt_Opacity * texture2D(source, tc);
+}
diff --git a/examples/multimedia/video/qmlvideofx/trace.h b/examples/multimedia/video/qmlvideofx/trace.h
new file mode 100644
index 000000000..73095f595
--- /dev/null
+++ b/examples/multimedia/video/qmlvideofx/trace.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRACE_H
+#define TRACE_H
+
+#include <QtCore/QDebug>
+
+#define ENABLE_TRACE
+//#define VERBOSE_TRACE
+
+namespace Trace {
+
+class NullDebug
+{
+public:
+ template <typename T>
+ NullDebug& operator<<(const T&) { return *this; }
+};
+
+inline NullDebug nullDebug() { return NullDebug(); }
+
+template <typename T>
+struct PtrWrapper
+{
+ PtrWrapper(const T *ptr) : m_ptr(ptr) { }
+ const T *const m_ptr;
+};
+
+} // namespace Trace
+
+template <typename T>
+inline QDebug& operator<<(QDebug &debug, const Trace::PtrWrapper<T> &wrapper)
+{
+ debug.nospace() << "[" << (void*)wrapper.m_ptr << "]";
+ return debug.space();
+}
+
+template<typename T>
+inline const void *qtVoidPtr(const T *ptr)
+{ return static_cast<const void *>(ptr); }
+
+#define qtThisPtr() qtVoidPtr(this)
+
+#ifdef ENABLE_TRACE
+ inline QDebug qtTrace() { return qDebug() << "[qmlvideofx]"; }
+# ifdef VERBOSE_TRACE
+ inline QDebug qtVerboseTrace() { return qtTrace(); }
+# else
+ inline Trace::NullDebug qtVerboseTrace() { return Trace::nullDebug(); }
+# endif
+#else
+ inline Trace::NullDebug qtTrace() { return Trace::nullDebug(); }
+ inline Trace::NullDebug qtVerboseTrace() { return Trace::nullDebug(); }
+#endif
+
+#endif // TRACE_H
+
diff --git a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp
new file mode 100644
index 000000000..1d44f1297
--- /dev/null
+++ b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "frequencymonitor.h"
+#include <QtCore/QDebug>
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QString>
+#include <QtCore/QTime>
+#include <QtCore/QTimer>
+
+//#define VERBOSE_TRACE
+
+inline QDebug qtTrace() { return qDebug() << "[frequencymonitor]"; }
+#ifdef VERBOSE_TRACE
+inline QDebug qtVerboseTrace() { return qtTrace(); }
+#else
+inline QNoDebug qtVerboseTrace() { return QNoDebug(); }
+#endif
+
+static const int DefaultSamplingInterval = 100;
+static const int DefaultTraceInterval = 0;
+
+class FrequencyMonitorPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ FrequencyMonitorPrivate(FrequencyMonitor *parent);
+ void calculateInstantaneousFrequency();
+
+private slots:
+ void calculateAverageFrequency();
+ void stalled();
+
+public:
+ FrequencyMonitor *const q_ptr;
+ QString m_label;
+ bool m_active;
+ qreal m_instantaneousFrequency;
+ QElapsedTimer m_instantaneousElapsed;
+ QTimer *m_averageTimer;
+ QElapsedTimer m_averageElapsed;
+ int m_count;
+ qreal m_averageFrequency;
+ QTimer *m_traceTimer;
+ QTimer *m_stalledTimer;
+};
+
+FrequencyMonitorPrivate::FrequencyMonitorPrivate(FrequencyMonitor *parent)
+: QObject(parent)
+, q_ptr(parent)
+, m_active(false)
+, m_instantaneousFrequency(0)
+, m_averageTimer(new QTimer(this))
+, m_count(0)
+, m_averageFrequency(0)
+, m_traceTimer(new QTimer(this))
+, m_stalledTimer(new QTimer(this))
+{
+ m_instantaneousElapsed.start();
+ connect(m_averageTimer, SIGNAL(timeout()),
+ this, SLOT(calculateAverageFrequency()));
+ if (DefaultSamplingInterval)
+ m_averageTimer->start(DefaultSamplingInterval);
+ m_averageElapsed.start();
+ connect(m_traceTimer, SIGNAL(timeout()),
+ q_ptr, SLOT(trace()));
+ if (DefaultTraceInterval)
+ m_traceTimer->start(DefaultTraceInterval);
+ m_stalledTimer->setSingleShot(true);
+ connect(m_stalledTimer, SIGNAL(timeout()),
+ this, SLOT(stalled()));
+}
+
+void FrequencyMonitorPrivate::calculateInstantaneousFrequency()
+{
+ const qint64 ms = m_instantaneousElapsed.restart();
+ m_instantaneousFrequency = ms ? qreal(1000) / ms : 0;
+ m_stalledTimer->start(3 * ms);
+ if (m_instantaneousFrequency)
+ q_ptr->setActive(true);
+ q_ptr->emit instantaneousFrequencyChanged(m_instantaneousFrequency);
+ q_ptr->emit frequencyChanged();
+}
+
+void FrequencyMonitorPrivate::calculateAverageFrequency()
+{
+ const qint64 ms = m_averageElapsed.restart();
+ m_averageFrequency = qreal(m_count * 1000) / ms;
+ q_ptr->emit averageFrequencyChanged(m_averageFrequency);
+ q_ptr->emit frequencyChanged();
+ m_count = 0;
+}
+
+void FrequencyMonitorPrivate::stalled()
+{
+ if (m_instantaneousFrequency) {
+ qtVerboseTrace() << "FrequencyMonitor::stalled";
+ m_instantaneousFrequency = 0;
+ q_ptr->emit instantaneousFrequencyChanged(m_instantaneousFrequency);
+ q_ptr->emit frequencyChanged();
+ }
+}
+
+FrequencyMonitor::FrequencyMonitor(QObject *parent)
+: QObject(parent)
+, d_ptr(0)
+{
+ d_ptr = new FrequencyMonitorPrivate(this);
+ qtTrace() << "FrequencyMonitor::FrequencyMonitor";
+}
+
+FrequencyMonitor::~FrequencyMonitor()
+{
+
+}
+
+const QString &FrequencyMonitor::label() const
+{
+ return d_func()->m_label;
+}
+
+bool FrequencyMonitor::active() const
+{
+ return d_func()->m_active;
+}
+
+int FrequencyMonitor::samplingInterval() const
+{
+ return d_ptr->m_averageTimer->isActive() ? d_ptr->m_averageTimer->interval() : 0;
+}
+
+int FrequencyMonitor::traceInterval() const
+{
+ return d_ptr->m_traceTimer->isActive() ? d_ptr->m_traceTimer->interval() : 0;
+}
+
+qreal FrequencyMonitor::instantaneousFrequency() const
+{
+ return d_func()->m_instantaneousFrequency;
+}
+
+qreal FrequencyMonitor::averageFrequency() const
+{
+ return d_func()->m_averageFrequency;
+}
+
+void FrequencyMonitor::notify()
+{
+ Q_D(FrequencyMonitor);
+ ++(d->m_count);
+ d->calculateInstantaneousFrequency();
+}
+
+void FrequencyMonitor::trace()
+{
+ Q_D(FrequencyMonitor);
+ const QString value = QString::fromLatin1("instant %1 average %2")
+ .arg(d->m_instantaneousFrequency, 0, 'f', 2)
+ .arg(d->m_averageFrequency, 0, 'f', 2);
+ if (d->m_label.isEmpty())
+ qtTrace() << "FrequencyMonitor::trace" << value;
+ else
+ qtTrace() << "FrequencyMonitor::trace" << "label" << d->m_label << value;
+}
+
+void FrequencyMonitor::setLabel(const QString &value)
+{
+ Q_D(FrequencyMonitor);
+ if (d->m_label != value) {
+ d->m_label = value;
+ emit labelChanged(d->m_label);
+ }
+}
+
+void FrequencyMonitor::setActive(bool value)
+{
+ Q_D(FrequencyMonitor);
+ if (d->m_active != value) {
+ d->m_active = value;
+ emit activeChanged(d->m_active);
+ }
+}
+
+void FrequencyMonitor::setSamplingInterval(int value)
+{
+ Q_D(FrequencyMonitor);
+ if (samplingInterval() != value) {
+ if (value) {
+ d->m_averageTimer->setInterval(value);
+ d->m_averageTimer->start();
+ } else {
+ d->m_averageTimer->stop();
+ }
+ emit samplingIntervalChanged(value);
+ }
+}
+
+void FrequencyMonitor::setTraceInterval(int value)
+{
+ Q_D(FrequencyMonitor);
+ if (traceInterval() != value) {
+ if (value) {
+ d->m_traceTimer->setInterval(value);
+ d->m_traceTimer->start();
+ } else {
+ d->m_traceTimer->stop();
+ }
+ emit traceIntervalChanged(value);
+ }
+}
+
+#include "frequencymonitor.moc"
diff --git a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.h b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.h
new file mode 100644
index 000000000..1efd8b3ad
--- /dev/null
+++ b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FREQUENCYMONITOR_H
+#define FREQUENCYMONITOR_H
+
+#include <QtCore/QObject>
+#include <QtCore/QTimer>
+
+class FrequencyMonitorPrivate;
+
+/**
+ * Class for measuring frequency of events
+ *
+ * Occurrence of the event is notified by the client via the notify() slot.
+ * On a regular interval, both an instantaneous and a rolling average
+ * event frequency are calculated.
+ */
+class FrequencyMonitor : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(FrequencyMonitor)
+ Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged)
+ Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
+ Q_PROPERTY(int samplingInterval READ samplingInterval WRITE setSamplingInterval NOTIFY samplingIntervalChanged)
+ Q_PROPERTY(int traceInterval READ traceInterval WRITE setTraceInterval NOTIFY traceIntervalChanged)
+ Q_PROPERTY(qreal instantaneousFrequency READ instantaneousFrequency NOTIFY instantaneousFrequencyChanged)
+ Q_PROPERTY(qreal averageFrequency READ averageFrequency NOTIFY averageFrequencyChanged)
+public:
+ FrequencyMonitor(QObject *parent = 0);
+ ~FrequencyMonitor();
+
+ static void qmlRegisterType();
+
+ const QString &label() const;
+ bool active() const;
+ int samplingInterval() const;
+ int traceInterval() const;
+ qreal instantaneousFrequency() const;
+ qreal averageFrequency() const;
+
+signals:
+ void labelChanged(const QString &value);
+ void activeChanged(bool);
+ void samplingIntervalChanged(int value);
+ void traceIntervalChanged(int value);
+ void frequencyChanged();
+ void instantaneousFrequencyChanged(qreal value);
+ void averageFrequencyChanged(qreal value);
+
+public slots:
+ Q_INVOKABLE void notify();
+ Q_INVOKABLE void trace();
+ void setActive(bool value);
+ void setLabel(const QString &value);
+ void setSamplingInterval(int value);
+ void setTraceInterval(int value);
+
+private:
+ FrequencyMonitorPrivate *d_ptr;
+};
+
+#endif // FREQUENCYMONITOR_H
diff --git a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.pri b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.pri
new file mode 100644
index 000000000..3ac8a08c4
--- /dev/null
+++ b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.pri
@@ -0,0 +1,5 @@
+HEADERS += $$PWD/frequencymonitor.h
+SOURCES += $$PWD/frequencymonitor.cpp
+INCLUDEPATH += $$PWD
+DEFINES += FREQUENCYMONITOR_SUPPORT
+
diff --git a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitordeclarative.cpp b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitordeclarative.cpp
new file mode 100644
index 000000000..33fd9a8ca
--- /dev/null
+++ b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitordeclarative.cpp
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "frequencymonitor.h"
+#include <QtQml/qqml.h>
+
+void FrequencyMonitor::qmlRegisterType()
+{
+ ::qmlRegisterType<FrequencyMonitor>("FrequencyMonitor", 1, 0, "FrequencyMonitor");
+}
diff --git a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitordeclarative.pri b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitordeclarative.pri
new file mode 100644
index 000000000..90a111cd1
--- /dev/null
+++ b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitordeclarative.pri
@@ -0,0 +1,3 @@
+include($$PWD/frequencymonitor.pri)
+QT += qml
+SOURCES += $$PWD/frequencymonitordeclarative.cpp
diff --git a/examples/multimedia/video/snippets/frequencymonitor/qml/frequencymonitor/FrequencyItem.qml b/examples/multimedia/video/snippets/frequencymonitor/qml/frequencymonitor/FrequencyItem.qml
new file mode 100644
index 000000000..893d2e84c
--- /dev/null
+++ b/examples/multimedia/video/snippets/frequencymonitor/qml/frequencymonitor/FrequencyItem.qml
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import FrequencyMonitor 1.0
+
+Rectangle {
+ id: root
+ property bool logging: true
+ property bool displayed: true
+ property bool enabled: logging || displayed
+ property alias active: monitor.active
+ property int samplingInterval: 500
+ property color textColor: "yellow"
+ property int textSize: 20
+ property alias label: monitor.label
+
+ border.width: 1
+ border.color: "yellow"
+ width: 5.5 * root.textSize
+ height: 3.0 * root.textSize
+ color: "black"
+ opacity: 0.5
+ radius: 10
+ visible: displayed && active
+
+ // This should ensure that the monitor is on top of all other content
+ z: 999
+
+ function notify() {
+ monitor.notify()
+ }
+
+ FrequencyMonitor {
+ id: monitor
+ samplingInterval: root.enabled ? root.samplingInterval : 0
+ onAverageFrequencyChanged: {
+ if (root.logging) trace()
+ averageFrequencyText.text = monitor.averageFrequency.toFixed(2)
+ }
+ }
+
+ Text {
+ id: labelText
+ anchors {
+ left: parent.left
+ top: parent.top
+ margins: 10
+ }
+ color: root.textColor
+ font.pixelSize: 0.6 * root.textSize
+ text: root.label
+ width: root.width - 2*anchors.margins
+ elide: Text.ElideRight
+ }
+
+ Text {
+ id: averageFrequencyText
+ anchors {
+ right: parent.right
+ bottom: parent.bottom
+ margins: 10
+ }
+ color: root.textColor
+ font.pixelSize: root.textSize
+ }
+}
diff --git a/examples/multimedia/video/snippets/performancemonitor/performancemonitor.cpp b/examples/multimedia/video/snippets/performancemonitor/performancemonitor.cpp
new file mode 100644
index 000000000..9a7e060b7
--- /dev/null
+++ b/examples/multimedia/video/snippets/performancemonitor/performancemonitor.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "performancemonitor.h"
+
+namespace PerformanceMonitor {
+
+ bool parseArgument(const QString &arg, State &state)
+ {
+ bool result = false;
+ if ("-log-perf" == arg) {
+ state.logging = true;
+ state.valid = true;
+ result = true;
+ } else if ("-no-log-perf" == arg) {
+ state.logging = false;
+ state.valid = true;
+ result = true;
+ } else if ("-show-perf" == arg) {
+ state.visible = true;
+ state.valid = true;
+ result = true;
+ } else if ("-hide-perf" == arg) {
+ state.visible = false;
+ state.valid = true;
+ result = true;
+ }
+ return result;
+ }
+
+}
diff --git a/examples/multimedia/video/snippets/performancemonitor/performancemonitor.h b/examples/multimedia/video/snippets/performancemonitor/performancemonitor.h
new file mode 100644
index 000000000..d87d71eac
--- /dev/null
+++ b/examples/multimedia/video/snippets/performancemonitor/performancemonitor.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PERFORMANCEMONITOR_H
+#define PERFORMANCEMONITOR_H
+
+#include <QtCore/QString>
+
+namespace PerformanceMonitor {
+ struct State {
+ bool valid;
+ bool logging;
+ bool visible;
+
+ State() : valid(true), logging(false), visible(true) { }
+ State(bool l, bool v) : valid(true), logging(l), visible(v) { }
+ bool operator==(const State &other) const
+ { return logging == other.logging && visible == other.visible; }
+ bool operator!=(const State &other) const
+ { return logging != other.logging || visible != other.visible; }
+ };
+
+ bool parseArgument(const QString &arg, State &state);
+}
+
+#endif // PERFORMANCEMONITOR_H
+
diff --git a/examples/multimedia/video/snippets/performancemonitor/performancemonitor.pri b/examples/multimedia/video/snippets/performancemonitor/performancemonitor.pri
new file mode 100644
index 000000000..2df3cfb13
--- /dev/null
+++ b/examples/multimedia/video/snippets/performancemonitor/performancemonitor.pri
@@ -0,0 +1,5 @@
+INCLUDEPATH += $$PWD
+HEADERS += $$PWD/performancemonitor.h
+SOURCES += $$PWD/performancemonitor.cpp
+DEFINES += PERFORMANCEMONITOR_SUPPORT
+
diff --git a/examples/multimedia/video/snippets/performancemonitor/performancemonitordeclarative.cpp b/examples/multimedia/video/snippets/performancemonitor/performancemonitordeclarative.cpp
new file mode 100644
index 000000000..257e628bf
--- /dev/null
+++ b/examples/multimedia/video/snippets/performancemonitor/performancemonitordeclarative.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "frequencymonitor.h"
+#include "performancemonitor.h"
+
+namespace PerformanceMonitor {
+
+ void qmlRegisterTypes()
+ {
+ FrequencyMonitor::qmlRegisterType();
+ }
+}
diff --git a/examples/multimedia/video/snippets/performancemonitor/performancemonitordeclarative.h b/examples/multimedia/video/snippets/performancemonitor/performancemonitordeclarative.h
new file mode 100644
index 000000000..e5515cb1b
--- /dev/null
+++ b/examples/multimedia/video/snippets/performancemonitor/performancemonitordeclarative.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PERFORMANCEMONITORDECLARATIVE_H
+#define PERFORMANCEMONITORDECLARATIVE_H
+
+#include "performancemonitor.h"
+
+namespace PerformanceMonitor {
+ void qmlRegisterTypes();
+}
+
+#endif // PERFORMANCEMONITORDECLARATIVE_H
diff --git a/examples/multimedia/video/snippets/performancemonitor/performancemonitordeclarative.pri b/examples/multimedia/video/snippets/performancemonitor/performancemonitordeclarative.pri
new file mode 100644
index 000000000..cf32c4ed2
--- /dev/null
+++ b/examples/multimedia/video/snippets/performancemonitor/performancemonitordeclarative.pri
@@ -0,0 +1,5 @@
+include($$PWD/../frequencymonitor/frequencymonitordeclarative.pri)
+include($$PWD/performancemonitor.pri)
+
+HEADERS += $$PWD/performancemonitordeclarative.h
+SOURCES += $$PWD/performancemonitordeclarative.cpp
diff --git a/examples/multimedia/video/snippets/performancemonitor/qml/performancemonitor/PerformanceItem.qml b/examples/multimedia/video/snippets/performancemonitor/qml/performancemonitor/PerformanceItem.qml
new file mode 100644
index 000000000..c62d22555
--- /dev/null
+++ b/examples/multimedia/video/snippets/performancemonitor/qml/performancemonitor/PerformanceItem.qml
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ property bool logging: true
+ property bool displayed: true
+ property bool videoActive
+ property int margins: 5
+ property bool enabled: true
+
+ color: "transparent"
+
+ // This should ensure that the monitor is on top of all other content
+ z: 999
+
+ Column {
+ id: column
+ anchors {
+ fill: root
+ margins: 10
+ }
+ spacing: 10
+ }
+
+ QtObject {
+ id: d
+ property Item qmlFrameRateItem: null
+ property Item videoFrameRateItem: null
+ }
+
+ Connections {
+ id: videoFrameRateActiveConnections
+ ignoreUnknownSignals: true
+ onActiveChanged: root.videoActive = videoFrameRateActiveConnections.target.active
+ }
+
+ states: [
+ State {
+ name: "hidden"
+ PropertyChanges {
+ target: root
+ opacity: 0
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "*"
+ to: "*"
+ NumberAnimation {
+ properties: "opacity"
+ easing.type: Easing.OutQuart
+ duration: 500
+ }
+ }
+ ]
+
+ state: enabled ? "baseState" : "hidden"
+
+ function createQmlFrameRateItem() {
+ var component = Qt.createComponent("../frequencymonitor/FrequencyItem.qml")
+ if (component.status == Component.Ready)
+ d.qmlFrameRateItem = component.createObject(column, { label: "QML frame rate",
+ displayed: root.displayed,
+ logging: root.logging
+ })
+ }
+
+ function createVideoFrameRateItem() {
+ var component = Qt.createComponent("../frequencymonitor/FrequencyItem.qml")
+ if (component.status == Component.Ready)
+ d.videoFrameRateItem = component.createObject(column, { label: "Video frame rate",
+ displayed: root.displayed,
+ logging: root.logging
+ })
+ videoFrameRateActiveConnections.target = d.videoFrameRateItem
+ }
+
+
+ function init() {
+ createQmlFrameRateItem()
+ createVideoFrameRateItem()
+ }
+
+ function videoFramePainted() {
+ if (d.videoFrameRateItem)
+ d.videoFrameRateItem.notify()
+ }
+
+ function qmlFramePainted() {
+ if (d.qmlFrameRateItem)
+ d.qmlFrameRateItem.notify()
+ }
+
+ onVideoActiveChanged: {
+ if (d.videoFrameRateItem)
+ d.videoFrameRateItem.active = root.videoActive
+ }
+}
diff --git a/examples/multimedia/video/video.pro b/examples/multimedia/video/video.pro
new file mode 100644
index 000000000..3127a4e49
--- /dev/null
+++ b/examples/multimedia/video/video.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+
+SUBDIRS += qmlvideo qmlvideofx
+