8 Commits
v0.2.1 ... main

Author SHA1 Message Date
0e6d8f9c8b Added api key input 2025-05-18 18:31:34 -04:00
735fc3d2ae ### Added
- 4 new actions
-- Toggle Hear self
-- Toggle Hear background music
-- Toggle mute mic
-- Toggle mute Soundboard for me
2024-02-15 20:40:49 -05:00
d5ce9d1810 ### Added
- three new variables

### Updated
- feedback labels have been reworded to make their value more obvious

### Fixed
- Reset failure variable in retry logic on successful connection
2024-02-15 19:43:09 -05:00
56d486e4cf ### Added
- preset for hold to beep (basically the 'censor beep')
2024-01-27 00:59:01 -05:00
73e4f56599 ### Update
- filled out the Readme file with a little more information
2024-01-23 12:52:19 -05:00
095ab387c6 ### Update
- version number
- updated voicemod dependency to point to an actual version rather then the HEAD of a branch
2024-01-23 12:42:06 -05:00
b9df465090 ### Update
- help file
2024-01-23 12:28:54 -05:00
619e10d43f ### Fix
- init runs twice since we weren't doing an await on our init call
- variables now update correctly on startup

### Removed
- api key config option is no longer needed as we are just going to use the one key supplied by VoiceMod
2024-01-23 12:22:31 -05:00
8 changed files with 144 additions and 24 deletions

View File

@@ -1,3 +1,6 @@
# companion-module-voicemod # companion-module-voicemod
A [BitFocus Companion](https://bitfocus.io/companion/) module for interacting
with [Voicemod](https://www.voicemod.net/)'s control api.
See [HELP.md](./companion/HELP.md) and [LICENSE](./LICENSE) See [HELP.md](./companion/HELP.md) and [LICENSE](./LICENSE)

View File

@@ -62,5 +62,33 @@ module.exports = function (self) {
self.vm.stopAllSounds() self.vm.stopAllSounds()
}, },
}, },
hear_self: {
name: 'Toggle Hear Self',
options: [],
callback: async (event) => {
self.vm.internal.toggleHearMyVoice()
},
},
hear_background: {
name: 'Toggle Hear Background',
options: [],
callback: async (event) => {
self.vm.internal.toggleBackground()
},
},
mute_mic: {
name: 'Toggle Mute Mic',
options: [],
callback: async (event) => {
self.vm.internal.toggleMuteMic()
},
},
mute_memes_for_me: {
name: 'Toggle Mute Soundboard for me',
options: [],
callback: async (event) => {
self.vm.internal.toggleMuteMemeForMe()
},
},
}) })
} }

View File

@@ -1,3 +1,9 @@
## Your module ## Voicemod API
Write some help for your users here! ### Configuration
Due to a limitation in the voicemod software, host address should always be 127.0.0.1.
It was stated in their issue tracker that they will be looking at adding a toggle to
allow connections from outside the local host.
This would benefit users that want to run voicemod on another system from the controlling software.

View File

@@ -3,9 +3,9 @@ const { combineRgb } = require('@companion-module/base')
module.exports = async function (self) { module.exports = async function (self) {
self.setFeedbackDefinitions({ self.setFeedbackDefinitions({
VoiceChangerState: { VoiceChangerState: {
name: 'Voice Changer State', name: 'Voice Changer Enabled',
type: 'boolean', type: 'boolean',
label: 'Voice Changer State', label: 'Voice Changer Enabled',
defaultStyle: { defaultStyle: {
bgcolor: combineRgb(255, 0, 0), bgcolor: combineRgb(255, 0, 0),
color: combineRgb(0, 0, 0), color: combineRgb(0, 0, 0),
@@ -16,9 +16,9 @@ module.exports = async function (self) {
}, },
}, },
BackgroundEffectState: { BackgroundEffectState: {
name: 'Background Effect State', name: 'Background Effect Enabled',
type: 'boolean', type: 'boolean',
label: 'Background Effect Status', label: 'Background Effect Enabled',
defaultStyle: { defaultStyle: {
bgcolor: combineRgb(255, 0, 0), bgcolor: combineRgb(255, 0, 0),
color: combineRgb(0, 0, 0), color: combineRgb(0, 0, 0),
@@ -29,9 +29,9 @@ module.exports = async function (self) {
}, },
}, },
HearMyVoiceState: { HearMyVoiceState: {
name: 'Hear My Voice State', name: 'Hear My Voice Enabled',
type: 'boolean', type: 'boolean',
label: 'Hear My Voice State', label: 'Hear My Voice Enabled',
defaultStyle: { defaultStyle: {
bgcolor: combineRgb(255, 0, 0), bgcolor: combineRgb(255, 0, 0),
color: combineRgb(0, 0, 0), color: combineRgb(0, 0, 0),
@@ -42,9 +42,9 @@ module.exports = async function (self) {
}, },
}, },
MicMutedState: { MicMutedState: {
name: 'Microphone Mute State', name: 'Microphone Mute Enabled',
type: 'boolean', type: 'boolean',
label: 'Microphone Mute State', label: 'Microphone Mute Enabled',
defaultStyle: { defaultStyle: {
bgcolor: combineRgb(255, 0, 0), bgcolor: combineRgb(255, 0, 0),
color: combineRgb(0, 0, 0), color: combineRgb(0, 0, 0),
@@ -55,9 +55,9 @@ module.exports = async function (self) {
}, },
}, },
MemesMutedForMeState: { MemesMutedForMeState: {
name: 'Soundboard - Mute For Me State', name: 'Soundboard - Mute For Me Enabled',
type: 'boolean', type: 'boolean',
label: 'Soundboard Mute For Me State', label: 'Soundboard Mute For Me Enabled',
defaultStyle: { defaultStyle: {
bgcolor: combineRgb(255, 0, 0), bgcolor: combineRgb(255, 0, 0),
color: combineRgb(0, 0, 0), color: combineRgb(0, 0, 0),

61
main.js
View File

@@ -3,6 +3,7 @@ const UpgradeScripts = require('./upgrades')
const UpdateActions = require('./actions') const UpdateActions = require('./actions')
const UpdateFeedbacks = require('./feedbacks') const UpdateFeedbacks = require('./feedbacks')
const UpdateVariableDefinitions = require('./variables') const UpdateVariableDefinitions = require('./variables')
const UpdatePresets = require('./presets')
const { VoiceMod } = require('voicemod') const { VoiceMod } = require('voicemod')
class ModuleInstance extends InstanceBase { class ModuleInstance extends InstanceBase {
@@ -19,6 +20,7 @@ class ModuleInstance extends InstanceBase {
this.hearMyVoiceEnabled = false this.hearMyVoiceEnabled = false
this.muteEnabled = false this.muteEnabled = false
this.muteMemesEnabled = false this.muteMemesEnabled = false
this.currentVoiceName = ''
} }
sleep(ms) { sleep(ms) {
@@ -33,57 +35,90 @@ class ModuleInstance extends InstanceBase {
this.updateStatus(InstanceStatus.Connecting) this.updateStatus(InstanceStatus.Connecting)
this.vm = new VoiceMod(this.config.host, this.config.apiKey === '' ? 'anyClient' : this.config.apiKey) this.vm = new VoiceMod(this.config.host, this.config.apiKey === '' ? 'anyClient' : this.config.apiKey)
try { try {
this.vm.init().then( await this.vm.init().then(
async () => { async () => {
this.vm.internal.on('backgroundEffectsEnabledEvent', (background) => { this.vm.internal.on('backgroundEffectsEnabledEvent', (background) => {
this.backgroundEffectsEnabled = true this.backgroundEffectsEnabled = true
this.checkFeedbacks('BackgroundEffectState') this.checkFeedbacks('BackgroundEffectState')
this.updateVariableDefinitions()
}) })
this.vm.internal.on('backgroundEffectsDisabledEvent', (background) => { this.vm.internal.on('backgroundEffectsDisabledEvent', (background) => {
this.backgroundEffectsEnabled = false this.backgroundEffectsEnabled = false
this.checkFeedbacks('BackgroundEffectState') this.checkFeedbacks('BackgroundEffectState')
this.updateVariableDefinitions()
}) })
this.vm.internal.on('voiceChangerEnabledEvent', (data) => { this.vm.internal.on('voiceChangerEnabledEvent', (data) => {
this.voiceChangerEnabled = true this.voiceChangerEnabled = true
this.checkFeedbacks('VoiceChangerState') this.checkFeedbacks('VoiceChangerState')
this.updateVariableDefinitions()
}) })
this.vm.internal.on('voiceChangerDisabledEvent', (data) => { this.vm.internal.on('voiceChangerDisabledEvent', (data) => {
this.voiceChangerEnabled = false this.voiceChangerEnabled = false
this.checkFeedbacks('VoiceChangerState') this.checkFeedbacks('VoiceChangerState')
this.updateVariableDefinitions()
}) })
this.vm.internal.on('hearMySelfEnabledEvent', (data) => { this.vm.internal.on('hearMySelfEnabledEvent', (data) => {
this.hearMyVoiceEnabled = true this.hearMyVoiceEnabled = true
this.checkFeedbacks('HearMyVoiceState') this.checkFeedbacks('HearMyVoiceState')
this.updateVariableDefinitions()
}) })
this.vm.internal.on('hearMySelfDisabledEvent', (data) => { this.vm.internal.on('hearMySelfDisabledEvent', (data) => {
this.hearMyVoiceEnabled = false this.hearMyVoiceEnabled = false
this.checkFeedbacks('HearMyVoiceState') this.checkFeedbacks('HearMyVoiceState')
this.updateVariableDefinitions()
}) })
this.vm.internal.on('muteMicrophoneEnabledEvent', (data) => { this.vm.internal.on('muteMicrophoneEnabledEvent', (data) => {
this.muteEnabled = true this.muteEnabled = true
this.checkFeedbacks('MicMutedState') this.checkFeedbacks('MicMutedState')
this.updateVariableDefinitions()
}) })
this.vm.internal.on('muteMicrophoneDisabledEvent', (data) => { this.vm.internal.on('muteMicrophoneDisabledEvent', (data) => {
this.muteEnabled = false this.muteEnabled = false
this.checkFeedbacks('MicMutedState') this.checkFeedbacks('MicMutedState')
this.updateVariableDefinitions()
}) })
this.vm.internal.on('muteMemeForMeEnabledEvent', (data) => { this.vm.internal.on('muteMemeForMeEnabledEvent', (data) => {
this.muteMemesEnabled = true this.muteMemesEnabled = true
this.checkFeedbacks('MemesMutedForMeState') this.checkFeedbacks('MemesMutedForMeState')
this.updateVariableDefinitions()
}) })
this.vm.internal.on('muteMemeForMeDisabledEvent', (data) => { this.vm.internal.on('muteMemeForMeDisabledEvent', (data) => {
this.muteMemesEnabled = false this.muteMemesEnabled = false
this.checkFeedbacks('MemesMutedForMeState') this.checkFeedbacks('MemesMutedForMeState')
this.updateVariableDefinitions()
})
this.vm.internal.on('getAllSoundboard', (data) => {
this.updateActions()
})
this.vm.internal.on('voiceLoadedEvent', (data) => {
this.currentVoiceName = data.voiceId
this.updateVariableDefinitions()
})
this.vm.internal.on('getCurrentVoice', (data) => {
this.currentVoiceName = data.voiceId
this.updateVariableDefinitions()
})
this.vm.internal.on('toggleVoiceChanger', (data) => {
this.voiceChangerEnabled = data.value
this.checkFeedbacks('VoiceChangerState')
this.updateVariableDefinitions()
})
this.vm.internal.on('toggleMuteMic', (data) => {
this.muteEnabled = data.value
this.checkFeedbacks('MicMutedState')
this.updateVariableDefinitions()
}) })
this.vm.internal.getVoiceChangerStatus()
this.vm.internal.getBackgroundEffectStatus()
this.vm.internal.getMuteMicStatus()
this.vm.internal.getMuteMemeForMeStatus()
await this.vm.internal.getCurrentVoice()
this.vm.internal.getVoiceChangerStatus()
this.vm.internal.getMuteMicStatus()
this.failure = 0
this.loaded = true
this.updateStatus(InstanceStatus.Ok) this.updateStatus(InstanceStatus.Ok)
this.updatePresets()
this.updateActionsFeedbacksVariables() this.updateActionsFeedbacksVariables()
this.loaded = true
this.log('debug', 'connected to VM and ready') this.log('debug', 'connected to VM and ready')
}, },
(reason) => { (reason) => {
@@ -97,7 +132,6 @@ class ModuleInstance extends InstanceBase {
this.updateStatus(InstanceStatus.UnknownError) this.updateStatus(InstanceStatus.UnknownError)
++this.failure ++this.failure
} }
if (this.loaded === false) await this.sleep(500)
} while (this.loaded === false && this.failure < 5) } while (this.loaded === false && this.failure < 5)
} }
// When module gets deleted // When module gets deleted
@@ -124,7 +158,7 @@ class ModuleInstance extends InstanceBase {
id: 'apiKey', id: 'apiKey',
type: 'textinput', type: 'textinput',
label: 'API Key', label: 'API Key',
tooltip: 'Enter your developer API Key for voicemod (not required for now)', tooltip: 'Enter your API Key for voicemod (https://control-api.voicemod.net)',
default: '', default: '',
}, },
] ]
@@ -153,10 +187,17 @@ class ModuleInstance extends InstanceBase {
this.setVariableValues({ this.setVariableValues({
microphoneMuted: this.muteEnabled, microphoneMuted: this.muteEnabled,
voiceChangerStatus: !this.voiceChangerEnabled, hearMyVoice: this.hearMyVoiceEnabled,
voiceSelected: undefined, hearBackgroundMusic: this.backgroundEffectsEnabled,
hearMemesForMe: this.muteMemesEnabled,
voiceChangerStatus: this.voiceChangerEnabled,
voiceSelected: this.currentVoiceName,
}) })
} }
updatePresets() {
UpdatePresets(this)
}
} }
runEntrypoint(ModuleInstance, UpgradeScripts) runEntrypoint(ModuleInstance, UpgradeScripts)

View File

@@ -1,6 +1,6 @@
{ {
"name": "voicemod-api", "name": "voicemod-api",
"version": "0.2.0", "version": "1.0.0",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {
"format": "prettier -w ." "format": "prettier -w ."
@@ -12,7 +12,7 @@
}, },
"dependencies": { "dependencies": {
"@companion-module/base": "~1.5.1", "@companion-module/base": "~1.5.1",
"voicemod": "git+https://github.com/RavenX8/voicemod-api.git#companion-module-voicemod-api" "voicemod": "git+https://github.com/RavenX8/voicemod-api.git#39a07b74e20e76d0ff5776f0768d1c934364a9fd"
}, },
"devDependencies": { "devDependencies": {
"@companion-module/tools": "^1.4.1" "@companion-module/tools": "^1.4.1"

39
presets.js Normal file
View File

@@ -0,0 +1,39 @@
const { combineRgb } = require('@companion-module/base')
module.exports = async function (self) {
const presets = {}
presets[`beep`] = {
type: 'button',
category: 'Sounds',
name: 'Beep!',
style: {
text: `Beep!`,
size: '24',
color: combineRgb(255, 255, 255),
bgcolor: combineRgb(0, 0, 0),
},
steps: [
{
down: [
{
actionId: 'set_beep_sound',
options: {
beepEnabled: true,
},
},
],
up: [
{
actionId: 'set_beep_sound',
options: {
beepEnabled: false,
},
},
],
},
],
feedbacks: [],
}
self.setPresetDefinitions(presets)
}

View File

@@ -3,5 +3,8 @@ module.exports = async function (self) {
{ variableId: 'microphoneMuted', name: 'Microphone Muted' }, { variableId: 'microphoneMuted', name: 'Microphone Muted' },
{ variableId: 'voiceChangerStatus', name: 'Voice Changer Enabled' }, { variableId: 'voiceChangerStatus', name: 'Voice Changer Enabled' },
{ variableId: 'voiceSelected', name: 'Current Voice Selected' }, { variableId: 'voiceSelected', name: 'Current Voice Selected' },
{ variableId: 'hearMyVoice', name: 'Hear My Voice Enabled' },
{ variableId: 'hearBackgroundMusic', name: 'Background Music Enabled' },
{ variableId: 'hearMemesForMe', name: 'Hear Memes for Me Enabled' },
]) ])
} }