Symbian C++ and QtCreator



  • Hello,

    I am trying to develop an application that involves TextToSpeech (TTS) for Nokia N8. As Qt does not have a TTS API built-in, I had to search for one over the Internet. Turns out that I found a very good API, but it did not offer support for Symbian at all (QtSpeech - http://lynxline.com/projects/qtspeech/).

    In my quest to find an API for TextToSpeech I found one developed by Artem Marchenko. It seems to be just what I need for my application but I cannot find a way to include the necessary headers, they doesn't seem to be found by QtCreator. I searched for the headers inside QtSDK directories and found them, but the IDE keeps telling me they are not there.

    I would like to know if anyone has a similar problem or if it's a compatibility issue. I have been stuck with this problem for 2 days now and can't find a solution.

    I will paste the code here for reference:

    "TtsPlayer.h"

    @/*

    • ============================================================================
    • Name : TtsPlayer.h
    • Part of : TextToSpeech example
    • Created : 05.07.2006 by Artem Marchenko
    • Description: Text-to-speech player wrapper
    • Version : 1.0
    • Copyright: Artem Marchenko 2006, http://symbianexample.com
    • ============================================================================
      */

    #ifndef TTSPLAYER_H
    #define TTSPLAYER_H

    // Include Files
    #include <MdaAudioSamplePlayer.h>
    #include <e32base.h>

    class CTtsPlayer : public CBase, public MMdaAudioPlayerCallback
    {
    public:
    // construction
    static CTtsPlayer* NewLC();
    ~CTtsPlayer();
    /** Simplified call'n'forget interface.

    • Synchronous function
    • @leave System-wide error codes. @see MMdaAudioPlayerCallback errors
      /
      void PlayTextL( TDesC& aText );
      // From the observer interface
      public:
      virtual void MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds &aDuration);
      virtual void MapcPlayComplete(TInt aError);
      private:
      void ConstructL();
      private:
      CMdaAudioPlayerUtility
      iPlayer;
      TBool iPlaybackInProgress;
      CActiveSchedulerWait* iWaiter;
      // Playback error code
      TInt iErr;
      };

    #endif // TTSPLAYER_H

    // End of file
    @

    "TtsPlayer.cpp"

    @
    /*

    • ============================================================================
    • Name : TtsPlayer.cpp
    • Part of : TextToSpeech example
    • Created : 05.07.2006 by Artem Marchenko
    • Description:
    • TtsPlayer.cpp - source file
      
    • Version : 1.0
    • Copyright: Artem Marchenko 2006, http://symbianexample.com
    • ============================================================================
      */

    // Include Files

    #include <e32base.h>
    #include <e32std.h>
    #include <e32def.h>
    #include "TtsPlayer.h"

    // Prefix telling the audio utility that TTS should be used
    _LIT( KTtsPrefix, "(tts)" );

    CTtsPlayer* CTtsPlayer::NewLC()
    {
    CTtsPlayer* self = new (ELeave) CTtsPlayer;
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }

    CTtsPlayer::~CTtsPlayer()
    {
    delete iWaiter;
    delete iPlayer;
    }

    void CTtsPlayer::ConstructL()
    {
    iPlayer = CMdaAudioPlayerUtility::NewL( *this );
    iWaiter = new (ELeave) CActiveSchedulerWait;
    }

    void CTtsPlayer::PlayTextL( TDesC& aText )
    {
    __ASSERT_ALWAYS( iPlaybackInProgress == EFalse, User::Leave( KErrNotReady ) );
    HBufC8* playableText = HBufC8::NewLC( aText.Length() + KTtsPrefix().Length() );
    playableText->Des().Append( KTtsPrefix );
    playableText->Des().Append( aText );
    iPlayer->OpenDesL( *playableText );
    iPlaybackInProgress = ETrue;
    iWaiter->Start();
    // At this point playback is already completed or failed
    User::LeaveIfError( iErr );
    CleanupStack::PopAndDestroy( playableText );
    }

    void CTtsPlayer::MapcInitComplete( TInt aError, const TTimeIntervalMicroSeconds& /aDuration/ )
    {
    iErr = aError;
    if( aError != KErrNone )
    {
    iPlaybackInProgress = EFalse;
    // Let the paused PlayTextL complete
    iWaiter->AsyncStop();
    }
    else
    {
    iPlayer->Play();
    }
    }

    void CTtsPlayer::MapcPlayComplete( TInt aError )
    {
    iErr = aError;
    iPlaybackInProgress = EFalse;
    // Let the paused PlayTextL complete
    iWaiter->AsyncStop();
    }
    // End of file
    @



  • As for pure Symbian C++ programming, you'd better use IDE Carbide rather than creator: http://www.developer.nokia.com/Resources/Tools_and_downloads/Other/Carbide.c++/



  • Is it possible to use QML and other Qt features in this IDE?



  • yes you can integrate your qt in carbide. And can make Qt application with carbide.c++ .And in case of Qt you have to use Qt mobiliy


  • Moderators

    I do not see any need to switch to carbide just because you use C++ code. C++ works great in Creator: Qt is C++ after all.

    What is does your .pro file look like? That is what is used to create the complete build stuff, so that is most likely misconfigured.



  • [quote author="Tobias Hunger" date="1310452221"]I do not see any need to switch to carbide just because you use C++ code. C++ works great in Creator: Qt is C++ after all.

    What is does your .pro file look like? That is what is used to create the complete build stuff, so that is most likely misconfigured.[/quote]

    my pro file:

    @

    Add files and directories to ship with the application

    by adapting the examples below.

    file1.source = myfile

    dir1.source = mydir

    DEPLOYMENTFOLDERS = # file1 dir1

    symbian:TARGET.UID3 = 0xEA017DD0

    Smart Installer package's UID

    This UID is from the protected range

    and therefore the package will fail to install if self-signed

    By default qmake uses the unprotected range value if unprotected UID is defined for the application

    and 0x2002CCCF value if protected UID is given to the application

    #symbian:DEPLOYMENT.installer_header = 0x2002CCCF

    Allow network access on Symbian

    symbian:TARGET.CAPABILITY += NetworkServices

    If your application uses the Qt Mobility libraries, uncomment

    the following lines and add the respective components to the

    MOBILITY variable.

    CONFIG += mobility

    MOBILITY +=

    SOURCES += main.cpp mainwindow.cpp
    TtsPlayer.cpp
    HEADERS += mainwindow.h
    TtsPlayer.h
    FORMS += mainwindow.ui

    Please do not modify the following two lines. Required for deployment.

    include(deployment.pri)
    qtcAddDeployment()
    @
    my pri file:
    @

    checksum 0x9840 version 0x40002

    This file was generated by an application wizard of Qt Creator.

    The code below handles deployment to Symbian and Maemo, aswell as copying

    of the application data to shadow build directories on desktop.

    It is recommended not to modify this file, since newer versions of Qt Creator

    may offer an updated version of it.

    defineTest(qtcAddDeployment) {
    for(deploymentfolder, DEPLOYMENTFOLDERS) {
    item = item$${deploymentfolder}
    itemsources = $${item}.sources
    $$itemsources = $$eval($${deploymentfolder}.source)
    itempath = $${item}.path
    $$itempath= $$eval($${deploymentfolder}.target)
    export($$itemsources)
    export($$itempath)
    DEPLOYMENT += $$item
    }

    MAINPROFILEPWD = $$PWD

    symbian {
    isEmpty(ICON):exists($${TARGET}.svg):ICON = $${TARGET}.svg
    isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x20000 0x2000000
    } else:win32 {
    copyCommand =
    for(deploymentfolder, DEPLOYMENTFOLDERS) {
    source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
    source = $$replace(source, /, \)
    sourcePathSegments = $$split(source, \)
    target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments)
    target = $$replace(target, /, \)
    !isEqual(source,$$target) {
    !isEmpty(copyCommand):copyCommand += &&
    isEqual(QMAKE_DIR_SEP, \) {
    copyCommand += $(COPY_DIR) "$$source" "$$target"
    } else {
    source = $$replace(source, \\, /)
    target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
    target = $$replace(target, \\, /)
    copyCommand += test -d "$$target" || mkdir -p "$$target" && cp -r "$$source" "$$target"
    }
    }
    }
    !isEmpty(copyCommand) {
    copyCommand = @echo Copying application data... && $$copyCommand
    copydeploymentfolders.commands = $$copyCommand
    first.depends = $(first) copydeploymentfolders
    export(first.depends)
    export(copydeploymentfolders.commands)
    QMAKE_EXTRA_TARGETS += first copydeploymentfolders
    }
    } else:unix {
    maemo5 {
    desktopfile.path = /usr/share/applications/hildon
    } else {
    desktopfile.path = /usr/share/applications
    copyCommand =
    for(deploymentfolder, DEPLOYMENTFOLDERS) {
    source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
    source = $$replace(source, \\, /)
    macx {
    target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
    } else {
    target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
    }
    target = $$replace(target, \\, /)
    sourcePathSegments = $$split(source, /)
    targetFullPath = $$target/$$last(sourcePathSegments)
    !isEqual(source,$$targetFullPath) {
    !isEmpty(copyCommand):copyCommand += &&
    copyCommand += $(MKDIR) "$$target"
    copyCommand += && $(COPY_DIR) "$$source" "$$target"
    }
    }
    !isEmpty(copyCommand) {
    copyCommand = @echo Copying application data... && $$copyCommand
    copydeploymentfolders.commands = $$copyCommand
    first.depends = $(first) copydeploymentfolders
    export(first.depends)
    export(copydeploymentfolders.commands)
    QMAKE_EXTRA_TARGETS += first copydeploymentfolders
    }
    }
    installPrefix = /opt/$${TARGET}
    for(deploymentfolder, DEPLOYMENTFOLDERS) {
    item = item$${deploymentfolder}
    itemfiles = $${item}.files
    $$itemfiles = $$eval($${deploymentfolder}.source)
    itempath = $${item}.path
    $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
    export($$itemfiles)
    export($$itempath)
    INSTALLS += $$item
    }
    icon.files = $${TARGET}.png
    icon.path = /usr/share/icons/hicolor/64x64/apps
    desktopfile.files = $${TARGET}.desktop
    target.path = $${installPrefix}/bin
    export(icon.files)
    export(icon.path)
    export(desktopfile.files)
    export(desktopfile.path)
    export(target.path)
    INSTALLS += desktopfile icon target
    }

    export (ICON)
    export (INSTALLS)
    export (DEPLOYMENT)
    export (TARGET.EPOCHEAPSIZE)
    export (TARGET.CAPABILITY)
    export (LIBS)
    export (QMAKE_EXTRA_TARGETS)
    }
    @

    includes I am not able to do:

    @
    #include <MdaAudioSamplePlayer.h>
    #include <e32base.h>
    #include <e32std.h>
    #include <e32def.h>
    @



  • I forgot to uncomment the line:
    @
    #CONFIG += mobility
    @

    Uncommented it and still no luck. I can include the mobility APIs now but the headers I need are not there.

    I found the headers under:

    @
    \QtSDK\Symbian\SDKs\Symbian3Qt473\epoc32
    @

    but I don't know how to add this path to my project.



  • I managed to include the headers in the project by adding their path to the INCLUDEPATH in the .pro file. As expected, this generated a lot of build errors as QtCreator could not resolve the definitions inside the headers.

    Has anyone been able to use SymbianC++ successfully? How do I include the necessary files to the project?



  • I apparently solved the library problems I was facing when setting as target the symbian device, and not the simulator. But now I got a new error message:

    :-1: error: Recipe linkandpostlink failed with exit code 1.

    @
    :-1: Running command: C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/tools/checklib.exe stdc++ --elf C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/urel/qtmain.lib
    Running command: C:/QtSDK/Symbian/tools/gcce4/bin/arm-none-symbianelf-g++.exe -Wl,-Ttext,0x8000 -Wl,--no-undefined -nodefaultlibs -Wl,--strip-debug -Wl,-shared -Wl,-Tdata,0x400000 -Wl,--default-symver '-Wl,-soname=TTS{000a0000}[ea017dd0].exe' -Wl,--entry=_E32Startup -Wl,-u,_E32Startup,C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/urel/eexe.lib -o C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/urel/TTS.exe.sym -Wl,-Map=C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/urel/TTS.exe.map @C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/build/tts/c_4f6c8efd5954da7e/TTS_exe/armv5/urel/TTS_urel_objects.via --start-group C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/urel/usrt3_1.lib --end-group C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/urel/usrt3_1.lib C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/urel/qtmain.lib C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/lib/libstdcppv5.dso C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/lib/QtGui.dso C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/lib/QtCore.dso C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/lib/libpthread.dso C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/lib/libc.dso C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/lib/libm.dso C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/lib/euser.dso C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/lib/libdl.dso C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/lib/stdnew.dso C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/lib/drtaeabi.dso C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/lib/dfpaeabi.dso -lsupc++ -lgcc
    c:/qtsdk/symbian/tools/gcce4/bin/../lib/gcc/arm-none-symbianelf/4.4.1/../../../../arm-none-symbianelf/bin/ld.exe: warning: C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/release/armv5/urel/usrt3_1.lib(ucppinit.o) uses variable-size enums yet the output is to use 32-bit enums; use of enum values across objects may fail
    C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/build/tts/c_4f6c8efd5954da7e/TTS_exe/armv5/urel/TtsPlayer.o: In function CTtsPlayer::PlayTextL(TDesC16&)': C:/Users/Fabio/Desktop/GRID/TCC/TTS/TtsPlayer.cpp:50: undefined reference toCMdaAudioPlayerUtility::OpenDesL(TDesC8 const&)'
    C:/QtSDK/Symbian/SDKs/Symbian3Qt473/epoc32/build/tts/c_4f6c8efd5954da7e/TTS_exe/armv5/urel/TtsPlayer.o: In function CTtsPlayer::ConstructL()': C:/Users/Fabio/Desktop/GRID/TCC/TTS/TtsPlayer.cpp:40: undefined reference toCMdaAudioPlayerUtility::NewL(MMdaAudioPlayerCallback&, int, int)'
    collect2: ld returned 1 exit status
    @

    :-1: error: The make-engine exited with errors.

    It seems that I am on the right way to build this project but I am stuck at this error right now.



  • Make sure you are building the target for device target and not emulator binaries.



  • [quote author="qtrahul" date="1310751396"]Make sure you are building the target for device target and not emulator binaries.[/quote]

    Thanks for the reply! I am building for device target (my mistake not doing this from the start, but I am a newbie xD). That solved all the include problems I had but now I face the linkandpostlink error (described above).

    Could anyone try to build the code I presented at the beginning of the topic for an N8?



  • Is this useful? http://www.developer.nokia.com/Community/Wiki/Building_Symbian_C++_Projects_Using_Qt_SDK

    Once you can build the Symbian project then you can build the Qt wrapper.



  • Hi Fabio,

    Were you able to achieve the output?
    Did the procedure which you followed above worked? or Did you go for any other work around?



  • Fixed it.....

    It seems that the libraries are not picked up when i include the following to my app.pri file.

    -lmediaclientaudio -lremconinterfacebase -lremconcoreapi

    Now i moved this to my app.pro file and it worked.
    @LIBS += -lcone -leikcore -lavkon -lmediaclientaudio -lremconinterfacebase -lremconcoreapi@

    However, I don't know how to change the voice pitch/language and add different voice support.

    Can anyone suggest me how to proceed.

    Thanks


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.