TimeLineAnnotator / desktop

A GUI for graphical analysis and annotation of video and audio files.
https://tilia-app.com
Creative Commons Attribution Share Alike 4.0 International
8 stars 2 forks source link

Additional Player Features #123

Closed azfoo closed 9 hours ago

azfoo commented 1 month ago

Playback speed change, Looping and Volume control

FelipeDefensor commented 1 month ago

+1 for the volume control and for the playback rate change. It would be great if we had a way to change the rate independently of pitch, but my research tells me that we would need a specialized audio processing library for that, and also a way to buffer and load audios with different rates. Something to work on in the near future, I would say.

FelipeDefensor commented 1 month ago

What I had in my mind when I suggested "looping" was being able to loop the span inside a hierarchy. That way, users could hear a small passage repeatedely, which is very useful for practicing or transcribing.

Although what you implemented seems correct, it doesn't seem very useful to me. Are there any use cases I'm not considering?

azfoo commented 1 month ago

my research tells me that we would need a specialized audio processing library for that, and also a way to buffer and load audios with different rates.

Apparently it might be system dependent. Windows seem to have 2 methods for audio processing, one causes pitch change and the other doesn't. But that's not a very useful solution.

azfoo commented 1 month ago

What I had in my mind when I suggested "looping" was being able to loop the span inside a hierarchy. That way, users could hear a small passage repeatedely, which is very useful for practicing or transcribing.

That makes more sense. Will look into it.

Although what you implemented seems correct, it doesn't seem very useful to me. Are there any use cases I'm not considering?

I suppose if you played things back faster and on loop, it could be used to check your work. But if we implemented it the way you prefer, this use case would be covered too.

What should the process of looping be like? Does it loop the last selected hierarchy or does the user have to specify one before looping? The second seems like the more obvious answer but what do you think?

FelipeDefensor commented 1 month ago

What I had in my mind when I suggested "looping" was being able to loop the span inside a hierarchy. That way, users could hear a small passage repeatedely, which is very useful for practicing or transcribing.

That makes more sense. Will look into it.

Although what you implemented seems correct, it doesn't seem very useful to me. Are there any use cases I'm not considering?

I suppose if you played things back faster and on loop, it could be used to check your work. But if we implemented it the way you prefer, this use case would be covered too.

What should the process of looping be like? Does it loop the last selected hierarchy or does the user have to specify one before looping? The second seems like the more obvious answer but what do you think?

Can we choose which method gets used on Windows? That would solve it for a large part of users until we come with the permanent solution.

FelipeDefensor commented 1 month ago

What I had in my mind when I suggested "looping" was being able to loop the span inside a hierarchy. That way, users could hear a small passage repeatedely, which is very useful for practicing or transcribing.

I suppose if you played things back faster and on loop, it could be used to check your work. But if we implemented it the way you prefer, this use case would be covered too.

Would it? Because on most cases there won't be a hierarchy that spans the whole track.

What should the process of looping be like? Does it loop the last selected hierarchy or does the user have to specify one before looping? The second seems like the more obvious answer but what do you think?

Well, I agree that specifying is the way to go, but I'm not sure how the UI for that would be. Perhaps we could highlight the area that is currently being looped with a different color and prevent seeking the playback head outside it?

FelipeDefensor commented 1 month ago

The specifying itself could be done via context menu or toolbar button, perhaps. Also, we need some UI element to disable the loop.

azfoo commented 1 month ago

I've updated the way it loops. Could you take another look before I work on the UI side of this?

FelipeDefensor commented 4 weeks ago

Ok, it loops the hierarchy that was selected when pressing loop, right? Seems to work for me. There's a lot to keep in mind here, some of which you probably already figured out.

Several things can happen to the hierarchy while looping is active:

The user might also select another hierarchy while looping. How do we handle that?

azfoo commented 4 weeks ago

At the moment, there are two things that cancel a loop: pressing the activated loop button and seeking outside of the looped area.

I'm thinking the following: Issue Solution
The start and end points of the selected hierarchy may change move the start and end points of the loop accordingly
The hierarchy may be deleted if the hierarchy selected is at either end of the looped area, shorten the looped area; if it is in the middle, cancel the looping [because it is possible to loop between two disjunct sections].
The hierarhcy may be split cancel looping - we don't know which one the user wants. or perhaps do nothing and continue looping.
The hierarhcy may be merged with another one extend looped area if merged area is beyond the current area.
The user might also select another hierarchy while looping. How do we handle that? currently, if it is playing, it does nothing. But if it is not, clicking causes the player to seek, so the loop is cancelled. It doesn't automatically add the newly selected hierarchy to the loop. The old loop is technically remembered, but the user has to select to loop again.

Regarding the second point, a different way of doing it is by allowing the user to jump between two disjunct portions. It would probably be an interesting effect, but I don't know how useful that would be. That being said, I wonder if the selection process throughout the app should be different if the user holds down Shift or Control as it usually is in other applications...

What do you think?

azfoo commented 4 weeks ago

(ooops that wasn't the right button...)

FelipeDefensor commented 4 weeks ago

Commenting and expanding on what you proposed:

Issue Solution
The start and end points of the selected hierarchy may change Agreed.
The hierarchy may be deleted Agreed.
The hierarhcy may be split I'm in favor of doing nothing. The user can select one of the splits and reloop if desired.
The hierarhcy may be merged with another one Agreed.
The user might also select another hierarchy while looping. How do we handle that? Note that a double click triggers a seek even during playback. I agree that seeking outside the loop (by any means, btw) should cancel it.
Resize hierarchy by dragging its handles Resize loop accordingly without interrupting playback.
Undo or redo any of the actions above with Ctrl+Z or Ctrl+Y This one is trickier. Ideally we would remember the loop state and set/reset it as needed, but that might be tricky.

I think disjunct looping can wait unless we can think of a use case, as that will probably make the rest easier. I think we should allow Ctrl and Shift selections to be looped only if the are not disjunct.

I'm thinking that an obvious next step from all this would be optionally decoupling the looping from hierarchies, allowing the user to also select an audio span to be looped by clicking and dragging on a "blank" timeline area. The selected looping area could then be resized by, let's say, some handles, as usually happens in DAWs. That could be integrated with the hierarchy looping by optionally snapping the looped boundaries to hierarchy boundaries. Is that clear? Implementing this method increases the scope by quite a bit, so we can skip it for now, but perhaps it would be more efficient to do both at the same time.

azfoo commented 4 weeks ago

Regarding undo/redoing:

I think disjunct looping can wait unless we can think of a use case, as that will probably make the rest easier. I think we should allow Ctrl and Shift selections to be looped only if they are not disjunct.

I'm thinking that an obvious next step from all this would be optionally decoupling the looping from hierarchies, allowing the user to also select an audio span to be looped by clicking and dragging on a "blank" timeline area.

FelipeDefensor commented 4 weeks ago

I don't think that should affect the looping because doing seems to imply that something about the timeline has changed - the loop isn't something saved in the file after work is done, so nothing about the file itself can be undone/redone. Being able to undo a loop makes the app more similar to a DAW than notation software.

I agree that creating a loop shouldn't be considered an "action" that can be undone, neither should it be saved to the file. I was referring to the case where some modification to the hierarchy that is being looped is undone/redone (e.g. dragging one of its end, merging it with another).

f we did decide to not allow disjunct sections, should an error be raised if they are disjunct? Or should it loop on an arbitrary section? Alternatively, we could leave it as it is, where the selected disjunct sections are looped with the middle bit included. I could do something to show that the entire section is being looped.

Wrt the first option, I think the error is the better option. Looping an arbitrary section would be surpirsing to the user. I'm also fine with the second option.

Realistically, I'm happy to expand the allowed timelines that can start a loop since all elements have some kind of timestamp on them - that would mean that we wouldn't need to create a new timeline. (This would be quite easy to do I think.) That being said, there is no reason why someone couldn't add a hierarchy timeline called "loop", just to loop selected bits of audio.

I wasn't thinking about a dedicated timeline type, but about something that would be available "on top of" existing timelines. Adding a hierarchy timeline specifically for looping achieves the same result with not a lot of extra work, indeed, so I think we can skip this complex implementation, for now.