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

Seperate the parsing and rendering process #194

Closed
YeDaxia opened this issue Aug 12, 2018 · 3 comments
Closed

Seperate the parsing and rendering process #194

YeDaxia opened this issue Aug 12, 2018 · 3 comments
Assignees
Labels
area-file-formats Related to supported file formats area-rendering Everything related to the rendering state-needs-discussion 💬 type-bug 🕷️
Milestone

Comments

@YeDaxia
Copy link

YeDaxia commented Aug 12, 2018

environment

  • Version used: (master branch)
  • Platform used: JavaScript
  • Rendering engine used: SVG
  • Browser Name and Version: chrome & node.js
  • Operating System and version (desktop or mobile): macos

Problem

test gtp file: download

I want to separate the parser to the backend server of node.js, I try to parse the score object as json at the server side, and render the score as SVG at browser side, but I meet some problem, here's the thing:

the server side code (node.js):

var converter = new AlphaTab.Model.JsonConverter();
var score = AlphaTab.Importer.ScoreLoader.LoadScoreFromBytes(data);
return converter.ScoreToJsObject(score);

the browser side code:

$.get(parseUrl, function(data){
    var converter = new AlphaTab.Model.JsonConverter();
    var score  = converter.JsObjectToScore(data);
    gtpTab.alphaTab('score', score);
})

the Expected result should rendered:

but it turns out:

And when I try to test the convertion process all in brower side, it works:

var score  = AlphaTab.Importer.ScoreLoader.LoadScoreFromBytes(responseArray);
var converter = new AlphaTab.Model.JsonConverter();
var jsScore = converter.ScoreToJsObject(score); 
gtpTab.alphaTab('score', converter.JsObjectToScore(jsScore));

thanks for your job. please help me to solve this problem.

@Danielku15 Danielku15 self-assigned this Aug 12, 2018
@Danielku15 Danielku15 added state-needs-discussion 💬 type-bug 🕷️ area-file-formats Related to supported file formats area-rendering Everything related to the rendering labels Aug 12, 2018
@Danielku15
Copy link
Member

Thanks for reporting. It somehow looks to me that the notes are transposed several octaves down. Relatively they are still correct.

The test case that it works within the browser at least shows that there is no bug in the code itself. In both cases alphaTab accepts a raw json without any further settings and renders it.

I could imagine that something is wrong on the server side. Did you check if 2 JSONs (from browser and from node.js) are really the same? (e.g. via http://www.jsondiff.com/)

@YeDaxia
Copy link
Author

YeDaxia commented Aug 12, 2018

I do another test, it appears the same problem, here' s how how I test it:

environment: all code runs in chrome brower side.

  1. firstly, get the json string from the browser side:
var score  = AlphaTab.Importer.ScoreLoader.LoadScoreFromBytes(responseArray);
var converter = new AlphaTab.Model.JsonConverter();
var jsScore = converter.ScoreToJsObject(score);
console.log(JSON.stringify(jsScore));

print the json string, remove the code.

  1. secondly, copy this json object to data and render it.

check the whole json data here;

data = {}; // cory from the printing json above. 
var converter = new AlphaTab.Model.JsonConverter();
var score  = converter.JsObjectToScore(data);
gtpTab.alphaTab('score', score);               

I have checked the code of LoadScoreFromBytes, but cannot find any clue. I think I must miss something.

@Danielku15
Copy link
Member

Danielku15 commented Aug 19, 2018

I found the issue. The issue is in the JSON.stringify and the typed arrays. When a typed array is serialized to string via JSON.stringify it becomes an object. But when again converting the string to an object, it is not a typed array anymore:

JSON.stringify(new Int32Array(10)) 
  == "{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0}"

JSON.parse(JSON.stringify(new Int32Array(10))) 
 == {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0}

The solution is to serialize typed arrays as array:

var score  = alphaTab.importer.ScoreLoader.LoadScoreFromBytes(data);
var jsScore = alphaTab.model.JsonConverter.ScoreToJsObject(score);
var json = JSON.stringify(jsScore, function(k, v) {
	if (ArrayBuffer.isView(v)) {
		return Array.apply([], v);
	}
	return v;
});

Here a full node.js script that was working for me:

const express = require('express')
const TextDecoder = require('util').TextDecoder
const fs = require('fs');

const alphaTab = require('../Build/JavaScript/alphaTab.js').alphaTab

const app = express()
const port = 3000
app.get('/', (request, response) => {
  const file = request.query.file;
  if(file) {
    try {
      var data = fs.readFileSync(file);
      var score  = alphaTab.importer.ScoreLoader.LoadScoreFromBytes(data);
      var jsScore = alphaTab.model.JsonConverter.ScoreToJsObject(score);
      var json = JSON.stringify(jsScore, function(k, v) {
        if (ArrayBuffer.isView(v)) {
          return Array.apply([], v);
        }
        return v;
      });
    
      response.header('Access-Control-Allow-Origin', '*');
      response.header('Content-Type', 'application/json');
      response.send(json);
    }
    catch(e) {
      console.log(e);
      console.log(e.stack);
      response.status(404).send('Error: ' + e);
    }
    
  }
  else {
    response.status(404).send('File not found');
  }  
})

app.listen(port, (err) => {
  if (err) {
    return console.log('something bad happened', err)
  }

  console.log(`server is listening on ${port}`)
})

Please note that the casing changed in the lastest master/develop versions. I also made some fixes that were causing troubles when including alphaTab into node.

Edit1
I added also some specific JsonConverter.ScoreToJson and JsonConverter.JsonToScore which wrap the string serialization correctly. With this you should be safe to proceed.

If you have further issues feel free to reopen the issue.

@Danielku15 Danielku15 added this to the 1.0.0 milestone Aug 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-file-formats Related to supported file formats area-rendering Everything related to the rendering state-needs-discussion 💬 type-bug 🕷️
Projects
None yet
Development

No branches or pull requests

2 participants