Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype of providing feedback using sounds #1100

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions installer/mac/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ cp ../../../../build/reaper_osara.dylib .
cp ../../../../config/mac/reaper-kb.ini OSARA.ReaperKeyMap
mkdir locale
cp ../../../../locale/*.po locale/
mkdir sounds
cp ../../../../sounds/*.mp3 sounds/
cd ../..
rm -f $dmg
# We seem to need a delay here to avoid an "hdiutil: create failed - Resource busy" error.
Expand Down
2 changes: 2 additions & 0 deletions installer/mac/content/Install OSARA.command
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ function run(argv) {
s(`cp '${source}/OSARA.ReaperKeyMap' '${target}/KeyMaps/'`);
s(`mkdir -p '${target}/osara/locale'`);
s(`cp '${source}/locale/'* '${target}/osara/locale/'`);
s(`mkdir -p '${target}/osara/sounds'`);
s(`cp '${source}/sounds/'* '${target}/osara/sounds/'`);
var res = app.displayDialog(
"Do you want to replace the existing keymap with the Osara keymap?", {
buttons: ["Yes", "No"],
Expand Down
3 changes: 3 additions & 0 deletions installer/osara.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ Section "OSARA plug-in" SecPlugin
CreateDirectory "$INSTDIR\osara\locale"
SetOutPath "$INSTDIR\osara\locale"
File "..\locale\*.po"
CreateDirectory "$INSTDIR\osara\sounds"
SetOutPath "$INSTDIR\osara\sounds"
File "..\sounds\*.mp3"
${Unless} $portable = ${BST_CHECKED}
WriteUninstaller "$INSTDIR\osara\uninstall.exe"
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\OSARA" "DisplayName" "OSARA"
Expand Down
Binary file added sounds/item.mp3
Binary file not shown.
Binary file added sounds/marker.mp3
Binary file not shown.
1 change: 1 addition & 0 deletions src/archBuild_sconscript
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ sources = [
"midiEditorCommands.cpp",
"envelopeCommands.cpp",
"controlSurface.cpp",
"coreUtils.cpp",
"exports.cpp",
"fxChain.cpp",
"translation.cpp",
Expand Down
116 changes: 116 additions & 0 deletions src/coreUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* OSARA: Open Source Accessibility for the REAPER Application
* Core utilities code
* Copyright 2024 James Teh
* License: GNU General Public License version 2.0
*/

#include "coreUtils.h"

#include <string>

#include "osara.h"
#include "config.h"

using namespace std;

namespace {
preview_register_t soundPreviewReg = {0};
double lastSoundCursorPos = 0.0;

bool isMarkerOrRegionBetween(double start, double end) {
int count = CountProjectMarkers(nullptr, nullptr, nullptr);
for (int i = 0; i < count; ++i) {
double markerPos, regionEnd;
bool isRegion;
EnumProjectMarkers(i, &isRegion, &markerPos, &regionEnd, nullptr, nullptr);
if (markerPos > end) {
break;
}
if ((start <= markerPos && markerPos <= end) ||
(isRegion && start <= regionEnd && regionEnd <= end)) {
return true;
}
}
return false;
}

bool isPassingItemEdge(double start, double end) {
if (end - start > 0.020) {
// The cursor jumped more than 20 ms. We only want to report when passing
// close to an item edge.
return false;
}
MediaTrack* track = GetLastTouchedTrack();
if (!track) {
return false;
}
int count = CountTrackMediaItems(track);
for (int i = 0; i < count; ++i) {
MediaItem* item = GetTrackMediaItem(track, i);
double itemStart = *(double*)GetSetMediaItemInfo(item, "D_POSITION", nullptr);
if (itemStart > end) {
break;
}
double length = *(double*)GetSetMediaItemInfo(item, "D_LENGTH", nullptr);
double itemEnd = itemStart + length;
if ((start <= itemStart && itemStart <= end) ||
(start <= itemEnd && itemEnd <= end)) {
return true;
}
}
return false;
}

} // namespace

void playSound(const char* fileName) {
if (!settings::playSounds) {
return;
}
if (soundPreviewReg.src) {
StopPreview(&soundPreviewReg);
PCM_Source_Destroy(soundPreviewReg.src);
} else {
// Initialise preview.
#ifdef _WIN32
InitializeCriticalSection(&soundPreviewReg.cs);
#else
pthread_mutex_init(&soundPreviewReg.mutex, nullptr);
#endif
soundPreviewReg.volume = 1.0;
}
string path(GetResourcePath());
path += "/osara/sounds/";
path += fileName;
soundPreviewReg.src = PCM_Source_CreateFromFile(path.c_str());
soundPreviewReg.curpos = 0.0;
PlayPreview(&soundPreviewReg);
}

void playSoundForCursorMovement() {
if (!settings::playSounds) {
return;
}
double cursor = GetCursorPosition();
if (cursor == lastSoundCursorPos) {
return; // No movement, nothing to do.
}
double start, end;
if (cursor > lastSoundCursorPos) {
// Moving forward.
start = lastSoundCursorPos;
end = cursor;
} else {
// Moving backward.
start = cursor;
end = lastSoundCursorPos;
}
if (isMarkerOrRegionBetween(start, end)) {
playSound("marker.mp3");
}
if (isPassingItemEdge(start, end)) {
playSound("item.mp3");
}
lastSoundCursorPos = cursor;
}
11 changes: 11 additions & 0 deletions src/coreUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* OSARA: Open Source Accessibility for the REAPER Application
* Core utilities header
* Copyright 2024 James Teh
* License: GNU General Public License version 2.0
*/

#pragma once

void playSound(const char* fileName);
void playSoundForCursorMovement();
9 changes: 7 additions & 2 deletions src/osara.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#ifndef _OSARA_H
#define _OSARA_H

// We need to include sstream first to avoid issues with SWELL.
#include <sstream>
#ifdef _WIN32
# include <windows.h>
#else
Expand All @@ -17,10 +19,9 @@
# include <windows.h>
# pragma clang diagnostic pop
#endif
#include <string>
#include <functional>
#include <memory>
#include <string>
#include <sstream>

#define REAPERAPI_MINIMAL
#define REAPERAPI_WANT_GetLastTouchedTrack
Expand Down Expand Up @@ -219,6 +220,10 @@
#define REAPERAPI_WANT_format_timestr_len
#define REAPERAPI_WANT_parse_timestr_len
#define REAPERAPI_WANT_TimeMap_GetTimeSigAtTime
#define REAPERAPI_WANT_PCM_Source_CreateFromFile
#define REAPERAPI_WANT_PCM_Source_Destroy
#define REAPERAPI_WANT_PlayPreview
#define REAPERAPI_WANT_StopPreview

#include <reaper/reaper_plugin.h>
#include <reaper/reaper_plugin_functions.h>
Expand Down
2 changes: 2 additions & 0 deletions src/reaper_osara.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "fxChain.h"
#include "translation.h"
#include "updateCheck.h"
#include "coreUtils.h"

using namespace std;
using namespace fmt::literals;
Expand Down Expand Up @@ -1180,6 +1181,7 @@ void postCursorMovement(int command) {
if (shouldReportTimeMovement()) {
outputMessage(formatCursorPosition().c_str());
}
playSoundForCursorMovement();
}

void postCursorMovementScrub(int command) {
Expand Down
3 changes: 3 additions & 0 deletions src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ BoolSetting(reportNotes, MIDI_EDITOR_SECTION,
BoolSetting(reportSurfaceChanges, MAIN_SECTION,
"Report changes made via &control surfaces",
false)
BoolSetting(playSounds, MAIN_SECTION,
"Provide feedback using s&ounds",
false)