Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Play small Audio files without gaps
Qt 6.12 LTS is out! See what's new in the release blog

Play small Audio files without gaps

Scheduled Pinned Locked Moved Solved QML and Qt Quick
12 Posts 3 Posters 4.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • YunusY Offline
    YunusY Offline
    Yunus
    wrote on last edited by
    #2

    @SeDi I tried it myself but I didnt notice any gaps between audiofiles. As soon as one of them finishes, it is passing to the other.
    If there are some gaps, it should be about miliseconds. Do u want that time to be exactly 0 sec?

    1 Reply Last reply
    0
    • SeDiS Offline
      SeDiS Offline
      SeDi
      wrote on last edited by SeDi
      #3

      @Yunus Thank you for your answer, yes, "exactly 0 s" ist crucial for my purpose. I try to implement a demonstration for Mozarts "Musikalisches Würfelspiel" (as described here) where a dice decides which of one of six possible next bars is played. So the bars have to be played seamlessly, like with no gap at all. When you use two "normal" tunes, you probably won't notice any gap between fadeout and intro.

      I could make it a bit better with a chain of SoundEffects:

      SoundEffect {
                 id: bar1
                 source: "qrc:/snds/r1c1.wav";
                 onPlayingChanged: {
                     if (!playing) {
                         bar2.play()
                     }
                 }
      
             }
      

      But it's still very audible. Any way to produce a seamless audio stream?

      1 Reply Last reply
      0
      • SeDiS Offline
        SeDiS Offline
        SeDi
        wrote on last edited by
        #4

        I have improved the situation a bit (not much) by using a chain of "SoundEffect" items as low latency option. Still, it was not really usable.

        Fortunately, my samples all have the exact same length, so I could find a hack that gets me set for the moment, I am calling the samples with a Timer and I use an interval that is very slightly (but not too disturbingly) shorter than the actual sample duration.

               Button {
                    text: ("Play")
                    onClicked: {
                        timer.bar = 1
                        timer.start()
                        bar1.play()
                    }
                }
        
                SoundEffect { id: bar1 }
                SoundEffect { id: bar2 }
                SoundEffect { id: bar3 }
                SoundEffect { id: bar4 }
                SoundEffect { id: bar5 }
                SoundEffect { id: bar6 }
                SoundEffect { id: bar7 }
                SoundEffect { id: bar8 }
        
                SoundEffect { id: singlePlayBar }
        
                Timer {
                    id: timer
                    property int bar: 1
                    interval: 1475 // instead of 1500
                    onTriggered: {
                        bar++
                        switch (bar) {
                        case 1: bar1.play(); timer.restart(); break
                        case 2: bar2.play(); timer.restart(); break
                        case 3: bar3.play(); timer.restart(); break
                        case 4: bar4.play(); timer.restart(); break
                        case 5: bar5.play(); timer.restart(); break
                        case 6: bar6.play(); timer.restart(); break
                        case 7: bar7.play(); timer.restart(); break
                        case 8: bar8.play(); timer.restart(); break
                        }
                    }
                }
        

        Now you can actually get the idea from the audio, but there are still some crackling sounds from time to time.

        Any ideas on how to concatenate wav-files into a seamless audio stream would be gratefully appreciated!

        1 Reply Last reply
        0
        • fcarneyF Offline
          fcarneyF Offline
          fcarney
          wrote on last edited by
          #5

          Do your samples have gaps/silence at the beginning or end of the file?

          C++ is a perfectly valid school of magic.

          1 Reply Last reply
          0
          • SeDiS Offline
            SeDiS Offline
            SeDi
            wrote on last edited by
            #6

            Perfectly valid question. Absolutely not. Extracted regions, directly from Soundforge. Triple checked this and rebuilt them anyway - to no avail...

            fcarneyF 1 Reply Last reply
            0
            • SeDiS SeDi

              Perfectly valid question. Absolutely not. Extracted regions, directly from Soundforge. Triple checked this and rebuilt them anyway - to no avail...

              fcarneyF Offline
              fcarneyF Offline
              fcarney
              wrote on last edited by
              #7

              @SeDi said in Play small Audio files without gaps:

              to no avail...

              Dang, I was hoping it was simple.
              One thing you could do is use 2 Audio objects and have one play and have the other track progress of the played sound. Then start playing the next one in the other Audio object when it gets to a certain percentage of being done. Maybe even mess with volume and do a fade in fade out if that makes sense at all. I looked at Audio and it has the ms progress and total ms and volume control. So it may be doable. Otherwise I think you might need to build a custom C++ object.

              C++ is a perfectly valid school of magic.

              1 Reply Last reply
              1
              • SeDiS Offline
                SeDiS Offline
                SeDi
                wrote on last edited by
                #8

                As I am dealing with a sequence of 8 bars of music, I am currently using 8 separate "SoundEffect" items that I trigger with a timer, because the gap was way too long (rythmically relevant) when triggering the respective next one with "onPlayingChanged".

                The idea to use the duration and position (with a sufficiently small notifyInterval) is cool. I could actually take longer samples and let them crossfade into another. Tricky, but probably quite doable. I'll have to look into that. Thank you for that idea, @fcarney !

                With "build a custom C++ object" you probably have something specific in mind, do you? I'd happily use C++ parts here, if that would be more suitable.

                1 Reply Last reply
                0
                • fcarneyF Offline
                  fcarneyF Offline
                  fcarney
                  wrote on last edited by
                  #9

                  @SeDi said in Play small Audio files without gaps:

                  you probably have something specific in mind, do you?

                  Not really, I was just suggesting you might need to use C++ audio objects.

                  C++ is a perfectly valid school of magic.

                  1 Reply Last reply
                  0
                  • fcarneyF Offline
                    fcarneyF Offline
                    fcarney
                    wrote on last edited by fcarney
                    #10

                    @SeDi
                    Okay, I take that back. Are you looking for sound synthesis? I have played around with a library I modified to use with Qt. It can play samples I "think" but it also does sound synthesis. It is called Gamma. You can modify the threading to use QThread very easily.

                    Fixed lib name.

                    C++ is a perfectly valid school of magic.

                    1 Reply Last reply
                    1
                    • SeDiS Offline
                      SeDiS Offline
                      SeDi
                      wrote on last edited by SeDi
                      #11

                      Thanks, I'll definitely have a look into that. Synthesis is currently not my aim, but as a music teacher I am definitely interested in general. But, perhaps, SuperCollider could be a better language for that.

                      I've built a small item that automatically fades itself in and out. It has further reduced the crackling while having no huge impact on attack, even before using longer samples with it. Not gone yet, but better.

                      import QtQuick 2.13
                      import QtMultimedia 5.13
                      
                      Item {
                          id: fadeSoundEffectItem
                          property int fadeDuration: 40
                          Audio {
                              id: playSound
                              notifyInterval: 5
                              onPositionChanged: {
                                  if ((duration - position) <= fadeDuration && !fadeOutAnimation.running)  {
                                      fadeOutAnimation.duration = duration - playSound.position
                                      fadeOutAnimation.start()
                                  }
                      
                              }
                      
                          }
                          property alias source: playSound.source
                          property real volume: 1
                      
                          PropertyAnimation {
                              id: fadeInAnimation
                              target: playSound
                              property: "volume"
                              to: fadeSoundEffectItem.volume
                              duration: fadeDuration
                              easing.type: Easing.Linear
                          }
                          PropertyAnimation {
                              id: fadeOutAnimation
                              target: playSound
                              property: "volume"
                              to: 0
                              duration: duration - playSound.position
                              easing.type: Easing.Linear
                          }
                          function fadeInAndPlay () {
                              playSound.volume = 0;
                              playSound.play()
                              fadeInAnimation.start()
                          }
                          function play() { fadeInAndPlay() }
                      }
                      

                      Edit: fixed code

                      1 Reply Last reply
                      0
                      • SeDiS Offline
                        SeDiS Offline
                        SeDi
                        wrote on last edited by
                        #12

                        I'll set this to solved, because I will not explore this further. Probably, a buffered audio stream (perhaps with QAudioOutput) would yield the cleanest result but as the result from fading is sufficient for my needs, I'll leave it there for now.

                        Thanks for helping me!

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt
                        • Unsolved