Skip to content

Commit

Permalink
Artyom 1.0.0 💯
Browse files Browse the repository at this point in the history
Implementation of the soundex algorithm to increase the accuracy of
commands recognition and add commands with a new and clear syntax.
  • Loading branch information
sdkcarlos committed Sep 6, 2016
1 parent a098fff commit 1c6944d
Show file tree
Hide file tree
Showing 8 changed files with 331 additions and 63 deletions.
3 changes: 1 addition & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2015 Carlos Delgado
Copyright (c) 2016 Carlos Delgado

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

123 changes: 97 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,50 @@
<img src="https://raw.githubusercontent.com/sdkcarlos/artyom.js/master/src/images/artyomjs-logo.png" width="256" title="Artyom logo">
</p>

## Latest news
##[Read the official documentation of Artyom](http://ourcodeworld.com/projects/projects-documentation/1/list/artyom-js)
##[Read the official FAQ](http://ourcodeworld.com/projects/projects-faq/1/list/artyom-js)
##[Test the continuous mode here](https://sdkcarlos.github.io/jarvis.html)
#About Artyom

Use always the latest version of artyom.
Artyom.js is a robust and useful wrapper of the webkitSpeechRecognition and speechSynthesis APIs written in Javascript.
Besides, artyom allow you to add dinamically commands to your web app (website).

- **Artyom V 0.9.7 Released ! (25.07.2016 15:26 Berlin/Europe)**
- Artyom V 0.9.6 Released ! (06.06.2016 10:08 Berlin/Europe)
Artyom is constantly updated with new gadgets and awesome features, star and watch this repository to be aware of artyom updates.

Voice recognition javascript library. Create your own siri,google now or cortana within your website.
Between the most known features of artyom are :

Artyom is constantly maintained and updated with new gadgets.
### Speech Recognition

### Voice commands (with speech recognition) and speech synthesis made easy.
- Quick recognition of voice commands.
- Add commands easily.
- Smart commands (usage of wildcards).
- Create a dictation object to convert easily voice to text.
- Simulate commands without microphone.
- Execution keyword to execute a command immediately after the use of the keyword.
- Pause and resume command recognition.
- Artyom has available the soundex algorithm to increase the accuracy of the recognition of commands (disabled by default).
- Use a remote command processor service instead of local processing with Javascript.

<p align="center">
<img src="https://raw.githubusercontent.com/sdkcarlos/sdkcarlos.github.io/master/sites/artyom-resources/images/artyom_make_sandwich.jpg" alt="Artyom example use" width="256"/>
</p>
### Voice Synthesis

## Demostrations
###[Homepage](http://sdkcarlos.github.io/sites/artyom.html)
###[JARVIS Continuous mode](https://sdkcarlos.github.io/jarvis.html)
###[Sticky Notes Demo ALL Languages](https://sdkcarlos.github.io/demo-sites/artyom/artyom_sticky_notes.html)
- Synthesize large blocks of text without.
- onStart and onEnd callbacks will be always executed.

#Installation

You can get it on npm.
#### NPM

```shell
```batch
npm install artyom.js
```

And bower.
#### Bower

```shell
```batch
bower install artyom.js
```
Or download a zip package here [Download .zip](https://github.com/sdkcarlos/artyom.js/raw/master/public/artyom-source.zip)
Or just download a .zip package with the source code, minified file and commands examples : [download .zip file](https://github.com/sdkcarlos/artyom.js/raw/master/public/artyom-source.zip)

#[Ask for a method , problems, questions etc ...](https://github.com/sdkcarlos/artyom.js/issues)
#[Open Wiki (tutorial, documentation)](http://ourcodeworld.com/projects/projects-documentation/1/list/artyom-js)
#[See changelog](http://ourcodeworld.com/projects/projects-documentation/2/read-doc/official-changelog/artyom-js)
# Languages

Artyom offers **COMPLETE** Support for the following languages
Artyom provides **complete** support for the following languages. Every language needs an initialization code that needs to be provided in the lang property at the initialization.

| |Description |Codes for initialization|
------------- | ------------- | ------------- |
Expand All @@ -62,3 +61,75 @@ Artyom offers **COMPLETE** Support for the following languages
| <img src="https://raw.githubusercontent.com/sdkcarlos/sdkcarlos.github.io/master/sites/artyom-resources/images/flag-poland.png" alt="Supported language"/> | Polski (polonia)| pl-PL<br/>pl |
| <img src="https://raw.githubusercontent.com/sdkcarlos/sdkcarlos.github.io/master/sites/artyom-resources/images/flag-indonesia.png" alt="Supported language"/> | Indonesian (Indonesia)| id-ID<br/>id |
| <img src="https://raw.githubusercontent.com/sdkcarlos/sdkcarlos.github.io/master/sites/artyom-resources/images/flag-china.png" alt="Supported language"/> | Chinese (Cantonese[ 粤語(香港)] <br/> Mandarin[普通话(中国大陆)])| Cantonese<br/>zh-HK<br/> Mandarin<br />zh-CN|

# All you need to know about Artyom

- [Documentation](http://ourcodeworld.com/projects/projects-documentation/1/list/artyom-js)
- [Frequently Asked Questions](http://ourcodeworld.com/projects/projects-faq/1/list/artyom-js)
- [Changelog](http://ourcodeworld.com/projects/projects-documentation/2/read-doc/official-changelog/artyom-js)

Do not hesitate to create a ticket on the issues area of the Github repository for any question, problem or inconvenient that you may have about artyom.

# Basic usage

```javascript
// Add command (Short code artisan way)
artyom.on(['Good morning','Good afternoon']).then(function(i){
switch (i) {
case 0:
artyom.say("Good morning, how are you?");
break;
case 1:
artyom.say("Good afternoon, how are you?");
break;
}
});

// Smart command (Short code artisan way), set the second parameter of .on to true
artyom.on(['Repeat after me *'] , true).then(function(i,wildcard){
artyom.say("You've said : " + wildcard);
});

// or add some commands in the normal way

artyom.addCommands([
{
indexes: ['Hello','Hi','is someone there'],
action: function(i){
artyom.say("Hello, it's me");
}
},
{
indexes: ['Repeat after me *'],
smart:true,
action: function(i,wildcard){
artyom.say("You've said : "+ wildcard);
}
}
]);

// Start the commands !
artyom.initialize({
lang:"en-GB", // GreatBritain english
continuous:true, // Listen forever
soundex:true,// Use the soundex algorithm to increase accuracy
debug:true, // Show messages in the console
executionKeyword: "and do it now",
listen:true // Start to listen commands !
});
```

Working with artyom is cool and easy, read the documentation to discover more awesome features.

# Demostrations

- [Homepage](https://sdkcarlos.github.io/jarvis.html)
- [Continuous mode J.A.R.V.I.S](https://sdkcarlos.github.io/jarvis.html)
- [Sticky Notes](https://sdkcarlos.github.io/demo-sites/artyom/artyom_sticky_notes.html)


Thanks for visit the repository !

<p align="center">
<img src="https://raw.githubusercontent.com/sdkcarlos/sdkcarlos.github.io/master/sites/artyom-resources/images/artyom_make_sandwich.jpg" alt="Artyom example use" width="256"/>
</p>
120 changes: 106 additions & 14 deletions dev-no-download/artyom.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
* @copyright Copyright (c) 2016 Copyright Our Code World All Rights Reserved.
* @author Carlos Delgado - www.ourcodeworld.com
* @param {type} window
* @see http://sdkcarlos.github.io/artyom.html
* @see https://sdkcarlos.github.io/sites/artyom.html
* @returns Artyom
*/
(function (window) {'use strict';
// getVoices is an asynchronous native method. At firs time it will ALWAYS return an empty array
// after it will return an array with all the available voices in the browser
if ('speechSynthesis' in window) {
if (window.hasOwnProperty('speechSynthesis')) {
speechSynthesis.getVoices();
}

if (('webkitSpeechRecognition' in window)) {
if (window.hasOwnProperty('webkitSpeechRecognition')) {
var reconocimiento = new webkitSpeechRecognition();
}

Expand All @@ -30,13 +30,14 @@
debug: false,
helpers: {
redirectRecognizedTextOutput: null,
remoteProcessorHandler:null,
remoteProcessorHandler: null,
lastSay: null
},
executionKeyword: null,
obeyKeyword: null,
speaking:false,
obeying:true
speaking: false,
obeying: true,
soundex: false
};

/**
Expand Down Expand Up @@ -98,17 +99,44 @@
isChrome: true
};

if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0, 4))) {
if( navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) || navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i) || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/Windows Phone/i)){
device.isMobile = true;
}

if (navigator.userAgent.indexOf("Chrome") == -1) {
device.isChrome = false;
}

function ArtyomAI() {
function ArtyomInternals() {
/**
* Javascript implementation of the soundex algorithm.
* @see https://gist.github.com/shawndumas/1262659
* @returns {String}
*/
this.soundex = function(s) {
var a = s.toLowerCase().split(''),
f = a.shift(),
r = '',
codes={a:"",e:"",i:"",o:"",u:"",b:1,f:1,p:1,v:1,c:2,g:2,j:2,k:2,q:2,s:2,x:2,z:2,d:3,t:3,l:4,m:5,n:5,r:6};

r = f +
a
.map(function(v, i, a) {
return codes[v]
})
.filter(function(v, i, a) {
return ((i === 0) ? v !== codes[f] : v !== a[i - 1]);
})
.join('');

return (r + '000').slice(0, 4).toUpperCase();
};
}

function Artyom() {
var artyom = {};
var artyomCommands = [];
var artyomInternals = new ArtyomInternals();

/**
* Contains some basic information that artyom needs to know as the type of device and browser
Expand Down Expand Up @@ -243,6 +271,10 @@
artyomProperties.speed = config.speed;
}

if (config.hasOwnProperty("soundex")) {
artyomProperties.soundex = config.soundex;
}

if (config.hasOwnProperty("executionKeyword")) {
artyomProperties.executionKeyword = config.executionKeyword;
}
Expand Down Expand Up @@ -1106,6 +1138,41 @@
}
}//End Step 3

/**
* If the soundex options is enabled, proceed to process the commands in case that any of the previous
* ways of processing (exact, lowercase and command in quote) didn't match anything.
* Based on the soundex algorithm match a command if the spoken text is similar to any of the artyom commands.
* Example :
* If you have a command with "Open Wallmart" and "Open Willmar" is recognized, the open wallmart command will be triggered.
* soundex("Open Wallmart") == soundex("Open Willmar") <= true
*
*/
if(artyomProperties.soundex){
for (var i = 0; i < artyomCommands.length; i++) {
var instruction = artyomCommands[i];
var opciones = instruction.indexes;
var encontrado = -1;

for (var c = 0; c < opciones.length; c++) {
var opcion = opciones[c];
if (instruction.smart) {
continue;//Jump wildcard commands
}

if(artyomInternals.soundex(voz) == artyomInternals.soundex(opcion)){
artyom.debug(">> Matched Soundex command '"+opcion+"' AGAINST '"+voz+"' with index "+ c , "info");
encontrado = parseInt(c);
artyom_triggerEvent(artyom_global_events.COMMAND_MATCHED);

return {
indice: encontrado,
objeto: instruction
};
}
}
}
}

return false;
};

Expand Down Expand Up @@ -1440,8 +1507,7 @@
};

/**
* Pause the processing of commands. Artyom still listening in the background
* and it can be resumed after a couple of seconds.
* Pause the processing of commands. Artyom still listening in the background and it can be resumed after a couple of seconds.
*
* @returns {Boolean}
*/
Expand Down Expand Up @@ -1478,8 +1544,33 @@
};

/**
* Process the recognized text if artyom is active
* in remote mode.
* Add commands like an artisan. If you use artyom for simple tasks
* then probably you don't like to write a lot to achieve it.
*
* Use the artisan syntax to write less, but with the same accuracy.
*
* @disclaimer Not a promise-based implementation, just syntax.
* @returns {Boolean}
*/
artyom.on = function(indexes,smart){
return {
then: function(action){
var command = {
indexes:indexes,
action: action
};

if(smart){
command.smart = true;
}

artyom.addCommands(command);
}
};
};

/**
* Process the recognized text if artyom is active in remote mode.
*
* @returns {Boolean}
*/
Expand All @@ -1493,8 +1584,9 @@
}

if (typeof (artyom) === 'undefined') {
window.artyom = Object.preventExtensions(new ArtyomAI());
window.artyom = Object.preventExtensions(new Artyom());
} else {
console.warn("Artyom is being loaded twice in your document or you're injecting the artyom script via console (injected webkitSpeechRecognition will not work due to security reasons)");
console.info("Artyom has been already defined in the Window");
}

})(window);
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "artyom.js",
"version": "0.9.7",
"version": "1.0.0",
"description": "Artyom is a Robust Wrapper of the Google Chrome SpeechSynthesis and SpeechRecognition that allows you to create a virtual assistent",
"main": "artyom.js",
"scripts": {
Expand All @@ -21,7 +21,7 @@
"googleNow"
],
"author": "Carlos Delgado",
"license": "ISC",
"license": "MIT",
"bugs": {
"url": "https://github.com/sdkcarlos/artyom.js/issues"
},
Expand Down
Binary file modified public/artyom-source.zip
Binary file not shown.

0 comments on commit 1c6944d

Please sign in to comment.