diff options
Diffstat (limited to 'demos/mobile/guitartuner')
67 files changed, 5836 insertions, 0 deletions
diff --git a/demos/mobile/guitartuner/guitartuner.pro b/demos/mobile/guitartuner/guitartuner.pro new file mode 100644 index 0000000..6283530 --- /dev/null +++ b/demos/mobile/guitartuner/guitartuner.pro @@ -0,0 +1,89 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2010-10-22T14:28:56 +# +#------------------------------------------------- + +QT += core gui + +TARGET = guitartuner +TEMPLATE = app + +ICON = images/guitartuner_icon.svg + +SOURCES += src/main.cpp\ + src/guitartuner.cpp \ + src/voicegenerator.cpp \ + src/voiceanalyzer.cpp \ + src/guitartunerui.cpp \ + src/fastfouriertransformer.cpp + +HEADERS += src/guitartuner.h \ + src/voicegenerator.h \ + src/voiceanalyzer.h \ + src/constants.h \ + src/guitartunerui.h \ + src/fastfouriertransformer.h + +FORMS += src/guitartunerui.ui + +VERSION = 1.2.0 + +symbian { + INCLUDEPATH += /epoc32/include/mmf/common + INCLUDEPATH += /epoc32/include/mmf/server + LIBS += -lmmfdevsound + TARGET.UID3 = 0xEC46D2C8 + # TARGET.CAPABILITY += + # TARGET.EPOCSTACKSIZE = 0x14000 + # TARGET.EPOCHEAPSIZE = 0x020000 0x1000000 +} + +RESOURCES += \ + guitartuner.qrc + +# Avoid auto screen rotation +DEFINES += ORIENTATIONLOCK + +symbian { + contains(DEFINES, ORIENTATIONLOCK):LIBS += -lavkon -leikcore -leiksrv -lcone +} + + +# Add mobility into Qt's CONFIG, and add multimedia into MOBILITY. + +win32 { + QT += multimedia + RC_FILE = src/guitartuner.rc +} +else { + CONFIG += mobility + MOBILITY += multimedia +} + +symbian { + TARGET.CAPABILITY = UserEnvironment +} + +# Add declarative module +QT += declarative + +OTHER_FILES += \ + src/application.qml \ + src/mycomponents/Adjuster.qml \ + src/mycomponents/adjustbars.js \ + src/mycomponents/ToggleButton.qml + +OTHER_FILES += \ + src/mycomponents/NotesModel.qml \ + src/mycomponents/NoteButtonView.qml \ + src/mycomponents/Meter.qml + +unix:!symbian { + maemo5 { + target.path = /opt/usr/bin + } else { + target.path = /usr/local/bin + } + INSTALLS += target +} diff --git a/demos/mobile/guitartuner/guitartuner.qrc b/demos/mobile/guitartuner/guitartuner.qrc new file mode 100644 index 0000000..d8ba019 --- /dev/null +++ b/demos/mobile/guitartuner/guitartuner.qrc @@ -0,0 +1,43 @@ +<RCC> + <qresource prefix="/"> + <file>src/application.qml</file> + <file>src/mycomponents/adjustbars.js</file> + <file>src/mycomponents/Adjuster.qml</file> + <file>src/mycomponents/Meter.qml</file> + <file>src/mycomponents/NoteButtonView.qml</file> + <file>src/mycomponents/NotesModel.qml</file> + <file>src/mycomponents/ToggleButton.qml</file> + <file>src/mycomponents/images/meterBG.png</file> + <file>src/mycomponents/images/pointerShadow.png</file> + <file>src/mycomponents/images/sensitivity.png</file> + <file>src/mycomponents/images/tuner_a.png</file> + <file>src/mycomponents/images/tuner_a_on.png</file> + <file>src/mycomponents/images/tuner_b.png</file> + <file>src/mycomponents/images/tuner_b_on.png</file> + <file>src/mycomponents/images/tuner_d.png</file> + <file>src/mycomponents/images/tuner_d_on.png</file> + <file>src/mycomponents/images/tuner_e.png</file> + <file>src/mycomponents/images/tuner_e_on.png</file> + <file>src/mycomponents/images/tuner_g.png</file> + <file>src/mycomponents/images/tuner_g_on.png</file> + <file>src/mycomponents/images/voicemode_off.png</file> + <file>src/mycomponents/images/voicemode_on.png</file> + <file>src/mycomponents/images/volume.png</file> + <file>src/mycomponents/images/volume_off.png</file> + <file>src/mycomponents/images/guitartuner_skin.png</file> + <file>src/mycomponents/images/power.png</file> + <file>src/mycomponents/images/tuner_auto.png</file> + <file>src/mycomponents/images/tuner_auto_on.png</file> + <file>src/mycomponents/images/big_a.png</file> + <file>src/mycomponents/images/big_b.png</file> + <file>src/mycomponents/images/big_d.png</file> + <file>src/mycomponents/images/big_e.png</file> + <file>src/mycomponents/images/big_g.png</file> + <file>src/mycomponents/images/glowing_a.png</file> + <file>src/mycomponents/images/glowing_b.png</file> + <file>src/mycomponents/images/glowing_d.png</file> + <file>src/mycomponents/images/glowing_e.png</file> + <file>src/mycomponents/images/glowing_g.png</file> + <file>src/mycomponents/images/pointer.png</file> + </qresource> +</RCC> diff --git a/demos/mobile/guitartuner/images/guitartab.svg b/demos/mobile/guitartuner/images/guitartab.svg new file mode 100644 index 0000000..9d88d5d --- /dev/null +++ b/demos/mobile/guitartuner/images/guitartab.svg @@ -0,0 +1,174 @@ +<?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="70.661781" + height="55.997791" + id="svg2" + version="1.1" + inkscape:version="0.47 r22583" + sodipodi:docname="guitartab.svg"> + <defs + id="defs4"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective10" /> + <inkscape:perspective + id="perspective3604" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3632" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3632-4" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3632-9" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3632-8" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3632-2" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3690" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3712" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.98994949" + inkscape:cx="343.43632" + inkscape:cy="198.00574" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1280" + inkscape:window-height="888" + inkscape:window-x="-4" + inkscape:window-y="-4" + inkscape:window-maximized="1" + showguides="true" + inkscape:guide-bbox="true" + borderlayer="true" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-45.793001,-702.07386)"> + <rect + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.96666431;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="rect3728" + width="68.695114" + height="54.031128" + x="46.776333" + y="703.05719" /> + <g + id="g3732" + transform="matrix(0.11166616,0,0,0.11166616,41.003771,673.42071)"> + <path + sodipodi:nodetypes="cc" + id="path2816" + d="m 133.63811,570.46864 0,-225.36571" + style="fill:none;stroke:#000000;stroke-width:17.61199951;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cc" + id="path2816-7" + d="m 223.89631,570.46864 0,-225.36571" + style="fill:none;stroke:#000000;stroke-width:17.61199951;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cc" + id="path2816-0" + d="m 314.15451,570.46864 0,-225.36571" + style="fill:none;stroke:#000000;stroke-width:17.61199951;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cc" + id="path2816-4" + d="m 404.4127,570.46864 0,-225.36571" + style="fill:none;stroke:#000000;stroke-width:17.61199951;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cc" + id="path2816-8" + d="m 494.6709,570.46864 0,-225.36571" + style="fill:none;stroke:#000000;stroke-width:17.61199951;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cc" + id="path2816-45" + d="m 584.92911,570.46864 0,-225.36571" + style="fill:none;stroke:#000000;stroke-width:17.61199951;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cc" + id="path2816-5" + d="m 124.89988,344.21478 468.77277,0" + style="fill:none;stroke:#000000;stroke-width:19.51578331;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cc" + id="path2816-5-1" + d="m 125.76355,400.6818 467.80305,0" + style="fill:none;stroke:#000000;stroke-width:19.4955883;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + </g> + </g> +</svg> diff --git a/demos/mobile/guitartuner/images/guitartuner_icon.svg b/demos/mobile/guitartuner/images/guitartuner_icon.svg new file mode 100644 index 0000000..de7ebe0 --- /dev/null +++ b/demos/mobile/guitartuner/images/guitartuner_icon.svg @@ -0,0 +1,247 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/"> +]> +<svg version="1.1" + xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" + x="0px" y="0px" width="128px" height="128px" viewBox="0 0 128 128" overflow="visible" enable-background="new 0 0 128 128" + xml:space="preserve"> +<defs> +</defs> +<rect x="0" display="none" fill="#1A171B" width="128" height="128"/> +<circle fill="#13235B" cx="64" cy="64" r="47"/> +<g> + <g> + <path fill="#F29400" d="M14.352,113.699c0,0-13.927-13.928-3.122-24.732c7.203-7.205,11.706-2.701,15.308-6.305 + c3.602-3.601,1.417-6.729,5.28-10.84c7.547-8.035,15.842,3.149,15.842,3.149l4.765,4.765l-7.204,7.204 + c0,0,5.134,7.943,12.338,0.74c-3.827,10.578-9.411,9.39-13.014,12.99c-3.602,3.603,0.854,8.058-6.303,15.31 + C27.508,126.855,14.352,113.699,14.352,113.699z"/> + </g> + <defs> + <filter id="Adobe_OpacityMaskFilter" filterUnits="userSpaceOnUse" x="7.122" y="68.918" width="50.437" height="51.368"> + + <feColorMatrix type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" color-interpolation-filters="sRGB" result="source"/> + </filter> + </defs> + <mask maskUnits="userSpaceOnUse" x="7.122" y="68.918" width="50.437" height="51.368" id="SVGID_1_"> + <g filter="url(#Adobe_OpacityMaskFilter)"> + + <image overflow="visible" width="55" height="57" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA +EAMCAwYAAAG8AAACPgAAAr//2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX +Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa +JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIADkANwMBIgACEQEDEQH/ +xAB9AAABBQEBAAAAAAAAAAAAAAAAAgQFBgcBAwEBAAAAAAAAAAAAAAAAAAAAABAAAgMAAgICAwAA +AAAAAAAAAgMBBAUABhBAMBEhEiMRAAICAQMFAQAAAAAAAAAAAAECABEhEEESIDFRIgMwEgEAAAAA +AAAAAAAAAAAAAABA/9oADAMBAAIRAxEAAADPwAc+F5Kkx0alEcAdmuaSVq5PFkFles5qQR0J/T8X +0IuyGbQrdAm4IAAcNwsnjAgpIAAf/9oACAECAAEFAPQ//9oACAEDAAEFAPQ//9oACAEBAAEFAPNa +k2xx+W5UTExPlYSw8bI/jezBFerWBTeCJGVDrjrEZPT1qZUzgSvZT+qtc2zc516mL25WcuABIBHN +loQvbZXln3+eruEG5bRJfGnAB27WJKzYbC5TslWfh7YECtNZDoagQvst6LDfNW8+qVbtBCN3sRtF +jDYfw//aAAgBAgIGPwAH/9oACAEDAgY/AAf/2gAIAQEBBj8A1tRichkSj36FRcljUW12hsQlcHQK +osnsIC952EH0ZbPkwCo1DaOrigD66cmF5gxMDRrMY4Jl7Tie9wVoTGCnJwIWc2Tov0U43i+0u4aM +4A3m+i0bHiU5IMKoSSYXc2T+X//Z" transform="matrix(1 0 0 1 5.0005 66)"> + </image> + </g> + </mask> + <g mask="url(#SVGID_1_)"> + <path fill="#B20000" d="M14.352,113.699c0,0-13.927-13.928-3.122-24.732c7.203-7.205,11.706-2.701,15.308-6.305 + c3.602-3.601,1.417-6.729,5.28-10.84c7.547-8.035,15.842,3.149,15.842,3.149l4.765,4.765l-7.204,7.204 + c0,0,5.134,7.943,12.338,0.74c-3.827,10.578-9.411,9.39-13.014,12.99c-3.602,3.603,0.854,8.058-6.303,15.31 + C27.508,126.855,14.352,113.699,14.352,113.699z"/> + </g> +</g> +<g> + <path fill="#FFEDB8" d="M37.791,69.168c5.189,0,9.624,5.894,9.692,5.98l4.588,4.588l-7.027,7.027l-0.143,0.143l0.11,0.17 + c0.102,0.158,2.55,3.875,6.503,3.875c1.808,0,3.63-0.791,5.427-2.352c-2.541,6.327-5.777,7.936-8.649,9.362 + c-1.422,0.707-2.765,1.374-3.924,2.532c-1.562,1.562-1.672,3.261-1.8,5.227c-0.171,2.633-0.384,5.909-4.504,10.084 + c-2.771,2.808-5.958,4.231-9.472,4.231c-7.46,0-14-6.448-14.064-6.514c-0.137-0.138-13.625-13.877-3.122-24.379 + c4.152-4.153,7.301-4.348,10.078-4.519c1.97-0.122,3.67-0.227,5.229-1.786c1.829-1.829,2.218-3.585,2.595-5.284 + c0.384-1.735,0.782-3.529,2.69-5.562C33.761,70.118,35.709,69.168,37.791,69.168 M37.791,68.918c-1.932,0-3.979,0.781-5.974,2.904 + c-3.862,4.11-1.678,7.239-5.28,10.84c-3.602,3.604-8.104-0.9-15.308,6.305c-10.805,10.805,3.122,24.732,3.122,24.732 + s6.586,6.587,14.241,6.587c3.164,0,6.51-1.126,9.649-4.306c7.157-7.252,2.701-11.707,6.303-15.31 + c3.603-3.601,9.187-2.412,13.014-12.99c-2.248,2.247-4.293,3.021-6.044,3.021c-3.862,0-6.293-3.761-6.293-3.761l7.204-7.204 + l-4.765-4.765C47.66,74.972,43.17,68.918,37.791,68.918L37.791,68.918z"/> +</g> +<rect x="35.983" y="67.296" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 146.0415 81.7395)" fill="#41281B" width="40.217" height="7.64"/> +<rect x="35.697" y="84.509" transform="matrix(-0.7073 0.707 -0.707 -0.7073 128.185 124.851)" fill="#ECEDED" width="5.092" height="8.913"/> +<rect x="27.593" y="92.612" transform="matrix(-0.7072 0.7071 -0.7071 -0.7072 120.0864 144.402)" fill="#ECEDED" width="5.092" height="8.914"/> +<rect x="24.55" y="96.293" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 115.1376 156.3543)" fill="#F6F6F6" width="1.273" height="11.46"/> +<rect x="26.351" y="94.491" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 116.9377 152.0052)" fill="#F6F6F6" width="1.273" height="11.461"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.15" stroke-miterlimit="10" x1="23.499" y1="99.433" x2="66.495" y2="56.438"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.15" stroke-miterlimit="10" x1="28" y1="103.934" x2="70.997" y2="60.941"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.15" stroke-miterlimit="10" x1="27.101" y1="103.034" x2="70.096" y2="60.04"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.15" stroke-miterlimit="10" x1="26.2" y1="102.134" x2="69.196" y2="59.139"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.15" stroke-miterlimit="10" x1="25.3" y1="101.233" x2="68.295" y2="58.239"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.15" stroke-miterlimit="10" x1="24.4" y1="100.333" x2="67.395" y2="57.339"/> +<circle fill="#1A171B" cx="26.908" cy="113.596" r="1.761"/> +<path fill="#1A171B" d="M33.138,107.366c0.688,0.687,0.688,1.804,0,2.493c-0.688,0.686-1.804,0.686-2.492,0 + c-0.688-0.689-0.688-1.807,0-2.493C31.334,106.678,32.45,106.678,33.138,107.366z"/> +<circle fill="#FFEDB8" cx="36.848" cy="75.131" r="1.762"/> +<circle fill="#1A171B" cx="32.31" cy="115.397" r="1.762"/> +<path fill="#1A171B" d="M38.54,109.167c0.689,0.687,0.689,1.804,0,2.493c-0.688,0.686-1.804,0.686-2.492,0 + c-0.688-0.689-0.688-1.807,0-2.493C36.736,108.479,37.852,108.479,38.54,109.167z"/> +<g> + <g> + <path fill="#ECEDED" d="M105.895,10.52l2.704,2.702L70.764,51.056c0,0-2.702,2.702,0,5.404c2.704,2.702,5.405,0,5.405,0 + l37.833-37.833l2.704,2.702c0,0-35.132,35.131-37.835,37.833c-2.702,2.702-8.107,2.702-10.81,0s-2.702-8.106,0-10.809 + C70.765,45.649,105.895,10.52,105.895,10.52z"/> + </g> + <defs> + <filter id="Adobe_OpacityMaskFilter_1_" filterUnits="userSpaceOnUse" x="66.036" y="10.52" width="50.671" height="50.669"> + + <feColorMatrix type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" color-interpolation-filters="sRGB" result="source"/> + </filter> + </defs> + <mask maskUnits="userSpaceOnUse" x="66.036" y="10.52" width="50.671" height="50.669" id="SVGID_2_"> + <g filter="url(#Adobe_OpacityMaskFilter_1_)"> + + <image overflow="visible" width="55" height="56" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA +EAMCAwYAAAGyAAACNwAAA9T/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX +Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa +JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIADgANwMBIgACEQEDEQH/ +xACCAAEBAQADAAAAAAAAAAAAAAAABgQDBQcBAQAAAAAAAAAAAAAAAAAAAAAQAQEBAAIDAQEAAAAA +AAAAAAUEBhADACBAAQIRAAIBAgQEBgIDAQAAAAAAAAECAxEEACFREjHBQgUQIGEyUhNBFZEiIwYS +AQAAAAAAAAAAAAAAAAAAAED/2gAMAwEAAhEDEQAAAPPwDcOwp4w61WCTNwt0YL95scjGN1vxSIv3 +mwzgBUdyENnAAD//2gAIAQIAAQUA+D//2gAIAQMAAQUA+D//2gAIAQEAAQUA9Bx7GLNSHCL3+g49 +jFiKJuMNONS0CLmRkOQ4HHsYsRRNxhppqWgSqqJwxPatd3JeDj2MWIom4w001LQJVVE4Ym66pCrw +cexixFE3GGmmpaBKqonDE3XVIVcZ+r9JwppqWgSqqJwxN11SFXOV1/8ABHR3bgAvouuqQq9P/9oA +CAECAgY/AAf/2gAIAQMCBj8AB//aAAgBAQEGPwDyLaWi1Jzdz7UXU4ht7e4+2bb/ALJxofl6eVbS +0WpObufai6nH6ztlJO4yCskhzNT1vyGPrjrJNId00zZhQepuQx22xhudz3kkcMgNNw3sF3j+fFbS +0WpObufai6nH6ztlJO4yCskhzNT1vyGPrjrJNId00zZhQepuQwLe3AlvpRkOt3+TaAYXuksm+6SR +ZVY8AUO5QBoPBbS0WpObufai6nH6ztlJO4yCskhzNT1vyGPrjrJNId00zZhQepuQwLe3AlvpRkOt +3+TaAYe7u3Mk0hqSeAGg9PBbS0WpObufai6nH6ztlJO4yCskhzNT1vyGPrjrJNId00zZhQepuQwL +e3AlvpRkOt3+TaAYe7u3Mk0hqSeAGg9PGfuVrFW6ZnBYCpru2Bm9Fx9cdZJpDummbMKD1NyGBb24 +Et9KMh1u/wAm0Aw93duZJpDUk8ANB6eRu33sJnspGJyoSm7j/X8j84ZP+fsgJJM2IT6lB9cqnD3d +25kmkNSTwA0Hp5f/2Q==" transform="matrix(1 0 0 1 64.0005 8)"> + </image> + </g> + </mask> + <g opacity="0.77" mask="url(#SVGID_2_)"> + <path fill="#1C1B1B" d="M105.895,10.52l2.704,2.702L70.764,51.056c0,0-2.702,2.702,0,5.404c2.704,2.702,5.405,0,5.405,0 + l37.833-37.833l2.704,2.702c0,0-35.132,35.131-37.835,37.833c-2.702,2.702-8.107,2.702-10.81,0s-2.702-8.106,0-10.809 + C70.765,45.649,105.895,10.52,105.895,10.52z"/> + </g> +</g> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="40.044" y1="81.762" x2="45.447" y2="87.166"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="40.966" y1="80.84" x2="46.37" y2="86.241"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="41.96" y1="79.846" x2="47.363" y2="85.248"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="43.168" y1="78.639" x2="48.57" y2="84.042"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="44.587" y1="77.219" x2="49.99" y2="82.623"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="46.006" y1="75.801" x2="51.41" y2="81.203"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="47.285" y1="74.522" x2="52.688" y2="79.925"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="48.847" y1="72.961" x2="54.249" y2="78.362"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="50.621" y1="71.185" x2="56.023" y2="76.589"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="52.489" y1="69.329" x2="57.891" y2="74.731"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="54.405" y1="67.4" x2="59.709" y2="72.704"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="56.517" y1="65.392" x2="61.821" y2="70.696"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="59.166" y1="62.744" x2="64.469" y2="68.047"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="61.883" y1="60.026" x2="67.187" y2="65.329"/> +<line fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="64.902" y1="57.007" x2="70.206" y2="62.31"/> +<g display="none"> + <g display="inline"> + <path fill="#F29400" d="M0,24.468C0,24.468,0,9,12,9c8,0,8,5,12,5s4.525-2.95,8.952-3.088C41.605,10.642,40,21.458,40,21.458 + v5.291h-8c0,0-1.56,7.262,6.44,7.262C30.44,37.762,28,34,24,34c-4,0-4,4.948-12,5C0,39.078,0,24.468,0,24.468z"/> + </g> + <defs> + <filter id="Adobe_OpacityMaskFilter_2_" filterUnits="userSpaceOnUse" x="0" y="9" width="40.118" height="30"> + + <feColorMatrix type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" color-interpolation-filters="sRGB" result="source"/> + </filter> + </defs> + <mask maskUnits="userSpaceOnUse" x="0" y="9" width="40.118" height="30" id="SVGID_3_" display="inline"> + <g filter="url(#Adobe_OpacityMaskFilter_2_)"> + + <image overflow="visible" width="46" height="35" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA +EAMCAwYAAAGrAAACBgAAAl3/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX +Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa +JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIACMALgMBIgACEQEDEQH/ +xAB+AAABBQEBAAAAAAAAAAAAAAAAAgMFBgcEAQEBAAAAAAAAAAAAAAAAAAAAABAAAgMAAgIDAQAA +AAAAAAAAAgMBBAUREzAGECAxFBEAAgEEAQMFAAAAAAAAAAAAAAERIUECElEQMYEgIkIDExIBAAAA +AAAAAAAAAAAAAAAAMP/aAAwDAQACEQMRAAAAoEknQjPuDXogztq4Vo7NJyW2mgQdegRyGUyCwPEg +AB//2gAIAQIAAQUA8P8A/9oACAEDAAEFAPD/AP/aAAgBAQABBQARkpr4r3DYxLKR6W8zUfA8TzjV +4dZzMwJB2Mshs4aQm9VWsZAf7vXigbGW4IBllcDp3VwOtrlL+0u2nYmu6jvgIXPZxALHsLnTYdDi ++A/D+n//2gAIAQICBj8AH//aAAgBAwIGPwAf/9oACAEBAQY/AFjipbJdzZLY10c8QbPEi5WsCoVx +G9UNJGONmxzyI7jhmX1pU5P1uLNdri9w4yHRwbX6/LwX8+j/2Q==" transform="matrix(1 0 0 1 -2.9995 6)"> + </image> + </g> + </mask> + <g display="inline" mask="url(#SVGID_3_)"> + <path fill="#B20000" d="M0,24.468C0,24.468,0,9,12,9c8,0,8,5,12,5s4.525-2.95,8.952-3.088C41.605,10.642,40,21.458,40,21.458 + v5.291h-8c0,0-1.56,7.262,6.44,7.262C30.44,37.762,28,34,24,34c-4,0-4,4.948-12,5C0,39.078,0,24.468,0,24.468z"/> + </g> +</g> +<g display="none"> + <path display="inline" fill="#FFEDB8" d="M12,9.25c4.592,0,6.439,1.633,8.07,3.075c1.169,1.033,2.179,1.926,3.93,1.926 + c2.047,0,3.246-0.764,4.405-1.502c1.171-0.746,2.382-1.518,4.555-1.585c0.104-0.003,0.207-0.005,0.308-0.005 + c2.021,0,3.606,0.649,4.712,1.931c2.537,2.939,1.782,8.28,1.771,8.37V26.5H32h-0.202l-0.042,0.197 + c-0.028,0.13-0.663,3.21,1.127,5.426c0.979,1.211,2.483,1.913,4.481,2.093c-1.956,0.813-3.706,1.21-5.323,1.21 + c-1.76,0-3.121-0.458-4.438-0.9C26.416,34.126,25.295,33.75,24,33.75c-1.755,0-2.766,0.888-3.937,1.916 + c-1.631,1.432-3.479,3.054-8.064,3.084l-0.095,0C0.388,38.75,0.25,24.61,0.25,24.468C0.25,24.315,0.391,9.25,12,9.25 M12,9 + C0,9,0,24.468,0,24.468S-0.002,39,11.904,39c0.031,0,0.064,0,0.096,0c8-0.052,8-5,12-5c2.67,0,4.644,1.675,8.041,1.675 + c1.692,0,3.739-0.416,6.4-1.664c-8,0-6.44-7.262-6.44-7.262h8v-5.291c0,0,1.566-10.551-6.733-10.551 + c-0.104,0-0.209,0.001-0.316,0.005C28.525,11.05,28,14,24,14S20,9,12,9L12,9z"/> +</g> +<rect x="31.032" y="21" display="none" fill="#41281B" width="32.967" height="6"/> +<rect x="25" y="20.5" display="none" fill="#ECEDED" width="3.999" height="7"/> +<rect x="16.001" y="20.5" display="none" fill="#ECEDED" width="3.999" height="7"/> +<rect x="12" y="19.5" display="none" fill="#F6F6F6" width="1" height="9"/> +<rect x="14" y="19.5" display="none" fill="#F6F6F6" width="1" height="9"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.15" stroke-miterlimit="10" x1="13" y1="21.625" x2="60.75" y2="21.625"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.15" stroke-miterlimit="10" x1="13" y1="26.625" x2="60.75" y2="26.625"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.15" stroke-miterlimit="10" x1="13" y1="25.625" x2="60.75" y2="25.625"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.15" stroke-miterlimit="10" x1="13" y1="24.625" x2="60.75" y2="24.625"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.15" stroke-miterlimit="10" x1="13" y1="23.625" x2="60.75" y2="23.625"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.15" stroke-miterlimit="10" x1="13" y1="22.625" x2="60.75" y2="22.625"/> +<circle display="none" fill="#1A171B" cx="7.029" cy="31.382" r="1.384"/> +<circle display="none" fill="#1A171B" cx="12.564" cy="31.382" r="1.384"/> +<circle display="none" fill="#FFEDB8" cx="33.908" cy="15.543" r="1.384"/> +<circle display="none" fill="#1A171B" cx="9.029" cy="35.382" r="1.384"/> +<circle display="none" fill="#1A171B" cx="14.564" cy="35.382" r="1.384"/> +<g display="none"> + <g display="inline"> + <path fill="#ECEDED" d="M124,16v4H68c0,0-4,0-4,4s4,4,4,4h56v4c0,0-52,0-56,0s-8-4-8-8s4-8,8-8C72.001,16,124,16,124,16z"/> + </g> + <defs> + <filter id="Adobe_OpacityMaskFilter_3_" filterUnits="userSpaceOnUse" x="60" y="16" width="64" height="16"> + + <feColorMatrix type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0" color-interpolation-filters="sRGB" result="source"/> + </filter> + </defs> + <mask maskUnits="userSpaceOnUse" x="60" y="16" width="64" height="16" id="SVGID_4_" display="inline"> + <g filter="url(#Adobe_OpacityMaskFilter_3_)"> + + <image overflow="visible" width="68" height="20" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA +EAMCAwYAAAGtAAACAQAAAsf/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX +Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa +JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIABQARAMBIgACEQEDEQH/ +xACMAAEAAQUAAAAAAAAAAAAAAAAABQECAwQGAQEAAAAAAAAAAAAAAAAAAAAAEAABAgQGAwEAAAAA +AAAAAAAABicCAwQWMBIUBRUlAREXBxEAAAQCBwcEAwAAAAAAAAAAAAERAhIDITGR0hOjREFxBBQ0 +BRVRYUIzIqKDEgEAAAAAAAAAAAAAAAAAAAAw/9oADAMBAAIRAxEAAACH3tvnSTQwmUMJm2IoarAM +vTgoAC0OdB//2gAIAQIAAQUAwv/aAAgBAwABBQDC/9oACAEBAAEFAEmk4N2gnSvzWTMbUbUbUbUb +Uj+c5eq5VKwU28pKpQ6lp5lnqUs9SlnqUs9SlnqUiSKjh8aKq1e08nrXL9OUOUOUOUOUR/R8va8r +/9oACAECAgY/AC//2gAIAQMCBj8AL//aAAgBAQEGPwB3cO4Pwu3S1KtDeZV07CIHLN815trcw5jm +nucVA1GaNRmjUZo1GaNRmg4Mddn2j5eNi94oUtrHEdjZOKXxZG80UyP8jiadCKXqIC4TGJFjlOI2 +/tCOgmWtvDoJlrbw6CZa28OgmWtvDoJlrbwV3ATCLe28OSwz5lYcOhVRQzxUfN0w4dabV2JvGoT+ +Q1GUNRlDUZQ1GUNRlA48dNv1D5eSi9ooksqH/9k=" transform="matrix(1 0 0 1 58.0005 14)"> + </image> + </g> + </mask> + <g display="inline" opacity="0.75" mask="url(#SVGID_4_)"> + <path fill="#1C1B1B" d="M124,16v4H68c0,0-4,0-4,4s4,4,4,4h56v4c0,0-52,0-56,0s-8-4-8-8s4-8,8-8C72.001,16,124,16,124,16z"/> + </g> +</g> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="32" y1="21" x2="32" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="33.025" y1="21" x2="33.025" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="34.129" y1="21" x2="34.129" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="35.469" y1="21" x2="35.469" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="37.046" y1="21" x2="37.046" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="38.623" y1="21" x2="38.623" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="40.042" y1="21" x2="40.042" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="41.776" y1="21" x2="41.776" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="43.747" y1="21" x2="43.747" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="46.033" y1="21" x2="46.033" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="48.635" y1="21" x2="48.635" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="51.315" y1="21" x2="51.315" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="54.311" y1="21" x2="54.311" y2="27"/> +<line display="none" fill="none" stroke="#FFFFFF" stroke-width="0.25" stroke-miterlimit="10" x1="57.385" y1="21" x2="57.385" y2="27"/> +</svg> diff --git a/demos/mobile/guitartuner/images/inputMode.svg b/demos/mobile/guitartuner/images/inputMode.svg new file mode 100644 index 0000000..f95991a --- /dev/null +++ b/demos/mobile/guitartuner/images/inputMode.svg @@ -0,0 +1,161 @@ +<?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="690.84283" + height="597.90881" + id="svg2" + version="1.1" + inkscape:version="0.47 r22583" + sodipodi:docname="inputMode.svg"> + <defs + id="defs4"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective10" /> + <inkscape:perspective + id="perspective3604" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3622" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3622-7" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3653" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3653-4" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3653-8" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.7" + inkscape:cx="220.15692" + inkscape:cy="262.65754" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1280" + inkscape:window-height="888" + inkscape:window-x="-4" + inkscape:window-y="-4" + inkscape:window-maximized="1" + showguides="true" + inkscape:guide-bbox="true" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-9.1421334,-233.17919)"> + <path + sodipodi:type="arc" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path3620" + sodipodi:cx="64.649765" + sodipodi:cy="472.53461" + sodipodi:rx="117.1777" + sodipodi:ry="268.70059" + d="m 181.82746,472.53461 c 0,148.39924 -52.46224,268.70059 -117.177695,268.70059 -64.71545463,0 -117.177696,-120.30135 -117.177696,-268.70059 0,-148.39924 52.46224137,-268.7006 117.177696,-268.7006 64.715455,0 117.177695,120.30136 117.177695,268.7006 z" + transform="matrix(2.8726899,0,0,1.0798196,168.84482,21.881457)" /> + <g + id="g3694" + transform="translate(14.702487,2.8571428)"> + <path + sodipodi:nodetypes="cccc" + id="path2830" + d="m 261.68027,406.82393 36.36549,359.61431 82.97781,0 38.24049,-359.61431" + style="fill:none;stroke:#000000;stroke-width:14.10000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + transform="translate(-11.060917,113.98119)" + d="m 442.4468,276.6803 c 0,49.09448 -41.15572,88.89342 -91.92388,88.89342 -50.76816,0 -91.92388,-39.79894 -91.92388,-88.89342 0,-49.09449 41.15572,-88.89343 91.92388,-88.89343 50.76816,0 91.92388,39.79894 91.92388,88.89343 z" + sodipodi:ry="88.893425" + sodipodi:rx="91.923882" + sodipodi:cy="276.6803" + sodipodi:cx="350.52292" + id="path2826" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:17.61199951;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + sodipodi:type="arc" /> + <path + id="path3610" + d="M 417.09557,336.26145 265.86811,447.10263" + style="fill:none;stroke:#000000;stroke-width:8.15200043;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + id="path3610-1" + d="M 370.02409,308.17608 244.86468,399.91085" + style="fill:none;stroke:#000000;stroke-width:8.15200043;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + id="path3610-4" + d="M 266.87874,335.24091 418.10619,446.08209" + style="fill:none;stroke:#000000;stroke-width:8.15200043;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + id="path3610-4-9" + d="M 306.03234,300.77574 436.914,396.7046" + style="fill:none;stroke:#000000;stroke-width:8.15200043;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + id="path3610-4-8" + d="m 246.61065,376.5921 132.66972,97.23942" + style="fill:none;stroke:#000000;stroke-width:8.15200043;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + id="path3610-4-2" + d="M 433.44049,380.0107 304.57747,474.46002" + style="fill:none;stroke:#000000;stroke-width:8.15200043;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + </g> + </g> +</svg> diff --git a/demos/mobile/guitartuner/images/note.svg b/demos/mobile/guitartuner/images/note.svg new file mode 100644 index 0000000..c1f1771 --- /dev/null +++ b/demos/mobile/guitartuner/images/note.svg @@ -0,0 +1,101 @@ +<?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="690.84283" + height="597.90881" + id="svg2" + version="1.1" + inkscape:version="0.47 r22583" + sodipodi:docname="New document 1"> + <defs + id="defs4"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective10" /> + <inkscape:perspective + id="perspective3604" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.49497475" + inkscape:cx="586.90391" + inkscape:cy="224.44944" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1280" + inkscape:window-height="888" + inkscape:window-x="-4" + inkscape:window-y="-4" + inkscape:window-maximized="1" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-9.1421334,-233.17919)"> + <path + sodipodi:type="arc" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path3620" + sodipodi:cx="64.649765" + sodipodi:cy="472.53461" + sodipodi:rx="117.1777" + sodipodi:ry="268.70059" + d="m 181.82746,472.53461 c 0,148.39924 -52.46224,268.70059 -117.177695,268.70059 -64.71545463,0 -117.177696,-120.30135 -117.177696,-268.70059 0,-148.39924 52.46224137,-268.7006 117.177696,-268.7006 64.715455,0 117.177695,120.30136 117.177695,268.7006 z" + transform="matrix(2.8726899,0,0,1.0798196,168.84482,21.881457)" /> + <path + style="fill:none;stroke:#000000;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + d="m 355.87166,686.47203 0,-381.77521" + id="path2816" + sodipodi:nodetypes="cc" /> + <path + sodipodi:type="arc" + style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path2818" + sodipodi:cx="284.86301" + sodipodi:cy="703.85956" + sodipodi:rx="80.812202" + sodipodi:ry="83.842659" + d="m 365.67521,703.85956 c 0,46.30502 -36.18086,83.84266 -80.8122,83.84266 -44.63135,0 -80.81221,-37.53764 -80.81221,-83.84266 0,-46.30502 36.18086,-83.84266 80.81221,-83.84266 44.63134,0 80.8122,37.53764 80.8122,83.84266 z" + transform="matrix(0.86662604,0,0,0.86662604,41.962127,84.107402)" /> + <path + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3.49788642;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="M 498.23775,478.96203 C 487.43102,436.20815 446.22124,431.4938 416.5823,423.48582 381.21648,411.5191 365.03425,382.76349 358.75673,339.52089 l -2.02761,-36.99987 c 12.76379,33.73415 40.64336,44.6109 67.22015,53.67478 46.38196,11.01541 67.31525,50.25786 74.72373,107.8334 0.48397,6.08567 0.99901,19.27869 0.75259,19.27869 -0.0715,0 -0.60616,-1.95564 -1.1881,-4.34586 l 0,0 2.6e-4,0 z" + id="path3618" + sodipodi:nodetypes="ccccccsccc" /> + </g> +</svg> diff --git a/demos/mobile/guitartuner/images/noteNo.svg b/demos/mobile/guitartuner/images/noteNo.svg new file mode 100644 index 0000000..888d230 --- /dev/null +++ b/demos/mobile/guitartuner/images/noteNo.svg @@ -0,0 +1,105 @@ +<?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="690.84283" + height="597.90881" + id="svg2" + version="1.1" + inkscape:version="0.47 r22583" + sodipodi:docname="noteCrossed.svg"> + <defs + id="defs4"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective10" /> + <inkscape:perspective + id="perspective3604" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.49497475" + inkscape:cx="289.91906" + inkscape:cy="224.44944" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1280" + inkscape:window-height="888" + inkscape:window-x="-4" + inkscape:window-y="-4" + inkscape:window-maximized="1" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-9.1421334,-233.17919)"> + <path + sodipodi:type="arc" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path3620" + sodipodi:cx="64.649765" + sodipodi:cy="472.53461" + sodipodi:rx="117.1777" + sodipodi:ry="268.70059" + d="m 181.82746,472.53461 c 0,148.39924 -52.46224,268.70059 -117.177695,268.70059 -64.71545463,0 -117.177696,-120.30135 -117.177696,-268.70059 0,-148.39924 52.46224137,-268.7006 117.177696,-268.7006 64.715455,0 117.177695,120.30136 117.177695,268.7006 z" + transform="matrix(2.8726899,0,0,1.0798196,168.84482,21.881457)" /> + <path + style="fill:none;stroke:#000000;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + d="m 355.87166,686.47203 0,-381.77521" + id="path2816" + sodipodi:nodetypes="cc" /> + <path + sodipodi:type="arc" + style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path2818" + sodipodi:cx="284.86301" + sodipodi:cy="703.85956" + sodipodi:rx="80.812202" + sodipodi:ry="83.842659" + d="m 365.67521,703.85956 c 0,46.30502 -36.18086,83.84266 -80.8122,83.84266 -44.63135,0 -80.81221,-37.53764 -80.81221,-83.84266 0,-46.30502 36.18086,-83.84266 80.81221,-83.84266 44.63134,0 80.8122,37.53764 80.8122,83.84266 z" + transform="matrix(0.86662604,0,0,0.86662604,41.962127,84.107402)" /> + <path + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3.49788642;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="M 498.23775,478.96203 C 487.43102,436.20815 446.22124,431.4938 416.5823,423.48582 381.21648,411.5191 365.03425,382.76349 358.75673,339.52089 l -2.02761,-36.99987 c 12.76379,33.73415 40.64336,44.6109 67.22015,53.67478 46.38196,11.01541 67.31525,50.25786 74.72373,107.8334 0.48397,6.08567 0.99901,19.27869 0.75259,19.27869 -0.0715,0 -0.60616,-1.95564 -1.1881,-4.34586 l 0,0 2.6e-4,0 z" + id="path3618" + sodipodi:nodetypes="ccccccsccc" /> + <path + style="fill:none;stroke:#ff0000;stroke-width:16;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" + d="m 176.92972,346.31704 369.5113,373.55192" + id="path2817" /> + </g> +</svg> diff --git a/demos/mobile/guitartuner/src/application.qml b/demos/mobile/guitartuner/src/application.qml new file mode 100644 index 0000000..7da138d --- /dev/null +++ b/demos/mobile/guitartuner/src/application.qml @@ -0,0 +1,328 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.0 +import "mycomponents" + +/* The base canvas for all QML drawing. */ +Rectangle { + id: application + + property int targetNoteIndex: 0 + property alias frequency: noteChooser.currentFrequency + //Data provided to C++. + property bool isInput: true + property bool isMuted: false + property bool isAuto: true + property alias maxVoiceDifference: voiceDifferenceMeter.maxValue + property real volume: 0.5 + property real sensitivity: 0.5 + + //Signals to C++. + signal volumeChanged(real volume) + signal microphoneSensitivityChanged(real sensitivity) + signal targetFrequencyChanged(real frequency) + signal modeChanged(bool isInput) + signal muteStateChanged(bool isMuted) + + //Slots for signals coming from C++. + function voiceDifferenceChanged(difference) { + if (isAuto) timer.running = true; + voiceDifferenceMeter.valueChanged(difference); + noteImage.glowing = false + } + function correctFrequencyObtained() { + noteImage.glowing = true + } + function lowVoice() { + noteImage.glowing = false + } + + //Private function for changing the target frequency automatically. + function calculateTargetFrequency(difference) { + var tempDifference = Math.abs(difference); + var tempIndex = targetNoteIndex + while (!(difference < 0 && tempIndex == 0) && + tempDifference >= notes.get(tempIndex-(difference<0)).interval/2) { + tempDifference -= notes.get(tempIndex-(difference<0)).interval; + tempIndex += difference/Math.abs(difference); + } + if (tempIndex != targetNoteIndex) { + targetNoteIndex = tempIndex + noteChooser.currentFrequency = notes.get(targetNoteIndex).frequency; + targetFrequencyChanged(frequency); + } + } + + width: 360; height: 640 + color: "black" + + //Provides data for functions. + NotesModel {id: notes} + + /* A timer for changing the target frequency automatically. + * This is needed for avoiding recursion. */ + Timer { + id: timer + + interval: 1 + onTriggered: calculateTargetFrequency(voiceDifferenceMeter.value) + } + + //A meter for showing the difference between current and target frequency. + Meter { + id: voiceDifferenceMeter + + maxValue: 12 + minValue: -maxValue + height: imageSize.height/background.sourceSize.height*parent.height + width: imageSize.width/background.sourceSize.width*parent.width + anchors { + topMargin: 100/background.sourceSize.height*parent.height + horizontalCenter: parent.horizontalCenter + top: parent.top + } + } + + Image { + id: background + + anchors.fill: parent + smooth: true + source: "./mycomponents/images/guitartuner_skin.png" + } + + //A button for quitting the application. + Image { + id: quitButton + + width: sourceSize.width/background.sourceSize.width*parent.width + height: sourceSize.height/background.sourceSize.height*parent.height + source: "./mycomponents/images/power.png" + smooth: true + KeyNavigation.up: volumeAdjuster + KeyNavigation.down: modeButton + Keys.onEnterPressed: Qt.quit() + anchors{ + leftMargin: 297/background.sourceSize.width*parent.width + left: parent.left; + topMargin: 17/background.sourceSize.height*parent.height + top: parent.top + } + + MouseArea { + anchors.fill: parent + onClicked: Qt.quit() + } + } + + //An image for showing the target note. + Image { + id: noteImage + + property bool glowing: false + + width: sourceSize.width/background.sourceSize.width*parent.width + height: sourceSize.height/background.sourceSize.height*parent.height + source: glowing ? notes.get(targetNoteIndex).glowSource : notes.get(targetNoteIndex).bigSource + + anchors { + topMargin: 273/background.sourceSize.height*parent.height + top: parent.top + horizontalCenter: parent.horizontalCenter + } + } + + //A button for choosing the input/output mode. + Image { + id: modeButton + + function buttonPressed() { + isInput = !isInput + modeChanged(isInput) + if (isInput) { + soundIcons.source = "./mycomponents/images/sensitivity.png" + source = "./mycomponents/images/voicemode_off.png" + volumeAdjuster.setValue(sensitivity) + } + else { + //Change off from "auto" mode + if (isAuto) { + noteChooser.pushButton(targetNoteIndex) + } + if (isMuted) { + soundIcons.source = "./mycomponents/images/volume_off.png"; + } + else + soundIcons.source = "./mycomponents/images/volume.png" + source = "./mycomponents/images/voicemode_on.png" + volumeAdjuster.setValue(volume) + } + } + + width: sourceSize.width/background.sourceSize.width*parent.width + height: sourceSize.height/background.sourceSize.height*parent.height + smooth: true + source: "./mycomponents/images/voicemode_off.png" + KeyNavigation.up: quitButton + KeyNavigation.down: noteChooser + Keys.onEnterPressed: buttonPressed() + anchors { + leftMargin: 16/background.sourceSize.width*parent.width + left: parent.left + topMargin: 353/background.sourceSize.height*parent.height + top: parent.top + } + + MouseArea { + anchors.fill: parent + onPressed: { + parent.focus = true + parent.scale = 0.95 + } + onReleased: { + parent.scale = 1/0.95 + } + onClicked: parent.buttonPressed() + } + } + + //Buttons for choosing the target note. + NoteButtonView { + id: noteChooser + + width: parent.width*0.95; height: width/model.count + onNoteSelected: { + if (note == "Auto") { + if (!isAuto) { + isAuto = true + } + if (!isInput) { + modeButton.buttonPressed() + } + } + else { + timer.running = false; + isAuto = false + targetNoteIndex = index + targetFrequencyChanged(frequency) + } + focus = true + } + KeyNavigation.up: modeButton + KeyNavigation.down: soundIcons + anchors { + horizontalCenter: parent.horizontalCenter + topMargin: 454/background.sourceSize.height*parent.height + top: parent.top + } + } + + //An element for showing the mode and changing the mute state. + Image { + id: soundIcons + + function stateChanged() { + isMuted = !isMuted + muteStateChanged(isMuted) + if (isMuted) { + source = "qrc:/src/mycomponents/images/volume_off.png" + } + else { + source = "qrc:/src/mycomponents/images/volume.png" + } + } + + width: sourceSize.width/background.sourceSize.width*parent.width + height: sourceSize.height/background.sourceSize.height*parent.height + smooth: true + source: "./mycomponents/images/sensitivity.png" + Keys.onEnterPressed: stateChanged() + KeyNavigation.up: noteChooser + KeyNavigation.down: quitButton + KeyNavigation.left: volumeAdjuster + KeyNavigation.right: volumeAdjuster + anchors { + leftMargin: 42/background.sourceSize.width*parent.width + left: parent.left + topMargin: 565/background.sourceSize.height*parent.height + top: parent.top + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (!isInput) { + parent.stateChanged() + } + parent.focus = true + } + } + } + + //An element for adjusting volume. + Adjuster { + id: volumeAdjuster + + max: 1 + value: 0.5 + width: 222/background.sourceSize.width*parent.width + height: parent.height*0.1 + onFocusChangedByClick: focus = true + onArrowPressedWhenValueOverLimits: soundIcons.focus = true + KeyNavigation.up: modeButton + KeyNavigation.down: quitButton + anchors { + leftMargin: 98/background.sourceSize.width*parent.width + left: parent.left + verticalCenter: soundIcons.verticalCenter + } + onValueChanged: { + if (isInput) { + sensitivity = value; + microphoneSensitivityChanged(1-sensitivity) + } + else { + volume = value + volumeChanged(volume) + } + } + } +} diff --git a/demos/mobile/guitartuner/src/constants.h b/demos/mobile/guitartuner/src/constants.h new file mode 100644 index 0000000..c3eddaa --- /dev/null +++ b/demos/mobile/guitartuner/src/constants.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CONSTANTS_H +#define CONSTANTS_H + +#define M_MAX_AMPLITUDE_8BIT_SIGNED 127 +#define M_MAX_AMPLITUDE_8BIT_UNSIGNED 255 +#define M_MAX_AMPLITUDE_16BIT_SIGNED 32767 +#define M_MAX_AMPLITUDE_16BIT_UNSIGNED 65535 + +#define M_TWELTH_ROOT_OF_2 1.05946309435930000000 + +// M_SAMPLE_COUNT_MULTIPLIER is 2/(M_TWELTH_ROOT_OF_2 - 1) +#define M_SAMPLE_COUNT_MULTIPLIER 33.63430749021150000000 + +#endif // CONSTANTS_H diff --git a/demos/mobile/guitartuner/src/fastfouriertransformer.cpp b/demos/mobile/guitartuner/src/fastfouriertransformer.cpp new file mode 100644 index 0000000..9158fd4 --- /dev/null +++ b/demos/mobile/guitartuner/src/fastfouriertransformer.cpp @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "fastfouriertransformer.h" +#include "math.h" + +#define STIN inline +#define __STATIC + +#include "fftpack.c" + +// called by __ogg_fdrffti +__STATIC void drfti1(int n, float *wa, int *ifac); +void __ogg_fdrffti(int n, float *wsave, int *ifac); +void __ogg_fdcosqi(int n, float *wsave, int *ifac); +// called by drftf1 +STIN void dradf2(int ido,int l1,float *cc,float *ch,float *wa1); +// called by drftf1 +STIN void dradf4(int ido,int l1,float *cc,float *ch,float *wa1, + float *wa2,float *wa3); +// called by drftf1 +STIN void dradfg(int ido,int ip,int l1,int idl1,float *cc,float *c1, + float *c2,float *ch,float *ch2,float *wa); +// called by drftf1 +STIN void drftf1(int n,float *c,float *ch,float *wa,int *ifac); +void __ogg_fdrfftf(int n,float *r,float *wsave,int *ifac); +STIN void dcsqf1(int n,float *x,float *w,float *xh,int *ifac); +void __ogg_fdcosqf(int n,float *x,float *wsave,int *ifac); +STIN void dradb2(int ido,int l1,float *cc,float *ch,float *wa1); +STIN void dradb3(int ido,int l1,float *cc,float *ch,float *wa1, + float *wa2); +STIN void dradb4(int ido,int l1,float *cc,float *ch,float *wa1, + float *wa2,float *wa3); +STIN void dradbg(int ido,int ip,int l1,int idl1,float *cc,float *c1, + float *c2,float *ch,float *ch2,float *wa); +STIN void drftb1(int n, float *c, float *ch, float *wa, int *ifac); +void __ogg_fdrfftb(int n, float *r, float *wsave, int *ifac); +STIN void dcsqb1(int n,float *x,float *w,float *xh,int *ifac); +void __ogg_fdcosqb(int n,float *x,float *wsave,int *ifac); + +FastFourierTransformer::FastFourierTransformer(QObject *parent) : + QObject(parent), + m_waveFloat(0), + m_workingArray(0), + m_ifac(0), + m_last_n(-1) +{ +} + +FastFourierTransformer::~FastFourierTransformer() +{ + if (m_waveFloat != 0) { + delete [] m_waveFloat; + } + if (m_workingArray != 0) { + delete [] m_workingArray; + } + if (m_ifac != 0) { + delete [] m_ifac; + } +} + +/** + * Prepares the arrays to be of length n. + */ +void FastFourierTransformer::reserve(int n) +{ + Q_ASSERT(n>0); + if (m_waveFloat != 0) { + delete [] m_waveFloat; + } + if (m_workingArray != 0) { + delete [] m_workingArray; + } + if (m_ifac != 0) { + delete [] m_ifac; + } + m_workingArray = new float[2*n+15]; + m_waveFloat = new float[n]; + m_ifac = new int[n]; + __ogg_fdrffti(n, m_workingArray, m_ifac); + m_last_n = n; +} + +/** + * Calculates the Fast Fourier Transformation (FFT). + */ +void FastFourierTransformer::calculateFFT(QList<qint16> wave) +{ + const int n = wave.size(); + if (m_last_n != n) { + reserve(n); + } + for (int i = 0; i < n; i++) { + m_waveFloat[i] = (float) wave.at(i); + } + + __ogg_fdrfftf(n, m_waveFloat, m_workingArray, m_ifac); + +} + +/** + * Returns the index which corresponds to the maximum density + * of the FFT. + */ +int FastFourierTransformer::getMaximumDensityIndex() +{ + const int halfN = m_last_n / 2; + float maxDensity = 0; + int maxDensityIndex = 0; + float densitySquared = 0.f; + for (int k = 1; k < halfN; k++) { + // Here, we calculate the frequency k/N. + // k=1, the wave oscillation time is N, and the frequency + // is 1/sample. + // k=2, the wave oscillation time is N/2, and the frequency + // is 2/sample. + // k=3, the wave oscillation time is N/3, and the frequency + // is 3/sample. + // Note, that the documentation is for Fortran, so indexes in the + // documentation does not match. + // The sine and cosine coefficients are obtained thus as follows: + const float cosCoefficient = qAbs(m_waveFloat[2*k-1]); + const float sinCoefficient = qAbs(m_waveFloat[2*k]); + + densitySquared = sinCoefficient*sinCoefficient + cosCoefficient*cosCoefficient; + if (densitySquared > maxDensity) { + maxDensity = densitySquared; + maxDensityIndex = k; + } + } + + if (m_cutOffForDensitySquared < maxDensity) { + return maxDensityIndex; + } + else { + return -1; + } +} + +/** + * Sets the cutoff density. + */ +void FastFourierTransformer::setCutOffForDensity(float cutoff) +{ + m_cutOffForDensitySquared = cutoff*cutoff; +} diff --git a/demos/mobile/guitartuner/src/fastfouriertransformer.h b/demos/mobile/guitartuner/src/fastfouriertransformer.h new file mode 100644 index 0000000..d126b45 --- /dev/null +++ b/demos/mobile/guitartuner/src/fastfouriertransformer.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FASTFOURIERTRANSFORM_H +#define FASTFOURIERTRANSFORM_H + +#include <QObject> +#include <QList> + +class FastFourierTransformer : public QObject +{ + Q_OBJECT + +public: + FastFourierTransformer(QObject *parent = 0); + ~FastFourierTransformer(); + void reserve(int n); + void calculateFFT(QList<qint16> wave); + int getMaximumDensityIndex(); + void setCutOffForDensity(float cutoff); + +private: + float *m_waveFloat; + float *m_workingArray; + int *m_ifac; + int m_last_n; + float m_cutOffForDensitySquared; +}; + +#endif // FASTFOURIERTRANSFORM_H diff --git a/demos/mobile/guitartuner/src/fftpack.c b/demos/mobile/guitartuner/src/fftpack.c new file mode 100644 index 0000000..24eaa57 --- /dev/null +++ b/demos/mobile/guitartuner/src/fftpack.c @@ -0,0 +1,1406 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/******************************************************************** + + The routines in this file are from http://www.netlib.org/fftpack/. + According to the comments in the original file (which are provided below) + and according to the wikipedia article about the FFTPACK[1], + they are released as public domain. + + For information about the author of the original, Fortran routines, + and the author of the C translation these routines, + see the comments below. + + [1] http://en.wikipedia.org/wiki/FFTPACK, referenced 2010-12-21. + + ********************************************************************/ + +/******************************************************************** + + file: fft.c + function: Fast discrete Fourier and cosine transforms and inverses + author: Monty <xiphmont@mit.edu> + modifications by: Monty + last modification date: Jul 1 1996 + + ********************************************************************/ + +/* These Fourier routines were originally based on the Fourier + routines of the same names from the NETLIB bihar and fftpack + fortran libraries developed by Paul N. Swarztrauber at the National + Center for Atmospheric Research in Boulder, CO USA. They have been + reimplemented in C and optimized in a few ways for OggSquish. */ + +/* As the original fortran libraries are public domain, the C Fourier + routines in this file are hereby released to the public domain as + well. The C routines here produce output exactly equivalent to the + original fortran routines. Of particular interest are the facts + that (like the original fortran), these routines can work on + arbitrary length vectors that need not be powers of two in + length. */ + +#include <math.h> + +__STATIC void drfti1(int n, float *wa, int *ifac){ + static int ntryh[4] = { 4,2,3,5 }; + static float tpi = 6.28318530717958647692528676655900577; + float arg,argh,argld,fi; + int ntry=0,i,j=-1; + int k1, l1, l2, ib; + int ld, ii, ip, is, nq, nr; + int ido, ipm, nfm1; + int nl=n; + int nf=0; + + L101: + j++; + if (j < 4) + ntry=ntryh[j]; + else + ntry+=2; + + L104: + nq=nl/ntry; + nr=nl-ntry*nq; + if (nr!=0) goto L101; + + nf++; + ifac[nf+1]=ntry; + nl=nq; + if (ntry!=2) goto L107; + if (nf==1) goto L107; + + for (i=1;i<nf;i++){ + ib=nf-i+1; + ifac[ib+1]=ifac[ib]; + } + ifac[2] = 2; + + L107: + if (nl!=1) goto L104; + ifac[0]=n; + ifac[1]=nf; + argh=tpi/n; + is=0; + nfm1=nf-1; + l1=1; + + if (nfm1==0) return; + + for (k1=0;k1<nfm1;k1++){ + ip=ifac[k1+2]; + ld=0; + l2=l1*ip; + ido=n/l2; + ipm=ip-1; + + for (j=0;j<ipm;j++){ + ld+=l1; + i=is; + argld=(float)ld*argh; + fi=0.; + for (ii=2;ii<ido;ii+=2){ + fi+=1.; + arg=fi*argld; + wa[i++]=cos(arg); + wa[i++]=sin(arg); + } + is+=ido; + } + l1=l2; + } +} + +void __ogg_fdrffti(int n, float *wsave, int *ifac){ + + if (n == 1) return; + drfti1(n, wsave+n, ifac); +} + +void __ogg_fdcosqi(int n, float *wsave, int *ifac){ + static float pih = 1.57079632679489661923132169163975; + static int k; + static float fk, dt; + + dt=pih/n; + fk=0.; + for (k=0;k<n;k++){ + fk+=1.; + wsave[k] = cos(fk*dt); + } + + __ogg_fdrffti(n, wsave+n,ifac); +} + +STIN void dradf2(int ido,int l1,float *cc,float *ch,float *wa1){ + int i,k; + float ti2,tr2; + int t0,t1,t2,t3,t4,t5,t6; + + t1=0; + t0=(t2=l1*ido); + t3=ido<<1; + for (k=0;k<l1;k++){ + ch[t1<<1]=cc[t1]+cc[t2]; + ch[(t1<<1)+t3-1]=cc[t1]-cc[t2]; + t1+=ido; + t2+=ido; + } + + if (ido<2) return; + if (ido==2) goto L105; + + t1=0; + t2=t0; + for (k=0;k<l1;k++){ + t3=t2; + t4=(t1<<1)+(ido<<1); + t5=t1; + t6=t1+t1; + for (i=2;i<ido;i+=2){ + t3+=2; + t4-=2; + t5+=2; + t6+=2; + tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3]; + ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1]; + ch[t6]=cc[t5]+ti2; + ch[t4]=ti2-cc[t5]; + ch[t6-1]=cc[t5-1]+tr2; + ch[t4-1]=cc[t5-1]-tr2; + } + t1+=ido; + t2+=ido; + } + + if (ido%2==1) return; + + L105: + t3=(t2=(t1=ido)-1); + t2+=t0; + for (k=0;k<l1;k++){ + ch[t1]=-cc[t2]; + ch[t1-1]=cc[t3]; + t1+=ido<<1; + t2+=ido; + t3+=ido; + } +} + +STIN void dradf4(int ido,int l1,float *cc,float *ch,float *wa1, + float *wa2,float *wa3){ + static float hsqt2 = .70710678118654752440084436210485; + int i,k,t0,t1,t2,t3,t4,t5,t6; + float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4; + t0=l1*ido; + + t1=t0; + t4=t1<<1; + t2=t1+(t1<<1); + t3=0; + + for (k=0;k<l1;k++){ + tr1=cc[t1]+cc[t2]; + tr2=cc[t3]+cc[t4]; + ch[t5=t3<<2]=tr1+tr2; + ch[(ido<<2)+t5-1]=tr2-tr1; + ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4]; + ch[t5]=cc[t2]-cc[t1]; + + t1+=ido; + t2+=ido; + t3+=ido; + t4+=ido; + } + + if (ido<2) return; + if (ido==2) goto L105; + + t1=0; + for (k=0;k<l1;k++){ + t2=t1; + t4=t1<<2; + t5=(t6=ido<<1)+t4; + for (i=2;i<ido;i+=2){ + t3=(t2+=2); + t4+=2; + t5-=2; + + t3+=t0; + cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3]; + ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1]; + t3+=t0; + cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3]; + ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1]; + t3+=t0; + cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3]; + ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1]; + + tr1=cr2+cr4; + tr4=cr4-cr2; + ti1=ci2+ci4; + ti4=ci2-ci4; + ti2=cc[t2]+ci3; + ti3=cc[t2]-ci3; + tr2=cc[t2-1]+cr3; + tr3=cc[t2-1]-cr3; + + + ch[t4-1]=tr1+tr2; + ch[t4]=ti1+ti2; + + ch[t5-1]=tr3-ti4; + ch[t5]=tr4-ti3; + + ch[t4+t6-1]=ti4+tr3; + ch[t4+t6]=tr4+ti3; + + ch[t5+t6-1]=tr2-tr1; + ch[t5+t6]=ti1-ti2; + } + t1+=ido; + } + if (ido%2==1) return; + + L105: + + t2=(t1=t0+ido-1)+(t0<<1); + t3=ido<<2; + t4=ido; + t5=ido<<1; + t6=ido; + + for (k=0;k<l1;k++){ + ti1=-hsqt2*(cc[t1]+cc[t2]); + tr1=hsqt2*(cc[t1]-cc[t2]); + ch[t4-1]=tr1+cc[t6-1]; + ch[t4+t5-1]=cc[t6-1]-tr1; + ch[t4]=ti1-cc[t1+t0]; + ch[t4+t5]=ti1+cc[t1+t0]; + t1+=ido; + t2+=ido; + t4+=t3; + t6+=ido; + } +} + +STIN void dradfg(int ido,int ip,int l1,int idl1,float *cc,float *c1, + float *c2,float *ch,float *ch2,float *wa){ + + static float tpi=6.28318530717958647692528676655900577; + int idij,ipph,i,j,k,l,ic,ik,is; + int t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; + float dc2,ai1,ai2,ar1,ar2,ds2; + int nbd; + float dcp,arg,dsp,ar1h,ar2h; + int idp2,ipp2; + + arg=tpi/(float)ip; + dcp=cos(arg); + dsp=sin(arg); + ipph=(ip+1)>>1; + ipp2=ip; + idp2=ido; + nbd=(ido-1)>>1; + t0=l1*ido; + t10=ip*ido; + + if (ido==1) goto L119; + for (ik=0;ik<idl1;ik++)ch2[ik]=c2[ik]; + + t1=0; + for (j=1;j<ip;j++){ + t1+=t0; + t2=t1; + for (k=0;k<l1;k++){ + ch[t2]=c1[t2]; + t2+=ido; + } + } + + is=-ido; + t1=0; + if (nbd>l1){ + for (j=1;j<ip;j++){ + t1+=t0; + is+=ido; + t2= -ido+t1; + for (k=0;k<l1;k++){ + idij=is-1; + t2+=ido; + t3=t2; + for (i=2;i<ido;i+=2){ + idij+=2; + t3+=2; + ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3]; + ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1]; + } + } + } + }else{ + + for (j=1;j<ip;j++){ + is+=ido; + idij=is-1; + t1+=t0; + t2=t1; + for (i=2;i<ido;i+=2){ + idij+=2; + t2+=2; + t3=t2; + for (k=0;k<l1;k++){ + ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3]; + ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1]; + t3+=ido; + } + } + } + } + + t1=0; + t2=ipp2*t0; + if (nbd<l1){ + for (j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for (i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t5=t3-ido; + t6=t4-ido; + for (k=0;k<l1;k++){ + t5+=ido; + t6+=ido; + c1[t5-1]=ch[t5-1]+ch[t6-1]; + c1[t6-1]=ch[t5]-ch[t6]; + c1[t5]=ch[t5]+ch[t6]; + c1[t6]=ch[t6-1]-ch[t5-1]; + } + } + } + }else{ + for (j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for (k=0;k<l1;k++){ + t5=t3; + t6=t4; + for (i=2;i<ido;i+=2){ + t5+=2; + t6+=2; + c1[t5-1]=ch[t5-1]+ch[t6-1]; + c1[t6-1]=ch[t5]-ch[t6]; + c1[t5]=ch[t5]+ch[t6]; + c1[t6]=ch[t6-1]-ch[t5-1]; + } + t3+=ido; + t4+=ido; + } + } + } + +L119: + for (ik=0;ik<idl1;ik++)c2[ik]=ch2[ik]; + + t1=0; + t2=ipp2*idl1; + for (j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1-ido; + t4=t2-ido; + for (k=0;k<l1;k++){ + t3+=ido; + t4+=ido; + c1[t3]=ch[t3]+ch[t4]; + c1[t4]=ch[t4]-ch[t3]; + } + } + + ar1=1.; + ai1=0.; + t1=0; + t2=ipp2*idl1; + t3=(ip-1)*idl1; + for (l=1;l<ipph;l++){ + t1+=idl1; + t2-=idl1; + ar1h=dcp*ar1-dsp*ai1; + ai1=dcp*ai1+dsp*ar1; + ar1=ar1h; + t4=t1; + t5=t2; + t6=t3; + t7=idl1; + + for (ik=0;ik<idl1;ik++){ + ch2[t4++]=c2[ik]+ar1*c2[t7++]; + ch2[t5++]=ai1*c2[t6++]; + } + + dc2=ar1; + ds2=ai1; + ar2=ar1; + ai2=ai1; + + t4=idl1; + t5=(ipp2-1)*idl1; + for (j=2;j<ipph;j++){ + t4+=idl1; + t5-=idl1; + + ar2h=dc2*ar2-ds2*ai2; + ai2=dc2*ai2+ds2*ar2; + ar2=ar2h; + + t6=t1; + t7=t2; + t8=t4; + t9=t5; + for (ik=0;ik<idl1;ik++){ + ch2[t6++]+=ar2*c2[t8++]; + ch2[t7++]+=ai2*c2[t9++]; + } + } + } + + t1=0; + for (j=1;j<ipph;j++){ + t1+=idl1; + t2=t1; + for (ik=0;ik<idl1;ik++)ch2[ik]+=c2[t2++]; + } + + if (ido<l1) goto L132; + + t1=0; + t2=0; + for (k=0;k<l1;k++){ + t3=t1; + t4=t2; + for (i=0;i<ido;i++)cc[t4++]=ch[t3++]; + t1+=ido; + t2+=t10; + } + + goto L135; + + L132: + for (i=0;i<ido;i++){ + t1=i; + t2=i; + for (k=0;k<l1;k++){ + cc[t2]=ch[t1]; + t1+=ido; + t2+=t10; + } + } + + L135: + t1=0; + t2=ido<<1; + t3=0; + t4=ipp2*t0; + for (j=1;j<ipph;j++){ + + t1+=t2; + t3+=t0; + t4-=t0; + + t5=t1; + t6=t3; + t7=t4; + + for (k=0;k<l1;k++){ + cc[t5-1]=ch[t6]; + cc[t5]=ch[t7]; + t5+=t10; + t6+=ido; + t7+=ido; + } + } + + if (ido==1) return; + if (nbd<l1) goto L141; + + t1=-ido; + t3=0; + t4=0; + t5=ipp2*t0; + for (j=1;j<ipph;j++){ + t1+=t2; + t3+=t2; + t4+=t0; + t5-=t0; + t6=t1; + t7=t3; + t8=t4; + t9=t5; + for (k=0;k<l1;k++){ + for (i=2;i<ido;i+=2){ + ic=idp2-i; + cc[i+t7-1]=ch[i+t8-1]+ch[i+t9-1]; + cc[ic+t6-1]=ch[i+t8-1]-ch[i+t9-1]; + cc[i+t7]=ch[i+t8]+ch[i+t9]; + cc[ic+t6]=ch[i+t9]-ch[i+t8]; + } + t6+=t10; + t7+=t10; + t8+=ido; + t9+=ido; + } + } + return; + + L141: + + t1=-ido; + t3=0; + t4=0; + t5=ipp2*t0; + for (j=1;j<ipph;j++){ + t1+=t2; + t3+=t2; + t4+=t0; + t5-=t0; + for (i=2;i<ido;i+=2){ + t6=idp2+t1-i; + t7=i+t3; + t8=i+t4; + t9=i+t5; + for (k=0;k<l1;k++){ + cc[t7-1]=ch[t8-1]+ch[t9-1]; + cc[t6-1]=ch[t8-1]-ch[t9-1]; + cc[t7]=ch[t8]+ch[t9]; + cc[t6]=ch[t9]-ch[t8]; + t6+=t10; + t7+=t10; + t8+=ido; + t9+=ido; + } + } + } +} + +STIN void drftf1(int n,float *c,float *ch,float *wa,int *ifac){ + int i,k1,l1,l2; + int na,kh,nf; + int ip,iw,ido,idl1,ix2,ix3; + + nf=ifac[1]; + na=1; + l2=n; + iw=n; + + for (k1=0;k1<nf;k1++){ + kh=nf-k1; + ip=ifac[kh+1]; + l1=l2/ip; + ido=n/l2; + idl1=ido*l1; + iw-=(ip-1)*ido; + na=1-na; + + if (ip!=4) goto L102; + + ix2=iw+ido; + ix3=ix2+ido; + if (na!=0) + dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1); + else + dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1); + goto L110; + + L102: + if (ip!=2) goto L104; + if (na!=0) goto L103; + + dradf2(ido,l1,c,ch,wa+iw-1); + goto L110; + + L103: + dradf2(ido,l1,ch,c,wa+iw-1); + goto L110; + + L104: + if (ido==1)na=1-na; + if (na!=0) goto L109; + + dradfg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1); + na=1; + goto L110; + + L109: + dradfg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1); + na=0; + + L110: + l2=l1; + } + + if (na==1) return; + + for (i=0;i<n;i++)c[i]=ch[i]; +} + +void __ogg_fdrfftf(int n,float *r,float *wsave,int *ifac){ + if (n==1) return; + drftf1(n,r,wsave,wsave+n,ifac); +} + +STIN void dcsqf1(int n,float *x,float *w,float *xh,int *ifac){ + int modn,i,k,kc; + int np2,ns2; + float xim1; + + ns2=(n+1)>>1; + np2=n; + + kc=np2; + for (k=1;k<ns2;k++){ + kc--; + xh[k]=x[k]+x[kc]; + xh[kc]=x[k]-x[kc]; + } + + modn=n%2; + if (modn==0)xh[ns2]=x[ns2]+x[ns2]; + + for (k=1;k<ns2;k++){ + kc=np2-k; + x[k]=w[k-1]*xh[kc]+w[kc-1]*xh[k]; + x[kc]=w[k-1]*xh[k]-w[kc-1]*xh[kc]; + } + + if (modn==0)x[ns2]=w[ns2-1]*xh[ns2]; + + __ogg_fdrfftf(n,x,xh,ifac); + + for (i=2;i<n;i+=2){ + xim1=x[i-1]-x[i]; + x[i]=x[i-1]+x[i]; + x[i-1]=xim1; + } +} + +void __ogg_fdcosqf(int n,float *x,float *wsave,int *ifac){ + static float sqrt2=1.4142135623730950488016887242097; + float tsqx; + + switch (n){ + case 0:case 1: + return; + case 2: + tsqx=sqrt2*x[1]; + x[1]=x[0]-tsqx; + x[0]+=tsqx; + return; + default: + dcsqf1(n,x,wsave,wsave+n,ifac); + return; + } +} + +STIN void dradb2(int ido,int l1,float *cc,float *ch,float *wa1){ + int i,k,t0,t1,t2,t3,t4,t5,t6; + float ti2,tr2; + + t0=l1*ido; + + t1=0; + t2=0; + t3=(ido<<1)-1; + for (k=0;k<l1;k++){ + ch[t1]=cc[t2]+cc[t3+t2]; + ch[t1+t0]=cc[t2]-cc[t3+t2]; + t2=(t1+=ido)<<1; + } + + if (ido<2) return; + if (ido==2) goto L105; + + t1=0; + t2=0; + for (k=0;k<l1;k++){ + t3=t1; + t5=(t4=t2)+(ido<<1); + t6=t0+t1; + for (i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t5-=2; + t6+=2; + ch[t3-1]=cc[t4-1]+cc[t5-1]; + tr2=cc[t4-1]-cc[t5-1]; + ch[t3]=cc[t4]-cc[t5]; + ti2=cc[t4]+cc[t5]; + ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2; + ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2; + } + t2=(t1+=ido)<<1; + } + + if (ido%2==1) return; + +L105: + t1=ido-1; + t2=ido-1; + for (k=0;k<l1;k++){ + ch[t1]=cc[t2]+cc[t2]; + ch[t1+t0]=-(cc[t2+1]+cc[t2+1]); + t1+=ido; + t2+=ido<<1; + } +} + +STIN void dradb3(int ido,int l1,float *cc,float *ch,float *wa1, + float *wa2){ + static float taur = -.5; + static float taui = .86602540378443864676372317075293618; + int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; + float ci2,ci3,di2,di3,cr2,cr3,dr2,dr3,ti2,tr2; + t0=l1*ido; + + t1=0; + t2=t0<<1; + t3=ido<<1; + t4=ido+(ido<<1); + t5=0; + for (k=0;k<l1;k++){ + tr2=cc[t3-1]+cc[t3-1]; + cr2=cc[t5]+(taur*tr2); + ch[t1]=cc[t5]+tr2; + ci3=taui*(cc[t3]+cc[t3]); + ch[t1+t0]=cr2-ci3; + ch[t1+t2]=cr2+ci3; + t1+=ido; + t3+=t4; + t5+=t4; + } + + if (ido==1) return; + + t1=0; + t3=ido<<1; + for (k=0;k<l1;k++){ + t7=t1+(t1<<1); + t6=(t5=t7+t3); + t8=t1; + t10=(t9=t1+t0)+t0; + + for (i=2;i<ido;i+=2){ + t5+=2; + t6-=2; + t7+=2; + t8+=2; + t9+=2; + t10+=2; + tr2=cc[t5-1]+cc[t6-1]; + cr2=cc[t7-1]+(taur*tr2); + ch[t8-1]=cc[t7-1]+tr2; + ti2=cc[t5]-cc[t6]; + ci2=cc[t7]+(taur*ti2); + ch[t8]=cc[t7]+ti2; + cr3=taui*(cc[t5-1]-cc[t6-1]); + ci3=taui*(cc[t5]+cc[t6]); + dr2=cr2-ci3; + dr3=cr2+ci3; + di2=ci2+cr3; + di3=ci2-cr3; + ch[t9-1]=wa1[i-2]*dr2-wa1[i-1]*di2; + ch[t9]=wa1[i-2]*di2+wa1[i-1]*dr2; + ch[t10-1]=wa2[i-2]*dr3-wa2[i-1]*di3; + ch[t10]=wa2[i-2]*di3+wa2[i-1]*dr3; + } + t1+=ido; + } +} + +STIN void dradb4(int ido,int l1,float *cc,float *ch,float *wa1, + float *wa2,float *wa3){ + static float sqrt2=1.4142135623730950488016887242097; + int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8; + float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4; + t0=l1*ido; + + t1=0; + t2=ido<<2; + t3=0; + t6=ido<<1; + for (k=0;k<l1;k++){ + t4=t3+t6; + t5=t1; + tr3=cc[t4-1]+cc[t4-1]; + tr4=cc[t4]+cc[t4]; + tr1=cc[t3]-cc[(t4+=t6)-1]; + tr2=cc[t3]+cc[t4-1]; + ch[t5]=tr2+tr3; + ch[t5+=t0]=tr1-tr4; + ch[t5+=t0]=tr2-tr3; + ch[t5+=t0]=tr1+tr4; + t1+=ido; + t3+=t2; + } + + if (ido<2) return; + if (ido==2) goto L105; + + t1=0; + for (k=0;k<l1;k++){ + t5=(t4=(t3=(t2=t1<<2)+t6))+t6; + t7=t1; + for (i=2;i<ido;i+=2){ + t2+=2; + t3+=2; + t4-=2; + t5-=2; + t7+=2; + ti1=cc[t2]+cc[t5]; + ti2=cc[t2]-cc[t5]; + ti3=cc[t3]-cc[t4]; + tr4=cc[t3]+cc[t4]; + tr1=cc[t2-1]-cc[t5-1]; + tr2=cc[t2-1]+cc[t5-1]; + ti4=cc[t3-1]-cc[t4-1]; + tr3=cc[t3-1]+cc[t4-1]; + ch[t7-1]=tr2+tr3; + cr3=tr2-tr3; + ch[t7]=ti2+ti3; + ci3=ti2-ti3; + cr2=tr1-tr4; + cr4=tr1+tr4; + ci2=ti1+ti4; + ci4=ti1-ti4; + + ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2; + ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2; + ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3; + ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3; + ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4; + ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4; + } + t1+=ido; + } + + if (ido%2 == 1) return; + + L105: + + t1=ido; + t2=ido<<2; + t3=ido-1; + t4=ido+(ido<<1); + for (k=0;k<l1;k++){ + t5=t3; + ti1=cc[t1]+cc[t4]; + ti2=cc[t4]-cc[t1]; + tr1=cc[t1-1]-cc[t4-1]; + tr2=cc[t1-1]+cc[t4-1]; + ch[t5]=tr2+tr2; + ch[t5+=t0]=sqrt2*(tr1-ti1); + ch[t5+=t0]=ti2+ti2; + ch[t5+=t0]=-sqrt2*(tr1+ti1); + + t3+=ido; + t1+=t2; + t4+=t2; + } +} + +STIN void dradbg(int ido,int ip,int l1,int idl1,float *cc,float *c1, + float *c2,float *ch,float *ch2,float *wa){ + static float tpi=6.28318530717958647692528676655900577; + int idij,ipph,i,j,k,l,ik,is,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10, + t11,t12; + float dc2,ai1,ai2,ar1,ar2,ds2; + int nbd; + float dcp,arg,dsp,ar1h,ar2h; + int ipp2; + + t10=ip*ido; + t0=l1*ido; + arg=tpi/(float)ip; + dcp=cos(arg); + dsp=sin(arg); + nbd=(ido-1)>>1; + ipp2=ip; + ipph=(ip+1)>>1; + if (ido<l1) goto L103; + + t1=0; + t2=0; + for (k=0;k<l1;k++){ + t3=t1; + t4=t2; + for (i=0;i<ido;i++){ + ch[t3]=cc[t4]; + t3++; + t4++; + } + t1+=ido; + t2+=t10; + } + goto L106; + + L103: + t1=0; + for (i=0;i<ido;i++){ + t2=t1; + t3=t1; + for (k=0;k<l1;k++){ + ch[t2]=cc[t3]; + t2+=ido; + t3+=t10; + } + t1++; + } + + L106: + t1=0; + t2=ipp2*t0; + t7=(t5=ido<<1); + for (j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + t6=t5; + for (k=0;k<l1;k++){ + ch[t3]=cc[t6-1]+cc[t6-1]; + ch[t4]=cc[t6]+cc[t6]; + t3+=ido; + t4+=ido; + t6+=t10; + } + t5+=t7; + } + + if (ido == 1) goto L116; + if (nbd<l1) goto L112; + + t1=0; + t2=ipp2*t0; + t7=0; + for (j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + + t7+=(ido<<1); + t8=t7; + for (k=0;k<l1;k++){ + t5=t3; + t6=t4; + t9=t8; + t11=t8; + for (i=2;i<ido;i+=2){ + t5+=2; + t6+=2; + t9+=2; + t11-=2; + ch[t5-1]=cc[t9-1]+cc[t11-1]; + ch[t6-1]=cc[t9-1]-cc[t11-1]; + ch[t5]=cc[t9]-cc[t11]; + ch[t6]=cc[t9]+cc[t11]; + } + t3+=ido; + t4+=ido; + t8+=t10; + } + } + goto L116; + + L112: + t1=0; + t2=ipp2*t0; + t7=0; + for (j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + t7+=(ido<<1); + t8=t7; + t9=t7; + for (i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t8+=2; + t9-=2; + t5=t3; + t6=t4; + t11=t8; + t12=t9; + for (k=0;k<l1;k++){ + ch[t5-1]=cc[t11-1]+cc[t12-1]; + ch[t6-1]=cc[t11-1]-cc[t12-1]; + ch[t5]=cc[t11]-cc[t12]; + ch[t6]=cc[t11]+cc[t12]; + t5+=ido; + t6+=ido; + t11+=t10; + t12+=t10; + } + } + } + +L116: + ar1=1.; + ai1=0.; + t1=0; + t9=(t2=ipp2*idl1); + t3=(ip-1)*idl1; + for (l=1;l<ipph;l++){ + t1+=idl1; + t2-=idl1; + + ar1h=dcp*ar1-dsp*ai1; + ai1=dcp*ai1+dsp*ar1; + ar1=ar1h; + t4=t1; + t5=t2; + t6=0; + t7=idl1; + t8=t3; + for (ik=0;ik<idl1;ik++){ + c2[t4++]=ch2[t6++]+ar1*ch2[t7++]; + c2[t5++]=ai1*ch2[t8++]; + } + dc2=ar1; + ds2=ai1; + ar2=ar1; + ai2=ai1; + + t6=idl1; + t7=t9-idl1; + for (j=2;j<ipph;j++){ + t6+=idl1; + t7-=idl1; + ar2h=dc2*ar2-ds2*ai2; + ai2=dc2*ai2+ds2*ar2; + ar2=ar2h; + t4=t1; + t5=t2; + t11=t6; + t12=t7; + for (ik=0;ik<idl1;ik++){ + c2[t4++]+=ar2*ch2[t11++]; + c2[t5++]+=ai2*ch2[t12++]; + } + } + } + + t1=0; + for (j=1;j<ipph;j++){ + t1+=idl1; + t2=t1; + for (ik=0;ik<idl1;ik++)ch2[ik]+=ch2[t2++]; + } + + t1=0; + t2=ipp2*t0; + for (j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for (k=0;k<l1;k++){ + ch[t3]=c1[t3]-c1[t4]; + ch[t4]=c1[t3]+c1[t4]; + t3+=ido; + t4+=ido; + } + } + + if (ido==1) goto L132; + if (nbd<l1) goto L128; + + t1=0; + t2=ipp2*t0; + for (j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for (k=0;k<l1;k++){ + t5=t3; + t6=t4; + for (i=2;i<ido;i+=2){ + t5+=2; + t6+=2; + ch[t5-1]=c1[t5-1]-c1[t6]; + ch[t6-1]=c1[t5-1]+c1[t6]; + ch[t5]=c1[t5]+c1[t6-1]; + ch[t6]=c1[t5]-c1[t6-1]; + } + t3+=ido; + t4+=ido; + } + } + goto L132; + + L128: + t1=0; + t2=ipp2*t0; + for (j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for (i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t5=t3; + t6=t4; + for (k=0;k<l1;k++){ + ch[t5-1]=c1[t5-1]-c1[t6]; + ch[t6-1]=c1[t5-1]+c1[t6]; + ch[t5]=c1[t5]+c1[t6-1]; + ch[t6]=c1[t5]-c1[t6-1]; + t5+=ido; + t6+=ido; + } + } + } + +L132: + if (ido==1) return; + + for (ik=0;ik<idl1;ik++)c2[ik]=ch2[ik]; + + t1=0; + for (j=1;j<ip;j++){ + t2=(t1+=t0); + for (k=0;k<l1;k++){ + c1[t2]=ch[t2]; + t2+=ido; + } + } + + if (nbd>l1) goto L139; + + is= -ido-1; + t1=0; + for (j=1;j<ip;j++){ + is+=ido; + t1+=t0; + idij=is; + t2=t1; + for (i=2;i<ido;i+=2){ + t2+=2; + idij+=2; + t3=t2; + for (k=0;k<l1;k++){ + c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3]; + c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1]; + t3+=ido; + } + } + } + return; + + L139: + is= -ido-1; + t1=0; + for (j=1;j<ip;j++){ + is+=ido; + t1+=t0; + t2=t1; + for (k=0;k<l1;k++){ + idij=is; + t3=t2; + for (i=2;i<ido;i+=2){ + idij+=2; + t3+=2; + c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3]; + c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1]; + } + t2+=ido; + } + } +} + +STIN void drftb1(int n, float *c, float *ch, float *wa, int *ifac){ + int i,k1,l1,l2; + int na; + int nf,ip,iw,ix2,ix3,ido,idl1; + + nf=ifac[1]; + na=0; + l1=1; + iw=1; + + for (k1=0;k1<nf;k1++){ + ip=ifac[k1 + 2]; + l2=ip*l1; + ido=n/l2; + idl1=ido*l1; + if (ip!=4) goto L103; + ix2=iw+ido; + ix3=ix2+ido; + + if (na!=0) + dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1); + else + dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1); + na=1-na; + goto L115; + + L103: + if (ip!=2) goto L106; + + if (na!=0) + dradb2(ido,l1,ch,c,wa+iw-1); + else + dradb2(ido,l1,c,ch,wa+iw-1); + na=1-na; + goto L115; + + L106: + if (ip!=3) goto L109; + + ix2=iw+ido; + if (na!=0) + dradb3(ido,l1,ch,c,wa+iw-1,wa+ix2-1); + else + dradb3(ido,l1,c,ch,wa+iw-1,wa+ix2-1); + na=1-na; + goto L115; + + L109: +/* The radix five case can be translated later..... */ +/* if (ip!=5) goto L112; + + ix2=iw+ido; + ix3=ix2+ido; + ix4=ix3+ido; + if (na!=0) + dradb5(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1); + else + dradb5(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1); + na=1-na; + goto L115; + + L112:*/ + if (na!=0) + dradbg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1); + else + dradbg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1); + if (ido==1)na=1-na; + + L115: + l1=l2; + iw+=(ip-1)*ido; + } + + if (na==0) return; + + for (i=0;i<n;i++)c[i]=ch[i]; +} + +void __ogg_fdrfftb(int n, float *r, float *wsave, int *ifac){ + if (n == 1) return; + drftb1(n, r, wsave, wsave+n, ifac); +} + +STIN void dcsqb1(int n,float *x,float *w,float *xh,int *ifac){ + int modn,i,k,kc; + int np2,ns2; + float xim1; + + ns2=(n+1)>>1; + np2=n; + + for (i=2;i<n;i+=2){ + xim1=x[i-1]+x[i]; + x[i]-=x[i-1]; + x[i-1]=xim1; + } + + x[0]+=x[0]; + modn=n%2; + if (modn==0)x[n-1]+=x[n-1]; + + __ogg_fdrfftb(n,x,xh,ifac); + + kc=np2; + for (k=1;k<ns2;k++){ + kc--; + xh[k]=w[k-1]*x[kc]+w[kc-1]*x[k]; + xh[kc]=w[k-1]*x[k]-w[kc-1]*x[kc]; + } + + if (modn==0)x[ns2]=w[ns2-1]*(x[ns2]+x[ns2]); + + kc=np2; + for (k=1;k<ns2;k++){ + kc--; + x[k]=xh[k]+xh[kc]; + x[kc]=xh[k]-xh[kc]; + } + x[0]+=x[0]; +} + +void __ogg_fdcosqb(int n,float *x,float *wsave,int *ifac){ + static float tsqrt2 = 2.8284271247461900976033774484194; + float x1; + + if (n<2){ + x[0]*=4; + return; + } + if (n==2){ + x1=(x[0]+x[1])*4; + x[1]=tsqrt2*(x[0]-x[1]); + x[0]=x1; + return; + } + + dcsqb1(n,x,wsave,wsave+n,ifac); +} + + + diff --git a/demos/mobile/guitartuner/src/guitartuner.cpp b/demos/mobile/guitartuner/src/guitartuner.cpp new file mode 100644 index 0000000..1750e6a --- /dev/null +++ b/demos/mobile/guitartuner/src/guitartuner.cpp @@ -0,0 +1,359 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "guitartuner.h" + +#ifdef Q_OS_SYMBIAN +#include <SoundDevice.h> +#endif // Q_OS_SYMBIAN + +#if defined(Q_OS_SYMBIAN) && defined(ORIENTATIONLOCK) +#include <eikenv.h> +#include <eikappui.h> +#include <aknenv.h> +#include <aknappui.h> +#endif // Q_OS_SYMBIAN && ORIENTATIONLOCK + +GuitarTuner::GuitarTuner(QWidget *parent) : + QMainWindow(parent) +{ + + // Set up the QML. + m_guitarTunerUI = new QDeclarativeView(QUrl("qrc:/src/application.qml"), this); + setCentralWidget(m_guitarTunerUI); + m_guitarTunerUI->setResizeMode(QDeclarativeView::SizeRootObjectToView); + qmlObject = m_guitarTunerUI->rootObject(); + + // Init audio output and input. + initAudioOutput(); + initAudioInput(); + + // Connect the quit signal of m_guitarTunerUI + // into the close slot of this. + connect(m_guitarTunerUI->engine(), SIGNAL(quit()), SLOT(close())); + + // Connect the signals from qmlObject into proper slots + // of this and m_voicegenerator. + connect(qmlObject, SIGNAL(muteStateChanged(bool)), + SLOT(muteStateChanged(bool))); + connect(qmlObject, SIGNAL(volumeChanged(qreal)), + m_voicegenerator, SLOT(setAmplitude(qreal))); + connect(qmlObject, SIGNAL(volumeChanged(qreal)), + SLOT(setMaxVolumeLevel(qreal))); + + // Connect the modeChanged signal from qmlObject + // into modeChanged slot of this class. + connect(qmlObject, SIGNAL(modeChanged(bool)), + SLOT(modeChanged(bool))); + + // Connect the microphoneSensitivityChanged signal from + // m_guitarTunerUI into setCutOffPercentage slot of m_analyzer class. + connect(qmlObject, SIGNAL(microphoneSensitivityChanged(qreal)), + m_analyzer, SLOT(setCutOffPercentage(qreal))); + + // Connect the signals from m_analyzer into slots of qmlObject. + connect(m_analyzer, SIGNAL(lowVoice()), + qmlObject, SLOT(lowVoice())); + connect(m_analyzer, SIGNAL(correctFrequency()), + qmlObject, SLOT(correctFrequencyObtained())); + connect(m_analyzer, SIGNAL(voiceDifference(QVariant)), + qmlObject, SLOT(voiceDifferenceChanged(QVariant))); + + // Initialise the MaximumVoiceDifference + // value of qmlObject with the value obtained from m_analyzer. + qmlObject->setProperty("maxVoiceDifference", + m_analyzer->getMaximumVoiceDifference()); + + // Connect the targetFrequencyChanged signal of qmlObject + // into targetFrequencyChanged slot of this class. + connect(qmlObject, SIGNAL(targetFrequencyChanged(qreal)), + SLOT(targetFrequencyChanged(qreal))); + + // Start voice output or input by using the modeChanged function, + // depending of the current mode. + modeChanged(qmlObject->property("isInput").toBool()); + +} + +/** + * Inits audio output. + */ +void GuitarTuner::initAudioOutput() +{ + // Set up the output format. + m_format_output.setFrequency(DataFrequencyHzOutput); + m_format_output.setCodec("audio/pcm"); + m_format_output.setSampleSize(16); + m_format_output.setChannels(1); + m_format_output.setByteOrder(QAudioFormat::LittleEndian); + m_format_output.setSampleType(QAudioFormat::SignedInt); + + // Obtain a default output device, and if the format is not + // supported, find the nearest format available. + QAudioDeviceInfo outputDeviceInfo( + QAudioDeviceInfo::defaultOutputDevice()); + if (!outputDeviceInfo.isFormatSupported(m_format_output)) { + m_format_output = outputDeviceInfo.nearestFormat(m_format_output); + } + + // Create new QAudioOutput and VoiceGenerator instances, and store + // them in m_audioOutput and m_voicegenerator, respectively. + m_audioOutput = new QAudioOutput(outputDeviceInfo, + m_format_output, this); + m_voicegenerator = new VoiceGenerator(m_format_output, + qmlObject->property("frequency").toReal(), + qmlObject->property("volume").toReal(), + this); + + // Connect m_audioOutput stateChanged signal to outputStateChanged. + connect(m_audioOutput, SIGNAL(stateChanged(QAudio::State)), + SLOT(outputStateChanged(QAudio::State))); +} + +/** + * Inits audio input. + */ +void GuitarTuner::initAudioInput() +{ + // Set up the input format. + m_format_input.setFrequency(DataFrequencyHzInput); + m_format_input.setCodec("audio/pcm"); + m_format_input.setSampleSize(16); + m_format_input.setChannels(1); + m_format_input.setByteOrder(QAudioFormat::LittleEndian); + m_format_input.setSampleType(QAudioFormat::SignedInt); + + // Obtain a default input device, and if the format is not + // supported, find the nearest format available. + QAudioDeviceInfo inputDeviceInfo( + QAudioDeviceInfo::defaultInputDevice()); + if (!inputDeviceInfo.isFormatSupported(m_format_input)) { + m_format_input = inputDeviceInfo.nearestFormat(m_format_input); + } + + // Create new QAudioInput and VoiceAnalyzer instances, and store + // them in m_audioInput and m_analyzer, respectively. + // Remember to set the cut-off percentage for voice analyzer. + m_audioInput = new QAudioInput(inputDeviceInfo, m_format_input, this); + m_analyzer = new VoiceAnalyzer(m_format_input, this); + m_analyzer->setCutOffPercentage(qmlObject->property("sensitivity").toReal()); + +} + +/** + * Receives a mode changed signal. + */ +void GuitarTuner::modeChanged(bool isInput) +{ + + + + // If the mode must be changed to input mode: + if (isInput) { + + // Stop audio output and audio generator. + m_audioOutput->stop(); + m_voicegenerator->stop(); + // Start the audio analyzer and then the audio input. + m_analyzer->start(qmlObject->property("frequency").toReal()); + m_audioInput->start(m_analyzer); + + } + // Else: + else { + + // Stop audio input and audio analyzer. + m_audioInput->stop(); + m_analyzer->stop(); + + // Set up the audio output. + + // If the current frequency of voice generator + // is not the same as the target frequency selected in the UI, + // update voice generator's frequency. + if (m_voicegenerator->frequency() != qmlObject->property("frequency").toReal()) { + m_voicegenerator->setFrequency(qmlObject->property("frequency").toReal()); + } + + // Start the voice generator and then the audio output. + m_voicegenerator->start(); + m_audioOutput->start(m_voicegenerator); + // Call setMaxVolumeLevel(1) to set the maximum volume louder. + setMaxVolumeLevel(qmlObject->property("volume").toReal()); + + // If the voice is muted, the voice is suspended + // in the outputStateChanged slot. + + } +} + +/** + * Receives a output state changed signal. + * Suspends the audio output, if the state is ActiveState + * and the voice is muted. + */ +void GuitarTuner::outputStateChanged(QAudio::State state) +{ + if (QAudio::ActiveState == state && qmlObject->property("isMuted").toBool()) { + // If the voice is muted, suspend the voice. + m_audioOutput->suspend(); + } +} + +/** + * Receives a mute state changed signal. + * Suspends the audio output or resumes it, depending of the + * isMuted parameter. + */ +void GuitarTuner::muteStateChanged(bool isMuted) +{ + if (isMuted) { + m_audioOutput->suspend(); + } + else { + m_audioOutput->resume(); + } +} + +/** + * Receives a target frequency signal. + */ +void GuitarTuner::targetFrequencyChanged(qreal targetFrequency) +{ + // If the output mode is active: + if (!qmlObject->property("isInput").toBool()) { + // Stop the audio output and voice generator. + m_audioOutput->stop(); + m_voicegenerator->stop(); + // Set the voice generator's frequency to the target frequency. + m_voicegenerator->setFrequency(targetFrequency); + // Start the voice generator and audio output. + m_voicegenerator->start(); + m_audioOutput->start(m_voicegenerator); + // Call setMaxVolumeLevel(1) to set the maximum volume louder. + setMaxVolumeLevel(qmlObject->property("volume").toReal()); + + // If the voice is muted, the voice is suspended + // in the outputStateChanged slot. + + } + // Else: + else { + + // Stop the audio input and voice analyzer. + m_audioInput->stop(); + m_analyzer->stop(); + // Start the voice analyzer with new frequency and audio input. + m_analyzer->start(targetFrequency); + m_audioInput->start(m_analyzer); + + } +} + +/** + * This method provides a hack to set the maximum volume level in + * Symbian. + */ +void GuitarTuner::setMaxVolumeLevel(qreal percent) +{ + if (percent >= 1.0) { + percent = 1.0; + } + else if (percent <= 0.0) { + percent = 0.0; + } + percent = percent*0.5 + 0.5; + // Warning! This is a hack, which can break when the QtMobility + // changes. Use at your own risk. +#ifdef Q_OS_SYMBIAN + unsigned int *pointer_to_abstract_audio + = (unsigned int*)( (unsigned char*)m_audioOutput + 8 ); + unsigned int *dev_sound_wrapper + = (unsigned int*)(*pointer_to_abstract_audio) + 16; + unsigned int *temp + = ((unsigned int*)(*dev_sound_wrapper) + 6); + CMMFDevSound *dev_sound = (CMMFDevSound*)(*temp); + dev_sound->SetVolume((unsigned int) + (percent*(float)dev_sound->MaxVolume())); +#endif +} + +/** + * A function used to lock the orientation. + */ +void GuitarTuner::setOrientation(Orientation orientation) +{ +#ifdef Q_OS_SYMBIAN + if (orientation != Auto) { +#if defined(ORIENTATIONLOCK) + const CAknAppUiBase::TAppUiOrientation uiOrientation = + (orientation == LockPortrait) + ? CAknAppUi::EAppUiOrientationPortrait + : CAknAppUi::EAppUiOrientationLandscape; + CAknAppUi* appUi = dynamic_cast<CAknAppUi*> + (CEikonEnv::Static()->AppUi()); + TRAPD(error, + if (appUi) + appUi->SetOrientationL(uiOrientation); + ); +#else // ORIENTATIONLOCK + qWarning(QString("'ORIENTATIONLOCK' needs to be defined on") + +QString(" Symbian when locking the orientation.")); +#endif // ORIENTATIONLOCK + } +#elif defined(Q_WS_MAEMO_5) + Qt::WidgetAttribute attribute; + switch (orientation) { + case LockPortrait: + attribute = Qt::WA_Maemo5PortraitOrientation; + break; + case LockLandscape: + attribute = Qt::WA_Maemo5LandscapeOrientation; + break; + case Auto: + default: + attribute = Qt::WA_Maemo5AutoOrientation; + break; + } + setAttribute(attribute, true); +#else // Q_OS_SYMBIAN + Q_UNUSED(orientation); +#endif // Q_OS_SYMBIAN +} diff --git a/demos/mobile/guitartuner/src/guitartuner.h b/demos/mobile/guitartuner/src/guitartuner.h new file mode 100644 index 0000000..aa3e9f8 --- /dev/null +++ b/demos/mobile/guitartuner/src/guitartuner.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> +#include <QtDeclarative> +#include <QAudioDeviceInfo> +#include <QAudioOutput> +#include <QAudioInput> +#include "voicegenerator.h" +#include "voiceanalyzer.h" + +const int DataFrequencyHzOutput = 44100; +const int DataFrequencyHzInput = 48000; + +#define MAX_INPUT_VALUE 50 +#define MIN_INPUT_VALUE -50 + +class GuitarTuner : public QMainWindow +{ + Q_OBJECT +public: + enum Orientation { + LockPortrait, + LockLandscape, + Auto + }; + explicit GuitarTuner(QWidget *parent = 0); + qreal getVolume(); + qreal getMicrophoneSensitivity(); + bool getMuteState(); + void setOrientation(Orientation orientation); + +signals: + +public slots: + void modeChanged(bool isInput); + void muteStateChanged(bool isMuted); + void targetFrequencyChanged(qreal targetFrequency); + void outputStateChanged(QAudio::State state); + void setMaxVolumeLevel(qreal); + +private: + void initAudioOutput(); + void initAudioInput(); + VoiceGenerator *m_voicegenerator; + VoiceAnalyzer *m_analyzer; + QObject *qmlObject; + QAudioOutput *m_audioOutput; + QAudioInput *m_audioInput; + QAudioFormat m_format_output; + QAudioFormat m_format_input; + QDeclarativeView *m_guitarTunerUI; +}; + +#endif // MAINWINDOW_H diff --git a/demos/mobile/guitartuner/src/guitartuner.rc b/demos/mobile/guitartuner/src/guitartuner.rc new file mode 100644 index 0000000..85cee0b --- /dev/null +++ b/demos/mobile/guitartuner/src/guitartuner.rc @@ -0,0 +1,23 @@ +IDI_ICON1 ICON DISCARDABLE "/../images/guitartuner_icon.ico" + +1 VERSIONINFO +FILEVERSION 1,2,0,0 +PRODUCTVERSION 1,2,0,0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", "Nokia Corporation\0" + VALUE "FileDescription", "Qt Quick example application.\0" + VALUE "FileVersion", "1.2.0\0" + VALUE "LegalCopyright", "Copyright 2011 Nokia Corporation. All rights reserved.\0" + VALUE "ProductName", "Guitar Tuner\0" + VALUE "ProductVersion", "1.2.0\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END
\ No newline at end of file diff --git a/demos/mobile/guitartuner/src/guitartuner.ui b/demos/mobile/guitartuner/src/guitartuner.ui new file mode 100644 index 0000000..36ee1bd --- /dev/null +++ b/demos/mobile/guitartuner/src/guitartuner.ui @@ -0,0 +1,178 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>GuitarTuner</class> + <widget class="QWidget" name="GuitarTuner"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>187</width> + <height>279</height> + </rect> + </property> + <property name="windowTitle"> + <string>GuitarTuner</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="tabulatorIcon"> + <property name="text"> + <string notr="true"/> + </property> + <property name="pixmap"> + <pixmap resource="../guitartuner.qrc">:/images/guitartab.svg</pixmap> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QSlider" name="correctSoundSlider"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <property name="minimum"> + <number>-50</number> + </property> + <property name="maximum"> + <number>50</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="tickPosition"> + <enum>QSlider::TicksAbove</enum> + </property> + <property name="tickInterval"> + <number>50</number> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QToolButton" name="buttonPrev"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="arrowType"> + <enum>Qt::LeftArrow</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="noteLabel"> + <property name="text"> + <string>A</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="buttonNext"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="autoRaise"> + <bool>false</bool> + </property> + <property name="arrowType"> + <enum>Qt::RightArrow</enum> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QPushButton" name="modeButton"> + <property name="text"> + <string>Change mode</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QSlider" name="soundSlider"> + <property name="value"> + <number>65</number> + </property> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="soundButton"> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset resource="../guitartuner.qrc"> + <normaloff>:/images/note.svg</normaloff> + <normalon>:/images/noteNo.svg</normalon> + <activeon>:/images/noteNo.svg</activeon>:/images/note.svg</iconset> + </property> + <property name="iconSize"> + <size> + <width>30</width> + <height>30</height> + </size> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="micSensitivityLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>microphone +sensitivity</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources> + <include location="../guitartuner.qrc"/> + </resources> + <connections/> +</ui> diff --git a/demos/mobile/guitartuner/src/guitartunerui.cpp b/demos/mobile/guitartuner/src/guitartunerui.cpp new file mode 100644 index 0000000..9d59d7c --- /dev/null +++ b/demos/mobile/guitartuner/src/guitartunerui.cpp @@ -0,0 +1,341 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QTimer> + +#include "guitartunerui.h" +#include "ui_guitartunerui.h" + +GuitarTunerUI::GuitarTunerUI(QWidget *parent) : + QWidget(parent), + ui(new Ui::GuitarTunerUI), + m_maximumPrecision(0) +{ + ui->setupUi(this); + + // Set up the class attributes to proper values. + m_outputActive = false; + m_muted = false; + m_outputVolumeLevel = getVolumeFromSoundSlider(); + m_inputVolumeLevel = 1.0 - m_outputVolumeLevel; + + // Set up the current tone, the frequency, and the name for it. + m_currentToneIndex = 5; + updateFrequencyByToneIndex(m_currentToneIndex); + + // Connect the signals from UI into proper slots. + connect(ui->soundSlider, SIGNAL(valueChanged(int)), + SLOT(changeVolume())); + connect(ui->soundButton, SIGNAL(toggled(bool)), + SLOT(toggleSound(bool))); + connect(ui->modeButton, SIGNAL(clicked()), + SLOT(toggleInputOrOutput())); + connect(ui->buttonNext, SIGNAL(clicked()), SLOT(next())); + connect(ui->buttonPrev, SIGNAL(clicked()), SLOT(prev())); + + // Initialise up the UI by calling toggleInputOrOutput + // for the first time. + toggleInputOrOutput(); +} + +GuitarTunerUI::~GuitarTunerUI() +{ + delete ui; +} + +void GuitarTunerUI::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +/** + * Returns a value from 0 to 1, representing the volume. + */ +qreal GuitarTunerUI::getVolumeFromSoundSlider() const +{ + qreal value = ui->soundSlider->value(); + return value/ui->soundSlider->maximum(); +} + +/** + * Updates the m_currentToneFrequency and m_currentToneString, + * according to the given index. Also updates the UI. + */ +void GuitarTunerUI::updateFrequencyByToneIndex(int index) +{ + + switch (index) { + case 0: { + m_currentToneFrequency = FrequencyE; + m_currentToneString = "E"; + break; + } + case 1: { + m_currentToneFrequency = FrequencyA; + m_currentToneString = "A"; + break; + } + case 2: { + m_currentToneFrequency = FrequencyD; + m_currentToneString = "D"; + break; + } + case 3: { + m_currentToneFrequency = FrequencyG; + m_currentToneString = "G"; + break; + } + case 4: { + m_currentToneFrequency = FrequencyB; + m_currentToneString = "B"; + break; + } + case 5: { + m_currentToneFrequency = FrequencyE2; + m_currentToneString = "e"; + break; + } + default: { + qDebug() << "invalid index!" << index; + } + } + // Set the noteLabel text according to the current tone. + ui->noteLabel->setText(m_currentToneString); +} + +/** + * Returns the volume. + */ +qreal GuitarTunerUI::getVolume() const +{ + return m_outputVolumeLevel; +} + +/** + * Returns true if the sound is muted. + */ +bool GuitarTunerUI::getMuteState() const +{ + return m_muted; +} + + +/** + * Returns the microphone sensitivity. + */ +qreal GuitarTunerUI::getMicrophoneSensitivity() const +{ + return m_inputVolumeLevel; +} + +/** + * Returns whether the input mode is active. + */ +bool GuitarTunerUI::isInputModeActive() const +{ + return !m_outputActive; +} + +/** + * Returns the current target frequency. + */ +qreal GuitarTunerUI::getFrequency() const +{ + return m_currentToneFrequency; +} + +/** + * Toggles the sound according to the parameter. + * Has no effect if output is not active. + */ +void GuitarTunerUI::toggleSound(bool noSound) +{ + if (!m_outputActive) { + return; + } + m_muted = noSound; + emit muteChanged(m_muted); +} + +/** + * Changes the volume or microphone sensitivity. + */ +void GuitarTunerUI::changeVolume() +{ + qreal resultingAmplitude = getVolumeFromSoundSlider(); + qDebug() << "resultingAmplitude" << resultingAmplitude; + if (m_outputActive) { + m_outputVolumeLevel = resultingAmplitude; + emit volumeChanged(resultingAmplitude); + } + else { + m_inputVolumeLevel = resultingAmplitude; + emit microphoneSensitivityChanged(1.0-resultingAmplitude); + } +} + +/** + * Toggles input or output, depending of the current state. + */ +void GuitarTunerUI::toggleInputOrOutput() +{ + // If output mode is active: + if (m_outputActive) { + // Change UI to correspond to the input mode. + m_outputActive = false; + ui->soundSlider->setValue(m_inputVolumeLevel*100); + ui->soundButton->setDisabled(true); + ui->soundButton->hide(); + ui->micSensitivityLabel->show(); + emit modeChanged(true); + ui->modeButton->setText("To tone mode"); + } + // Else: + else { + // Change UI to correspond to the output mode. + m_outputActive = true; + ui->soundSlider->setValue(m_outputVolumeLevel*100); + ui->soundButton->setDisabled(false); + ui->micSensitivityLabel->hide(); + ui->soundButton->show(); + emit modeChanged(false); + ui->modeButton->setText("To listen mode"); + } +} + +/** + * Receives the low voice signal. + */ +void GuitarTunerUI::lowVoice() +{ + if (ui->noteLabel->font().bold()) { + QFont font; + font.setBold(false); + font.setUnderline(false); + ui->noteLabel->setFont(font); + } +} + +/** + * Receives the voice difference signal. + * The difference is qreal, where increase of 1 corresponds + * to increase of 1 tone to the target frequency. + */ +void GuitarTunerUI::voiceDifference(qreal difference) +{ + if (ui->noteLabel->font().bold()) { + QFont font; + font.setBold(false); + font.setUnderline(false); + ui->noteLabel->setFont(font); + } + ui->correctSoundSlider->setValue(difference*m_maximumPrecision); +} + +/** + * Receives the correct frequency signal. + * Makes the UI to visualize correct frequency event. + */ +void GuitarTunerUI::correctFrequencyObtained() +{ + qDebug() << "CORRECT FREQUENCY"; + QFont font; + font.setBold(true); + font.setUnderline(true); + ui->noteLabel->setFont(font); +} + +/** + * Sets up the maximum voice difference. + */ +void GuitarTunerUI::setMaximumVoiceDifference(int max) +{ + // Assert that the maximum precision is known. + Q_ASSERT(m_maximumPrecision != 0); + // Set the maximum and minimum values of the correctSoundSlider + // to the +- max*m_maximumPrecision, and set the tick interval + // to be m_maximumPrecision. + ui->correctSoundSlider->setMaximum(max*m_maximumPrecision); + ui->correctSoundSlider->setMinimum(-max*m_maximumPrecision); + ui->correctSoundSlider->setTickInterval(max*m_maximumPrecision); +} + +/** + * Stores the maximum precision per note. Used to setup the + * correct sound slider. + */ +void GuitarTunerUI::setMaximumPrecisionPerNote(int max) +{ + m_maximumPrecision = max; +} + +/** + * Changes the tone to the next value. + */ +void GuitarTunerUI::next() +{ + changeTone((m_currentToneIndex + 1) % 6); +} + +/** + * Changes the tone to the previous value. + */ +void GuitarTunerUI::prev() +{ + changeTone((m_currentToneIndex + 5) % 6); +} + +/** + * Changes the tone according to the new index. + */ +void GuitarTunerUI::changeTone(int newIndex) +{ + m_currentToneIndex = newIndex; + updateFrequencyByToneIndex(m_currentToneIndex); + qDebug() << "targetFrequencyChanged" << m_currentToneFrequency; + emit targetFrequencyChanged(m_currentToneFrequency); +} diff --git a/demos/mobile/guitartuner/src/guitartunerui.h b/demos/mobile/guitartuner/src/guitartunerui.h new file mode 100644 index 0000000..fa8e8f4 --- /dev/null +++ b/demos/mobile/guitartuner/src/guitartunerui.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GUITARTUNERUI_H +#define GUITARTUNERUI_H + +#include <QWidget> +#include <QDebug> + +namespace Ui { + class GuitarTunerUI; +} + +const qreal FrequencyE = 82.407; +const qreal FrequencyA = 110.00; +const qreal FrequencyD = 146.83; +const qreal FrequencyG = 196.00; +const qreal FrequencyB = 246.94; +const qreal FrequencyE2 = 329.63; + +class GuitarTunerUI : public QWidget +{ + Q_OBJECT + +public: + explicit GuitarTunerUI(QWidget *parent = 0); + ~GuitarTunerUI(); + + qreal getVolume() const; + bool getMuteState() const; + qreal getMicrophoneSensitivity() const; + bool isInputModeActive() const; + qreal getFrequency() const; + int getScaleMaximumValue() const; + void setMaximumVoiceDifference(int max); + void setMaximumPrecisionPerNote(int max); + +public slots: + void toggleSound(bool off); + void next(); + void prev(); + void changeVolume(); + void toggleInputOrOutput(); + + void lowVoice(); + void voiceDifference(qreal difference); + void correctFrequencyObtained(); + +signals: + void modeChanged(bool isInput); + void volumeChanged(qreal volume); + void microphoneSensitivityChanged(qreal sensitivity); + void muteChanged(bool isMuted); + void targetFrequencyChanged(qreal targetFrequency); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::GuitarTunerUI *ui; + void changeTone(int newIndex); + qreal getVolumeFromSoundSlider() const; + int m_currentToneIndex; + QString m_currentToneString; + qreal m_currentToneFrequency; + void updateFrequencyByToneIndex(int index); + bool m_outputActive; + bool m_muted; + qreal m_outputVolumeLevel; + qreal m_inputVolumeLevel; + int m_maximumPrecision; +}; + +#endif // GUITARTUNERUI_H diff --git a/demos/mobile/guitartuner/src/guitartunerui.ui b/demos/mobile/guitartuner/src/guitartunerui.ui new file mode 100644 index 0000000..af7b585 --- /dev/null +++ b/demos/mobile/guitartuner/src/guitartunerui.ui @@ -0,0 +1,178 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>GuitarTunerUI</class> + <widget class="QWidget" name="GuitarTunerUI"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>187</width> + <height>279</height> + </rect> + </property> + <property name="windowTitle"> + <string>GuitarTunerUI</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="tabulatorIcon"> + <property name="text"> + <string notr="true"/> + </property> + <property name="pixmap"> + <pixmap resource="../GuitarTuner.qrc">:/images/guitartab.svg</pixmap> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QSlider" name="correctSoundSlider"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <property name="minimum"> + <number>-50</number> + </property> + <property name="maximum"> + <number>50</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="tickPosition"> + <enum>QSlider::TicksAbove</enum> + </property> + <property name="tickInterval"> + <number>50</number> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QToolButton" name="buttonPrev"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="arrowType"> + <enum>Qt::LeftArrow</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="noteLabel"> + <property name="text"> + <string>A</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="buttonNext"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="autoRaise"> + <bool>false</bool> + </property> + <property name="arrowType"> + <enum>Qt::RightArrow</enum> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QPushButton" name="modeButton"> + <property name="text"> + <string>Change mode</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QSlider" name="soundSlider"> + <property name="value"> + <number>65</number> + </property> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="soundButton"> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset resource="../GuitarTuner.qrc"> + <normaloff>:/images/note.svg</normaloff> + <normalon>:/images/noteNo.svg</normalon> + <activeon>:/images/noteNo.svg</activeon>:/images/note.svg</iconset> + </property> + <property name="iconSize"> + <size> + <width>30</width> + <height>30</height> + </size> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="micSensitivityLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>microphone +sensitivity</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <resources> + <include location="../GuitarTuner.qrc"/> + </resources> + <connections/> +</ui> diff --git a/demos/mobile/guitartuner/src/main.cpp b/demos/mobile/guitartuner/src/main.cpp new file mode 100644 index 0000000..33b1181 --- /dev/null +++ b/demos/mobile/guitartuner/src/main.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/QApplication> +#include "guitartuner.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + GuitarTuner w; + w.setOrientation(GuitarTuner::LockPortrait); + +#ifdef Q_OS_SYMBIAN + w.showFullScreen(); +#elif defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) + w.showMaximized(); +#else + w.show(); +#endif + + return a.exec(); +} + diff --git a/demos/mobile/guitartuner/src/mycomponents/Adjuster.qml b/demos/mobile/guitartuner/src/mycomponents/Adjuster.qml new file mode 100644 index 0000000..342e6f7 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/Adjuster.qml @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.0 +import "adjustbars.js" as AdjustBars + +/* A barchart-like adjuster component. */ +Rectangle { + id: adjuster + + property real max: 100 + property real value: 0 + property bool created: false + + signal valueChanged(real value) + signal focusChangedByClick() + signal arrowPressedWhenValueOverLimits() + + function setValue(pValue) { + value = pValue; + AdjustBars.fillBars(value/max*AdjustBars.maxBars); + valueChanged(value); + } + + height: 60; width: 300 + color: "transparent" + Keys.onRightPressed: { + var val = value+max/AdjustBars.maxBars; + if (val <= max) { + value = val; + AdjustBars.fillBars(value/max*AdjustBars.maxBars); + valueChanged(value); + } + else { + arrowPressedWhenValueOverLimits() + } + } + Keys.onLeftPressed: { + var val = value-max/AdjustBars.maxBars; + if (0 <= val) { + value = val; + AdjustBars.fillBars(value/max*AdjustBars.maxBars); + valueChanged(value); + } + else { + arrowPressedWhenValueOverLimits() + } + } + Component.onCompleted: { + AdjustBars.createBars(); + AdjustBars.fillBars(value/max*AdjustBars.maxBars); + created = true; + } + Component.onDestruction: { + AdjustBars.destroyBars; + } + //Dynamic objects have to be recreated when the window size changes. + onWidthChanged: { + if (created) { + AdjustBars.destroyBars(); + AdjustBars.createBars(); + AdjustBars.fillBars(value/max*AdjustBars.maxBars); + } + } + onHeightChanged: { + if (created) { + AdjustBars.destroyBars(); + AdjustBars.createBars(); + AdjustBars.fillBars(value/max*AdjustBars.maxBars); + } + } + + MouseArea { + anchors.fill: parent + onPositionChanged: { + focusChangedByClick(); + var val = mouse.x/parent.width*parent.max; + if (0 < val && val < max) { + parent.value = val; + AdjustBars.fillBars(parent.value/parent.max*AdjustBars.maxBars); + valueChanged(parent.value); + } + } + onClicked: { + focusChangedByClick(); + var val = mouse.x/parent.width*parent.max; + if (0 < val && val < max) { + parent.value = val; + AdjustBars.fillBars(parent.value/parent.max*AdjustBars.maxBars); + valueChanged(parent.value); + } + } + } +} diff --git a/demos/mobile/guitartuner/src/mycomponents/Meter.qml b/demos/mobile/guitartuner/src/mycomponents/Meter.qml new file mode 100644 index 0000000..8a64711 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/Meter.qml @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.0 + +/* A meter component. */ +Rectangle { + id: meter + + property real value: 0 + property real minValue: -1 + property real maxValue: 1 + property alias imageSize: meterImage.sourceSize + + function valueChanged(pValue) { + value = pValue; + scaleValueToAngle(); + } + function scaleValueToAngle() { + pointer.angle = (((value-minValue)/(maxValue-minValue))* + (pointer.angleMax-pointer.angleMin))+ + pointer.angleMin; + } + + color: "transparent" + + Image { + id: meterImage + + smooth: true + source: "./images/meterBG.png" + anchors.fill: parent + } + + Image { + id:pointerShadow + + x: pointer.x - 2 + y: pointer.y - 2 + height: pointer.height + smooth: true + source: "./images/pointerShadow.png" + transform: Rotation { + origin.x: 2 + origin.y: height + angle: -pointer.angle + } + } + + Image { + id: pointer + + property real angle: 0 + property real angleMax: -45 + property real angleMin: 45 + + height: parent.height*0.92 + transformOrigin: "Bottom" + rotation: -angle + smooth: true + source: "./images/pointer.png" + anchors { + bottomMargin: 2 + bottom: parent.bottom; + horizontalCenter: parent.horizontalCenter + } + + Behavior on angle { + SpringAnimation { + spring: 1.4 + damping: 0.15 + } + } + } +} diff --git a/demos/mobile/guitartuner/src/mycomponents/NoteButtonView.qml b/demos/mobile/guitartuner/src/mycomponents/NoteButtonView.qml new file mode 100644 index 0000000..fc64fe5 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/NoteButtonView.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.0 + +/* A view component for buttons for choosing notes. */ +ListView { + id: noteChooser + + property real currentFrequency: 82.407 + + signal noteSelected(string note, real frequency, int index) + + //Press down the button corresponding to the given note. + function pushButton(index) { + currentIndex = index; + } + + width: 50*model.count + spacing*(model.count-1); height: 50 + orientation: ListView.Horizontal + model: NotesModel {} + delegate: notesDelegate + keyNavigationWraps: true + boundsBehavior: Flickable.StopAtBounds + + Component { + id: notesDelegate + + ToggleButton { + id: noteButton + + width: height; height: noteChooser.height + offImageSource: offSource + onImageSource: onSource + state: noteButton.ListView.isCurrentItem ? "pressed" : "unPressed" + onSelected: { + noteChooser.noteSelected(note, frequency, index) + if (note != "Auto") { + currentFrequency = frequency + } + } + onPushed: { + noteButton.ListView.view.currentIndex = index + } + } + } +} diff --git a/demos/mobile/guitartuner/src/mycomponents/NotesModel.qml b/demos/mobile/guitartuner/src/mycomponents/NotesModel.qml new file mode 100644 index 0000000..3d9c12a --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/NotesModel.qml @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.0 + +/* The model component for the NoteButtonView. */ +ListModel { + ListElement { + note: "E" + offSource: "./images/tuner_e.png" + onSource: "./images/tuner_e_on.png" + bigSource: "./mycomponents/images/big_e.png" + glowSource: "./mycomponents/images/glowing_e.png" + frequency: "82.407" + interval: "5" + } + ListElement { + note: "A" + offSource: "./images/tuner_a.png" + onSource: "./images/tuner_a_on.png" + bigSource: "./mycomponents/images/big_a.png" + glowSource: "./mycomponents/images/glowing_a.png" + frequency: "110.00" + interval: "5" + } + ListElement { + note: "D" + offSource: "./images/tuner_d.png" + onSource: "./images/tuner_d_on.png" + bigSource: "./mycomponents/images/big_d.png" + glowSource: "./mycomponents/images/glowing_d.png" + frequency: "146.83" + interval: "5" + } + ListElement { + note: "G" + offSource: "./images/tuner_g.png" + onSource: "./images/tuner_g_on.png" + bigSource: "./mycomponents/images/big_g.png" + glowSource: "./mycomponents/images/glowing_g.png" + frequency: "196.00" + interval: "4" + } + ListElement { + note: "B" + offSource: "./images/tuner_b.png" + onSource: "./images/tuner_b_on.png" + bigSource: "./mycomponents/images/big_b.png" + glowSource: "./mycomponents/images/glowing_b.png" + frequency: "246.94" + interval: "5" + } + ListElement { + note: "e" + offSource: "./images/tuner_e.png" + onSource: "./images/tuner_e_on.png" + bigSource: "./mycomponents/images/big_e.png" + glowSource: "./mycomponents/images/glowing_e.png" + frequency: "329.63" + interval: "9999" //Big enough that we can't move over this note + } + ListElement { + note: "Auto" + offSource: "./images/tuner_auto.png" + onSource: "./images/tuner_auto_on.png" + frequency: "82.407" + } +} diff --git a/demos/mobile/guitartuner/src/mycomponents/ToggleButton.qml b/demos/mobile/guitartuner/src/mycomponents/ToggleButton.qml new file mode 100644 index 0000000..cecf015 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/ToggleButton.qml @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.0 + +/* A toggle button component. */ +Rectangle { + id: toggleButton + + property url offImageSource: "" + property url onImageSource: "" + property alias imageSource: buttonImage.source + + signal selected() + signal pushed() + + color: "transparent" + state: "unPressed" + onStateChanged: { + if (state == "pressed") { + selected() + } + } + + Image { + id: buttonImage + + smooth: true + anchors.fill: parent + } + MouseArea { + id: mouseArea + + anchors.fill: parent + onPressed: { + if (parent.state == "unPressed") { + pushed() + } + } + } + + states: [ + State { + name: "pressed" + PropertyChanges { + target: toggleButton + scale: 0.95 + imageSource: onImageSource + } + }, + State { + name: "unPressed" + PropertyChanges { + target: toggleButton + scale: 1/0.95 + imageSource: offImageSource + } + } + ] + + transitions: [ + Transition { + from: "unPressed" + to: "pressed" + reversible: true + PropertyAnimation { + target: toggleButton + properties: "scale" + duration: 100 + } + } + ] +} diff --git a/demos/mobile/guitartuner/src/mycomponents/adjustbars.js b/demos/mobile/guitartuner/src/mycomponents/adjustbars.js new file mode 100644 index 0000000..a96292d --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/adjustbars.js @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* JavaScript functions for creating, handling and + * destroying the bars of the adjuster component. */ + +var maxBars = 10; +var firstBarHeight = 5; +var bars = new Array(maxBars); +var colors = new Array(maxBars); +var barWidthFactor = 2.3; + +function createBars() { + var barWidth = adjuster.width/maxBars/barWidthFactor; + for (var i = 1; i <= maxBars; i++) { + //Create, configure and store the bars. + var bar = Qt.createQmlObject('import QtQuick 1.0; Rectangle {smooth: true}', adjuster, "dynamicBar"); + bar.width = barWidth; + bar.height = firstBarHeight+(i/maxBars)*(adjuster.height*0.8-firstBarHeight); + bar.radius = bar.width/2; + bar.x = (i-1)*(barWidthFactor*barWidth); + bar.y = adjuster.height/2 - bar.height/2; + bars[i-1] = bar; + + //Calculate and store the colors + if (i < maxBars/2) { + colors[i-1] = Qt.rgba(1-i/(maxBars/2), 1, 1-i/(maxBars/2), i); + } + else { + colors[i-1] = Qt.rgba((i-(maxBars/2))/(maxBars/2), 1-((i-(maxBars/2))/(maxBars/2)), 0, i); + } + } +} + +function destroyBars() { + for (var i = 0; i < maxBars; i++) { + bars[i].color = "transparent" //Colors must be set to transparent or otherwise the bars will stay appeared. + bars[i].destroy(); + } +} + +function fillBars(barNumber) { + //Set the color for the bars (transparent from the selected bar to the end). + for (var i = 0; i < maxBars; i++) { + if (i < barNumber) { + bars[i].color = colors[i]; + } + else { + bars[i].color = "black"; + } + } +} diff --git a/demos/mobile/guitartuner/src/mycomponents/images/big_a.png b/demos/mobile/guitartuner/src/mycomponents/images/big_a.png Binary files differnew file mode 100644 index 0000000..3838e76 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/big_a.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/big_b.png b/demos/mobile/guitartuner/src/mycomponents/images/big_b.png Binary files differnew file mode 100644 index 0000000..114b32d --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/big_b.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/big_d.png b/demos/mobile/guitartuner/src/mycomponents/images/big_d.png Binary files differnew file mode 100644 index 0000000..3ede9f0 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/big_d.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/big_e.png b/demos/mobile/guitartuner/src/mycomponents/images/big_e.png Binary files differnew file mode 100644 index 0000000..cc1f488 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/big_e.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/big_g.png b/demos/mobile/guitartuner/src/mycomponents/images/big_g.png Binary files differnew file mode 100644 index 0000000..804177b --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/big_g.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/glowing_a.png b/demos/mobile/guitartuner/src/mycomponents/images/glowing_a.png Binary files differnew file mode 100644 index 0000000..b6fd0e2 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/glowing_a.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/glowing_b.png b/demos/mobile/guitartuner/src/mycomponents/images/glowing_b.png Binary files differnew file mode 100644 index 0000000..b5fa016 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/glowing_b.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/glowing_d.png b/demos/mobile/guitartuner/src/mycomponents/images/glowing_d.png Binary files differnew file mode 100644 index 0000000..32f1a29 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/glowing_d.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/glowing_e.png b/demos/mobile/guitartuner/src/mycomponents/images/glowing_e.png Binary files differnew file mode 100644 index 0000000..4be9f2a --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/glowing_e.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/glowing_g.png b/demos/mobile/guitartuner/src/mycomponents/images/glowing_g.png Binary files differnew file mode 100644 index 0000000..4216d82 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/glowing_g.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/guitartuner_malli.png b/demos/mobile/guitartuner/src/mycomponents/images/guitartuner_malli.png Binary files differnew file mode 100644 index 0000000..dbe3fc7 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/guitartuner_malli.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/guitartuner_skin.png b/demos/mobile/guitartuner/src/mycomponents/images/guitartuner_skin.png Binary files differnew file mode 100644 index 0000000..5d53df9 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/guitartuner_skin.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/lcdFrame.png b/demos/mobile/guitartuner/src/mycomponents/images/lcdFrame.png Binary files differnew file mode 100644 index 0000000..ff8dffc --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/lcdFrame.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/meterBG.png b/demos/mobile/guitartuner/src/mycomponents/images/meterBG.png Binary files differnew file mode 100644 index 0000000..4046355 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/meterBG.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/mute.png b/demos/mobile/guitartuner/src/mycomponents/images/mute.png Binary files differnew file mode 100644 index 0000000..382e6047 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/mute.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/pointer.png b/demos/mobile/guitartuner/src/mycomponents/images/pointer.png Binary files differnew file mode 100644 index 0000000..d0cb21b --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/pointer.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/pointerShadow.png b/demos/mobile/guitartuner/src/mycomponents/images/pointerShadow.png Binary files differnew file mode 100644 index 0000000..a708639 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/pointerShadow.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/power.png b/demos/mobile/guitartuner/src/mycomponents/images/power.png Binary files differnew file mode 100644 index 0000000..8ec0c5c --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/power.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/quit.png b/demos/mobile/guitartuner/src/mycomponents/images/quit.png Binary files differnew file mode 100644 index 0000000..2a9443e --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/quit.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/sensitivity.png b/demos/mobile/guitartuner/src/mycomponents/images/sensitivity.png Binary files differnew file mode 100644 index 0000000..c3d2ea3 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/sensitivity.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_a.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_a.png Binary files differnew file mode 100644 index 0000000..a1823e5 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_a.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_a_on.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_a_on.png Binary files differnew file mode 100644 index 0000000..7c78cbd --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_a_on.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_auto.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_auto.png Binary files differnew file mode 100644 index 0000000..b9e494b --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_auto.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_auto_on.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_auto_on.png Binary files differnew file mode 100644 index 0000000..d5608d8 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_auto_on.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_b.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_b.png Binary files differnew file mode 100644 index 0000000..94977f8 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_b.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_b_on.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_b_on.png Binary files differnew file mode 100644 index 0000000..78841dc --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_b_on.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_d.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_d.png Binary files differnew file mode 100644 index 0000000..293ee55 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_d.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_d_on.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_d_on.png Binary files differnew file mode 100644 index 0000000..705de41 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_d_on.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_e.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_e.png Binary files differnew file mode 100644 index 0000000..569d2c6 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_e.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_e_on.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_e_on.png Binary files differnew file mode 100644 index 0000000..1342a91 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_e_on.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_g.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_g.png Binary files differnew file mode 100644 index 0000000..a8f0de5 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_g.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/tuner_g_on.png b/demos/mobile/guitartuner/src/mycomponents/images/tuner_g_on.png Binary files differnew file mode 100644 index 0000000..6fdca41 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/tuner_g_on.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/voicemode_off.png b/demos/mobile/guitartuner/src/mycomponents/images/voicemode_off.png Binary files differnew file mode 100644 index 0000000..0701dd3 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/voicemode_off.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/voicemode_on.png b/demos/mobile/guitartuner/src/mycomponents/images/voicemode_on.png Binary files differnew file mode 100644 index 0000000..986d589 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/voicemode_on.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/volume.png b/demos/mobile/guitartuner/src/mycomponents/images/volume.png Binary files differnew file mode 100644 index 0000000..46fdb7f --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/volume.png diff --git a/demos/mobile/guitartuner/src/mycomponents/images/volume_off.png b/demos/mobile/guitartuner/src/mycomponents/images/volume_off.png Binary files differnew file mode 100644 index 0000000..a97e422 --- /dev/null +++ b/demos/mobile/guitartuner/src/mycomponents/images/volume_off.png diff --git a/demos/mobile/guitartuner/src/voiceanalyzer.cpp b/demos/mobile/guitartuner/src/voiceanalyzer.cpp new file mode 100644 index 0000000..9990e6d --- /dev/null +++ b/demos/mobile/guitartuner/src/voiceanalyzer.cpp @@ -0,0 +1,295 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "voiceanalyzer.h" + +/** + * Constant used to scale the cut-off density for the fft helper. + */ +const static float CutOffScaler = 0.05; + +/** + * Force the precision to be "1/PrecisionPerNote" notes + * near the target frequency. + */ +const static int PrecisionPerNote = 4; + +/** + * TargetFrequencyParameter is a constant which implies the index at + * which corresponds to the target frequency. + * 0.5 * N * 1/TargetFrequencyParameter is (about) the index which + * corresponds to the given target frequency. + * Effectively TargetFrequencyParameter = 2^z, and the z*TargetFrequency + * is the maximum frequency that can be noticed. + */ +const static int TargetFrequencyParameter = 4; + + +VoiceAnalyzer::VoiceAnalyzer(const QAudioFormat &format, QObject *parent): + QIODevice(parent), + m_format(format), + m_frequency(0), + m_position(0), + m_fftHelper(new FastFourierTransformer(this)) +{ + Q_ASSERT(qFuzzyCompare(M_SAMPLE_COUNT_MULTIPLIER, + float(2)/(M_TWELTH_ROOT_OF_2 -1.0))); + m_totalSampleCount = qRound(qreal(PrecisionPerNote) + *TargetFrequencyParameter + *M_SAMPLE_COUNT_MULTIPLIER); + m_samples.reserve(m_totalSampleCount); + int i = 2; + int j = 1; + for (; i < TargetFrequencyParameter; i *= 2) { + j++; + } + m_maximumVoiceDifference = j*12; + + setCutOffPercentage(CutOffScaler); +} + +/** + * Opens the parent QIODevice. Sets up the analysation parameters. + */ +void VoiceAnalyzer::start(qreal frequency) +{ + m_stepSize = (qreal) 1.0 * m_format.sampleRate() + / (TargetFrequencyParameter*2*frequency); + m_frequency = frequency; + open(QIODevice::WriteOnly); +} + +/** + * Closes the parent QIODevice, thus the voice is not analysed anymore. + * Resets the m_samples QList. + */ +void VoiceAnalyzer::stop() +{ + m_samples.clear(); + m_samples.reserve(m_totalSampleCount); + close(); +} + +/** + * Called when data is obtained. Stores each m_stepSize sample + * into a QList to be analysed. + */ +qint64 VoiceAnalyzer::writeData(const char *data, qint64 maxlen) +{ + const int channelBytes = m_format.sampleSize() / 8; + int sampleSize = m_format.channels() * channelBytes; + int m_stepSizeInBytes = m_stepSize*sampleSize; + // assert that each sample fits fully into the data + Q_ASSERT((m_position % sampleSize)==0); + const uchar *ptr = reinterpret_cast<const uchar *>(data); + while (m_position < maxlen) { + if (m_samples.size() < m_totalSampleCount) { + m_samples.append(getValueInt16(ptr+m_position)); + } + else { + analyzeVoice(); + m_samples.clear(); + m_samples.reserve(m_totalSampleCount); + // fast forward position to the first position after maxlen or to the maxlen + m_position += ((m_stepSizeInBytes - 1 + maxlen - m_position) / + m_stepSizeInBytes) * m_stepSizeInBytes; + break; + } + m_position += m_stepSizeInBytes; + } + m_position -= maxlen; + return maxlen; +} + +/** + * Interprets ptr as a pointer to int value and returns it. + */ +qint16 VoiceAnalyzer::getValueInt16(const uchar *ptr) +{ + qint16 realValue = 0; + if (m_format.sampleSize() == 8) + { + const qint16 value = *reinterpret_cast<const quint8*>(ptr); + if (m_format.sampleType() == QAudioFormat::UnSignedInt) { + realValue = value - M_MAX_AMPLITUDE_8BIT_SIGNED - 1; + } else if (m_format.sampleType() == QAudioFormat::SignedInt) { + realValue = value; + } + } else if (m_format.sampleSize() == 16) { + qint16 value = 0; + if (m_format.byteOrder() == QAudioFormat::LittleEndian) + value = qFromLittleEndian<quint16>(ptr); + else + value = qFromBigEndian<quint16>(ptr); + + if (m_format.sampleType() == QAudioFormat::UnSignedInt) { + realValue = value - M_MAX_AMPLITUDE_16BIT_SIGNED; + } else if (m_format.sampleType() == QAudioFormat::SignedInt) { + realValue = value; + } + } + return realValue; +} + +/** + * Takes a number between 0 and 1, scales it with CutOffScaler, + * multiplies it with maximum density, and then gives it + * to the fft helper. + */ +void VoiceAnalyzer::setCutOffPercentage(qreal cutoff) +{ + cutoff = CutOffScaler*cutoff; + if (m_format.sampleSize() == 8) { + float t = cutoff*m_totalSampleCount*M_MAX_AMPLITUDE_8BIT_SIGNED; + m_fftHelper->setCutOffForDensity(t); + } + else if (m_format.sampleSize() == 16) { + float t = cutoff*m_totalSampleCount*M_MAX_AMPLITUDE_16BIT_SIGNED; + m_fftHelper->setCutOffForDensity(t); + } +} + +/** + * Returns the current target frequency. + */ +qreal VoiceAnalyzer::frequency() +{ + return m_frequency; +} + +/** + * Returns the maximum absolute value sent by + * the voiceDifference() signal. + */ +int VoiceAnalyzer::getMaximumVoiceDifference() +{ + return m_maximumVoiceDifference; +} + +/** + * Returns the maximum precision per note + * near the target frequency. + */ +int VoiceAnalyzer::getMaximumPrecisionPerNote() +{ + return PrecisionPerNote; +} + +/** + * Analyzes the voice frequency and emits appropriate signals. + */ +void VoiceAnalyzer::analyzeVoice() +{ + m_fftHelper->calculateFFT(m_samples); + int index = m_fftHelper->getMaximumDensityIndex(); + + // If index == -1 + if (index == -1) { + // The voice is to be filtered away. + // Emit the lowVoice signal and return. + emit lowVoice(); + qDebug() << "low voice"; + return; + } + // Else, continue + + // Let the correctIndex to be + // the nearest index corresponding to the correct frequency. + qreal stepSizeInFrequency = (qreal)m_format.sampleRate() + / (m_totalSampleCount * m_stepSize); + qreal newFrequency = qreal(index) * stepSizeInFrequency; + // Calculate the nearest index corresponding to the correct frequency. + int correctIndex = qRound(m_frequency / stepSizeInFrequency); + qreal value = 0; + + // If the obtained frequency is more than + // log_2(TargetFrequencyParameter) octaves less than the m_frequency: + + // Note: + // Instead of m_frequency/TargetFrequencyParameter > newFrequency, + // the comparison is done without a div instructions by + // m_frequency > newFrequency * TargetFrequencyParameter. + + if (m_frequency > newFrequency * TargetFrequencyParameter) { + // Set the difference value to be -m_maximumVoiceDifference. + qDebug() << "compare" << "low" << newFrequency << m_frequency - stepSizeInFrequency * correctIndex << (m_frequency - stepSizeInFrequency * correctIndex) / stepSizeInFrequency; + value = -m_maximumVoiceDifference; + } + // Else, if the obtained frequency is more than + // log_2(TargetFrequencyParameter) octaves more than the m_frequency: + else if (m_frequency*TargetFrequencyParameter < newFrequency) { + // Set the difference value to be m_maximumVoiceDifference. + qDebug() << "compare" << "high" << newFrequency << m_frequency - stepSizeInFrequency * correctIndex << (m_frequency - stepSizeInFrequency * correctIndex) / stepSizeInFrequency; + value = m_maximumVoiceDifference; + } + // Else: + else { + // Calculate the difference between the obtained and the correct + // frequency in tones. + // Use stepSizeInFrequency * correctIndex instead of + // m_frequency so that the value is zero when there is correct + // voice obtained. Set the difference value to be + // log(frequency / target frequency) * 12 / log(2). + value = log(newFrequency / (stepSizeInFrequency * correctIndex)) + * 12 / M_LN2; + qDebug() << "compare" << value << newFrequency << m_frequency - stepSizeInFrequency * correctIndex << (m_frequency - stepSizeInFrequency * correctIndex) / stepSizeInFrequency; + } + + // Emit voiceDifference signal. + QVariant valueVar(value); //Has to be QVariant for QML + emit voiceDifference(valueVar); + + // If the correctIndex is index, emit the correctFrequency signal. + if (correctIndex == index) { + emit(correctFrequency()); + } +} + +/** + * Empty implementation for readData, since no data is provided + * by the VoiceAnalyzer class. + */ +qint64 VoiceAnalyzer::readData(char *data, qint64 maxlen) +{ + Q_UNUSED(data); + Q_UNUSED(maxlen); + + return 0; +} diff --git a/demos/mobile/guitartuner/src/voiceanalyzer.h b/demos/mobile/guitartuner/src/voiceanalyzer.h new file mode 100644 index 0000000..147a0d6 --- /dev/null +++ b/demos/mobile/guitartuner/src/voiceanalyzer.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VOICEANALYZER_H +#define VOICEANALYZER_H + +#include <QObject> +#include <QAudioFormat> +#include <QDebug> +#include <QtCore/qmath.h> +#include <QtCore/qendian.h> +#include <QVariant> + +#include "constants.h" +#include "fastfouriertransformer.h" +#include "math.h" + +class VoiceAnalyzer : public QIODevice +{ + Q_OBJECT +public: + VoiceAnalyzer(const QAudioFormat &format, QObject *parent = 0); + qint64 readData(char *data, qint64 maxlen); + qint64 writeData(const char *data, qint64 maxlen); + void start(qreal frequency); + void stop(); + qreal frequency(); + int getMaximumVoiceDifference(); + int getMaximumPrecisionPerNote(); + +public slots: + void setCutOffPercentage(qreal cutoff); + +private: + const QAudioFormat m_format; + QList<qint16> m_samples; + int m_totalSampleCount; + int m_maximumVoiceDifference; + + qint16 getValueInt16(const uchar *ptr); + int m_stepSize; + qreal m_frequency; + qint64 m_position; + FastFourierTransformer *m_fftHelper; + void analyzeVoice(); +signals: + void voiceDifference(QVariant frequency); + void correctFrequency(); + void lowVoice(); + +public slots: + +}; + + +#endif // VOICEANALYZER_H diff --git a/demos/mobile/guitartuner/src/voicegenerator.cpp b/demos/mobile/guitartuner/src/voicegenerator.cpp new file mode 100644 index 0000000..ce25b6e --- /dev/null +++ b/demos/mobile/guitartuner/src/voicegenerator.cpp @@ -0,0 +1,246 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "voicegenerator.h" + +const int BufferSizeMilliseconds = 100; + +VoiceGenerator::VoiceGenerator(const QAudioFormat &format, + qreal frequency, qreal amplitude, + QObject *parent) : + QIODevice(parent), + m_format(format), + m_amplitude(0.5) +{ + Q_ASSERT(m_format.sampleSize() % 8 == 0); + int sampleBytes = m_format.channels() * (m_format.sampleSize() / 8); + // + 1 to round up, just to be sure that all samples fit. + qint64 samplesInBuffer = m_format.sampleRate() + * BufferSizeMilliseconds / 1000 + 1; + qint64 length = samplesInBuffer * sampleBytes; + m_buffer.resize(length); + m_max_position = 0; + m_position = 0; + m_amplitude = amplitude; + setFrequency(frequency); +} + +VoiceGenerator::~VoiceGenerator() +{ +} + +/** + * Opens the parent QIODevice. + */ +void VoiceGenerator::start() +{ + open(QIODevice::ReadOnly); +} + +/** + * Closes the parent QIODevice. Resets the m_position to zero. + */ +void VoiceGenerator::stop() +{ + close(); + m_position = 0; +} + +/** + * Sets the frequency to new frequency. + */ +void VoiceGenerator::setFrequency(qreal frequency) +{ + Q_ASSERT(1 / frequency < BufferSizeMilliseconds); + this->m_frequency = frequency; + refreshData(); +} + +/** + * Sets the amplitude for the voice. + */ +void VoiceGenerator::setAmplitude(qreal amplitude) +{ + Q_ASSERT(amplitude >= 0); + m_amplitude = amplitude; + refreshData(); +} + +/** + * Returns the current frequency. + */ +qreal VoiceGenerator::frequency() +{ + return m_frequency; +} + +/** + * Generates voice data corresponding a sine voice with target frequency. + * The number of data generated is calculated + * and stored to m_max_position. + */ +void VoiceGenerator::refreshData() +{ + const int channelBytes = m_format.sampleSize() / 8; + const int sampleSize = m_format.channels() * channelBytes; + const qint64 voiceOscillationsInBuffer = BufferSizeMilliseconds + * m_frequency / 1000; + const qint64 voiceSamplesInBuffer = voiceOscillationsInBuffer + * m_format.sampleRate() / m_frequency; + m_max_position = voiceSamplesInBuffer * sampleSize; + qint64 dataGenerationLength = m_buffer.size(); + + + Q_ASSERT(m_max_position % (sampleSize) == 0); + Q_ASSERT(dataGenerationLength <= m_buffer.size()); + + short *t = (short*)m_buffer.data(); + + +/* + int te ; + static float fpos = 0.0f; + //dataGenerationLength>>=1; // in words + for (int f=0; f<dataGenerationLength; f++) { + te = (short)((sinf(fpos))* (65536.0f/2.0f)); + fpos += m_frequency/2000.0f; + t[f]= te; + }; + + m_amplitude = 1.0f; */ + uchar *ptr = reinterpret_cast<uchar *>(m_buffer.data()); + int sampleIndex = 0; + while (dataGenerationLength > 0) { + qreal realValue = 0; + if (sampleIndex < voiceSamplesInBuffer) { + realValue = m_amplitude + *qSin(2.0f * M_PI * m_frequency + * qreal(sampleIndex % m_format.sampleRate()) + / m_format.sampleRate()); + } + for (int i=0; i<m_format.channels(); ++i) { + setValue(ptr, realValue); + ptr += channelBytes; + dataGenerationLength -= channelBytes; + } + ++sampleIndex; + } +} + +/** + * Stores the realValue into bytes pointed by ptr as an int value. + * Align-safe. + */ +void VoiceGenerator::setValue(uchar *ptr, qreal realValue) { + if (m_format.sampleSize() == 8) + { + quint8 value = 0; + if (m_format.sampleType() == QAudioFormat::UnSignedInt) { + value = static_cast<quint8>( + qRound((1.0 + realValue) / 2 + * M_MAX_AMPLITUDE_8BIT_UNSIGNED)); + } else if (m_format.sampleType() == QAudioFormat::SignedInt) { + value = static_cast<qint8>( + qRound(realValue + * M_MAX_AMPLITUDE_8BIT_SIGNED)); + } + *reinterpret_cast<quint8*>(ptr) = value; + } else if (m_format.sampleSize() == 16) { + quint16 value = 0; + if (m_format.sampleType() == QAudioFormat::UnSignedInt) { + value = static_cast<quint16>( + qRound((1.0 + realValue) / 2 + * M_MAX_AMPLITUDE_16BIT_UNSIGNED)); + } else if (m_format.sampleType() == QAudioFormat::SignedInt) { + value = static_cast<qint16>( + qRound(realValue + * M_MAX_AMPLITUDE_16BIT_SIGNED)); + } + if (m_format.byteOrder() == QAudioFormat::LittleEndian) + qToLittleEndian<qint16>(value, ptr); + else + qToBigEndian<qint16>(value, ptr); + } +} + +qint64 VoiceGenerator::bytesAvailable() const +{ + return m_max_position + QIODevice::bytesAvailable(); +} + +/** + * Called by the QIODevice. Puts maxlen amount of voice + * samples into the data array. + */ +qint64 VoiceGenerator::readData(char *data, qint64 maxlen) +{ + qint64 total = 0; + qint64 chunk = 0; + while (total < maxlen) { + if (maxlen - total >= m_max_position - m_position) { + // the needed buffer is longer than the currently + // available buffer from m_position to the m_max_position + chunk = m_max_position - m_position; + memcpy(data, m_buffer.constData() + m_position, chunk); + m_position = 0; + } + else { + // we can copy the needed data directly, and the loop will end + chunk = maxlen - total; + memcpy(data, m_buffer.constData() + m_position, chunk); + m_position = (m_position + chunk) % m_max_position; + } + data += chunk; + total += chunk; + } + return total; +} + +/** + * Empty implementation for writeData, since no data is provided + * for the VoiceGenerator class. + */ +qint64 VoiceGenerator::writeData(const char *data, qint64 maxlen) +{ + Q_UNUSED(data); + Q_UNUSED(maxlen); + + return 0; +} diff --git a/demos/mobile/guitartuner/src/voicegenerator.h b/demos/mobile/guitartuner/src/voicegenerator.h new file mode 100644 index 0000000..e4abd90 --- /dev/null +++ b/demos/mobile/guitartuner/src/voicegenerator.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VOICEGENERATOR_H +#define VOICEGENERATOR_H + +#include <QIODevice> +#include <QByteArray> +#include <QAudioFormat> +#include <QtCore/qmath.h> +#include <QtCore/qendian.h> +#include <QDebug> + +#include "constants.h" + + +class VoiceGenerator : public QIODevice +{ + Q_OBJECT +public: + VoiceGenerator(const QAudioFormat &format, qreal frequency, qreal amplitude, QObject *parent = 0); + ~VoiceGenerator(); + void setFrequency(qreal frequency); + qint64 readData(char *data, qint64 maxlen); + qint64 writeData(const char *data, qint64 maxlen); + qint64 bytesAvailable() const; + qreal frequency(); +signals: + +public slots: + void setAmplitude(qreal amplitude); + void start(); + void stop(); + +private: + void setValue(uchar *ptr, qreal realValue); + void refreshData(); + const QAudioFormat m_format; + // buffer to store the data + QByteArray m_buffer; + // current position in buffer + qint64 m_position; + // max position depends on the sample rate of format and the frequency of voice + qint64 m_max_position; + qreal m_amplitude; + qreal m_frequency; +}; + +#endif // VOICEGENERATOR_H diff --git a/demos/mobile/guitartuner/ui_guitartunerui.h b/demos/mobile/guitartuner/ui_guitartunerui.h new file mode 100644 index 0000000..3a698aa --- /dev/null +++ b/demos/mobile/guitartuner/ui_guitartunerui.h @@ -0,0 +1,181 @@ +/******************************************************************************** +** Form generated from reading UI file 'guitartunerui.ui' +** +** Created: Wed Mar 2 14:59:33 2011 +** by: Qt User Interface Compiler version 4.7.2 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_GUITARTUNERUI_H +#define UI_GUITARTUNERUI_H + +#include <QtCore/QVariant> +#include <QtGui/QAction> +#include <QtGui/QApplication> +#include <QtGui/QButtonGroup> +#include <QtGui/QFrame> +#include <QtGui/QHBoxLayout> +#include <QtGui/QHeaderView> +#include <QtGui/QLabel> +#include <QtGui/QPushButton> +#include <QtGui/QSlider> +#include <QtGui/QToolButton> +#include <QtGui/QVBoxLayout> +#include <QtGui/QWidget> + +QT_BEGIN_NAMESPACE + +class Ui_GuitarTunerUI +{ +public: + QVBoxLayout *verticalLayout_2; + QLabel *tabulatorIcon; + QSlider *correctSoundSlider; + QHBoxLayout *horizontalLayout; + QToolButton *buttonPrev; + QLabel *noteLabel; + QToolButton *buttonNext; + QPushButton *modeButton; + QFrame *line; + QHBoxLayout *horizontalLayout_2; + QSlider *soundSlider; + QToolButton *soundButton; + QLabel *micSensitivityLabel; + + void setupUi(QWidget *GuitarTunerUI) + { + if (GuitarTunerUI->objectName().isEmpty()) + GuitarTunerUI->setObjectName(QString::fromUtf8("GuitarTunerUI")); + GuitarTunerUI->resize(187, 279); + verticalLayout_2 = new QVBoxLayout(GuitarTunerUI); + verticalLayout_2->setSpacing(6); + verticalLayout_2->setContentsMargins(11, 11, 11, 11); + verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); + tabulatorIcon = new QLabel(GuitarTunerUI); + tabulatorIcon->setObjectName(QString::fromUtf8("tabulatorIcon")); + tabulatorIcon->setText(QString::fromUtf8("")); + tabulatorIcon->setPixmap(QPixmap(QString::fromUtf8(":/images/guitartab.svg"))); + tabulatorIcon->setAlignment(Qt::AlignCenter); + + verticalLayout_2->addWidget(tabulatorIcon); + + correctSoundSlider = new QSlider(GuitarTunerUI); + correctSoundSlider->setObjectName(QString::fromUtf8("correctSoundSlider")); + correctSoundSlider->setEnabled(false); + correctSoundSlider->setAutoFillBackground(false); + correctSoundSlider->setMinimum(-50); + correctSoundSlider->setMaximum(50); + correctSoundSlider->setOrientation(Qt::Horizontal); + correctSoundSlider->setTickPosition(QSlider::TicksAbove); + correctSoundSlider->setTickInterval(50); + + verticalLayout_2->addWidget(correctSoundSlider); + + horizontalLayout = new QHBoxLayout(); + horizontalLayout->setSpacing(6); + horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + buttonPrev = new QToolButton(GuitarTunerUI); + buttonPrev->setObjectName(QString::fromUtf8("buttonPrev")); + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(buttonPrev->sizePolicy().hasHeightForWidth()); + buttonPrev->setSizePolicy(sizePolicy); + buttonPrev->setArrowType(Qt::LeftArrow); + + horizontalLayout->addWidget(buttonPrev); + + noteLabel = new QLabel(GuitarTunerUI); + noteLabel->setObjectName(QString::fromUtf8("noteLabel")); + noteLabel->setAlignment(Qt::AlignCenter); + + horizontalLayout->addWidget(noteLabel); + + buttonNext = new QToolButton(GuitarTunerUI); + buttonNext->setObjectName(QString::fromUtf8("buttonNext")); + sizePolicy.setHeightForWidth(buttonNext->sizePolicy().hasHeightForWidth()); + buttonNext->setSizePolicy(sizePolicy); + buttonNext->setAutoRaise(false); + buttonNext->setArrowType(Qt::RightArrow); + + horizontalLayout->addWidget(buttonNext); + + + verticalLayout_2->addLayout(horizontalLayout); + + modeButton = new QPushButton(GuitarTunerUI); + modeButton->setObjectName(QString::fromUtf8("modeButton")); + + verticalLayout_2->addWidget(modeButton); + + line = new QFrame(GuitarTunerUI); + line->setObjectName(QString::fromUtf8("line")); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + + verticalLayout_2->addWidget(line); + + horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setSpacing(6); + horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); + soundSlider = new QSlider(GuitarTunerUI); + soundSlider->setObjectName(QString::fromUtf8("soundSlider")); + soundSlider->setValue(65); + soundSlider->setOrientation(Qt::Vertical); + + horizontalLayout_2->addWidget(soundSlider); + + soundButton = new QToolButton(GuitarTunerUI); + soundButton->setObjectName(QString::fromUtf8("soundButton")); + QIcon icon; + icon.addFile(QString::fromUtf8(":/images/note.svg"), QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(QString::fromUtf8(":/images/noteNo.svg"), QSize(), QIcon::Normal, QIcon::On); + icon.addFile(QString::fromUtf8(":/images/noteNo.svg"), QSize(), QIcon::Active, QIcon::On); + soundButton->setIcon(icon); + soundButton->setIconSize(QSize(30, 30)); + soundButton->setCheckable(true); + soundButton->setAutoRaise(true); + + horizontalLayout_2->addWidget(soundButton); + + micSensitivityLabel = new QLabel(GuitarTunerUI); + micSensitivityLabel->setObjectName(QString::fromUtf8("micSensitivityLabel")); + QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Preferred); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(micSensitivityLabel->sizePolicy().hasHeightForWidth()); + micSensitivityLabel->setSizePolicy(sizePolicy1); + + horizontalLayout_2->addWidget(micSensitivityLabel); + + + verticalLayout_2->addLayout(horizontalLayout_2); + + + retranslateUi(GuitarTunerUI); + + QMetaObject::connectSlotsByName(GuitarTunerUI); + } // setupUi + + void retranslateUi(QWidget *GuitarTunerUI) + { + GuitarTunerUI->setWindowTitle(QApplication::translate("GuitarTunerUI", "GuitarTunerUI", 0, QApplication::UnicodeUTF8)); + buttonPrev->setText(QApplication::translate("GuitarTunerUI", "...", 0, QApplication::UnicodeUTF8)); + noteLabel->setText(QApplication::translate("GuitarTunerUI", "A", 0, QApplication::UnicodeUTF8)); + buttonNext->setText(QApplication::translate("GuitarTunerUI", "...", 0, QApplication::UnicodeUTF8)); + modeButton->setText(QApplication::translate("GuitarTunerUI", "Change mode", 0, QApplication::UnicodeUTF8)); + soundButton->setText(QApplication::translate("GuitarTunerUI", "...", 0, QApplication::UnicodeUTF8)); + micSensitivityLabel->setText(QApplication::translate("GuitarTunerUI", "microphone\n" +"sensitivity", 0, QApplication::UnicodeUTF8)); + } // retranslateUi + +}; + +namespace Ui { + class GuitarTunerUI: public Ui_GuitarTunerUI {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_GUITARTUNERUI_H |