আমার জন্য একটি গান খেলুন


23

চ্যালেঞ্জ

গিটারের ট্যাবলেটরে দেওয়া আপনার অবশ্যই ট্যাব দ্বারা উপস্থাপিত গানটি আউটপুট করতে পারেন। এটি আপনার কম্পিউটারের স্পিকারের বা অডিও ফাইলের (.wav, .mp3, .midi, .aif, ইত্যাদি) হতে পারে। টাইমিংয়ের জন্য দ্বিতীয় ইনপুটও থাকবে।

ট্যাবগুলি কোনও ফাইলের মাধ্যমে অথবা সরাসরি STDIN এ ইনপুট হতে পারে। ট্যাবটি ASCII আকারে থাকবে

ফটকা খেলা

সমস্ত ট্যাবগুলি স্ট্যান্ডার্ড E টিউনিং সহ 6 টি স্ট্রিং গিটারের জন্য: E2 (82.41 Hz), A2 (110.00 Hz), D3 (146.83 Hz), G3 (196.00 Hz), B3 (246.94 Hz), E4 (329.63 Hz)।

কেবলমাত্র কৌশলগুলি (সাধারণ বাছাই করা ছাড়াও) আপনার জন্য প্রয়োজনীয় যা তা হ'ল:

  • নমন (এটি সর্বদা অর্ধ স্বরের বাঁক হবে)
  • হাতুড়ি চলছে on
  • টানছে
  • উপরে / নিচে স্লাইডিং

যেহেতু আপনি নিঃশব্দ স্ট্রিংয়ের শব্দ সংশ্লেষ করতে পারবেন না, তাই xহিসাবে আচরণ করুন -

বাঁকানোর সময়, অনাবেন্টের কাছে বেঁকে যাওয়ার জন্য অন্বেত থেকে স্ট্রিংয়ের সম্পূর্ণ রূপান্তর আউটপুট করুন।

দ্বিতীয় ইনপুটটি এমন সময় হবে যখন ট্যাবে প্রতিটি প্রতীকটি সেকেন্ডে উপস্থাপন করে। উদাহরণ স্বরূপ:

ইনপুট জন্য:

e|---
B|---
G|---
D|---
A|---
E|---

সময় সহ 0.5, কারণ এখানে 3প্রতীকগুলির কলাম রয়েছে (তবে কোনও নোট নেই), আউটপুটযুক্ত অডিও ফাইলটি ( 3*0.5=1.5) 1.5কয়েক সেকেন্ডের নীরবতা রয়েছে।

উদাহরণ ট্যাব

1 - ওজন (জ্যাক হোয়াইট, জিমি পৃষ্ঠা + এজ সংস্করণ)

e|----3-----3---3----2---------3--------------------|
B|----3-----3---3----3--1-1----3--------------------|
G|----0-----0---0----2--0-0----0--------------------|
D|----0-----0---2-------2-2----0--------------------|          
A|----2-----0---2-------3-3----2--------------------|     
E|----3-----2---x----2--x-x----3--------------------|   

2 - কিশোর আত্মার মতো গন্ধ পাওয়া যায়

e|--------------|---------------|-------------|-------------|
B|--------------|---------------|-------------|-------------|
G|-----8h10-----|-8-8b----6--5--|-6--5--------|-------------|
D|-10--------6--|---------------|-------8-6-8-|-8b----6--5--|
A|--------------|---------------|-------------|-------------|
E|--------------|---------------|-------------|-------------|

3 - স্টার স্প্যানল্ড ব্যানার

e|---0-------2-5---9-7-5-----------9-7-5-4-2-4-5------|
B|-----2---2-------------2-4-5---5---------------5-2--|
G|-------2-------------------------------------------2|
D|----------------------------------------------------|
A|----------------------------------------------------|
E|----------------------------------------------------|

3
আমি আপনার ফ্রিকোয়েন্সিগুলিতে আরও কয়েকটি দশমিক স্থান যুক্ত করেছি। দেওয়া হয়েছে যে এক সেমিটোন = 1 ফ্রেটটি 1.059463: 1 এর অনুপাত: (যার অর্থ প্রায় 6% এর পার্থক্য) খুব কাছের 1Hz এ টিউন করা ভাল ইন-টিউন সাউন্ড পাওয়ার পক্ষে যথাযথ নয়। অবশ্যই জনপ্রিয়তার প্রতিযোগিতা হওয়ার কারণে, খারাপ টিউনিং গ্রহণযোগ্য হতে পারে তবে এটি জিততে পারে না।
স্তর নদী সেন্ট

খুব সৃজনশীল প্রতিযোগিতা! আমি ASCII ফর্মের লিঙ্কটি দেখার পরে, আমি উদাহরণ 2 বুঝতে পারি (যেহেতু আমি গানটি শুনেছি), তবে আমি গিটারটি জানি না বলে, আমি মনে করি চ্যালেঞ্জটির উচ্চতর শিক্ষার বক্ররেখা রয়েছে। অড্যাসিটির বেসিক ব্যবহার ব্যতীত অডিও ম্যানিপুলেশন নিয়ে আমারও খুব কম অভিজ্ঞতা আছে।
mbomb007

মিডি কি কোনও 'অডিও ফাইল' হিসাবে গণনা করে?
orlp

@ অর্পল হ্যাঁ, এটি হয়
বিটা

1
ভবিষ্যতের রেফারেন্সের জন্য ভাল: v * (2 ^ (f / 12)) = x; v = স্ট্রিংয়ের ফ্রিকোয়েন্সি; f = ফ্রেট (ট্যাবের নম্বর); x = ফ্রিকোয়েন্সি খেলেছে; ট্যাবগুলি আপনাকে একটি নোটের দৈর্ঘ্যও বলে না; আপনার প্রোগ্রামটি স্মার্ট হওয়া দরকার।
গ্রান্ট ডেভিস

উত্তর:


7

ম্যাটল্যাব

এটি একরকম অসম্পূর্ণ। অডিওটি যতটা সম্ভব সহজেই তৈরি করতে আমি একটি দ্রুত এবং নোংরা পদ্ধতি ব্যবহার করেছি। আমি যে পদ্ধতিটি ব্যবহার করেছি তাতে বাঁকানো / হাতুড়ি প্রয়োগ করা কঠিন হয়ে পড়েছে (এই প্রসঙ্গে আগে আমি এই শব্দগুলি কখনও শুনিনি)।

এই সমস্ত কথা বলার পরে, এই স্ক্রিপ্টটি "ইনপুট.টেক্সট" নামক একটি পাঠ্য ফাইলে পড়বে যা প্রয়োজনীয় হিসাবে এসকি-ট্যাব রয়েছে এবং গানটি খেলবে।

% সময়জ্ঞান
T = 0.25; % অবশ্যই, এই লাইনটি 't = ইনপুট (' টাইমিং: ') হতে পারে;
        % যদি আপনি যেমন টি উইনকি মান করেন যে টি * 8192 কোনও পূর্ণসংখ্যা নয়, কিছু
        % স্টাফ ব্যর্থ হবে
% ফ্রিকোয়েন্সি এবং অতিরিক্ত ভেরিয়েবলগুলি পরে কিছুটা আলস্যতার অনুমতি দেয়
e = 329.63; ইএন = 1;
বি = 246.94; বিএন = 2;
জি = 196.00; জিএন = 3;
ডি = 146.83; ডিএন = 4;
এ = 110.00; এএন = 5;
ই = 82.41; এন = 6;
% এটি আরও কম্পিউটার বান্ধব উপায়ে গানটি সংরক্ষণ করবে
গান = জিরোস (1,6);
ভি = ফ্রিকোয়েন্সি এবং এফ = ফ্রেট থেকে ফ্রিকোয়েন্সি পেতে% ফাংশন
W = @ (V, চ) বনাম * (2 ^ (চ / 12));
% ইনপুট পান এবং বড় লুপ শুরু করুন
ফাইল = fopen ('ইনপুট.টেক্সট');
লাইন = fgetl (ফাইল);
যখন ইশচার (লাইন)
    লাইনের প্রথম অক্ষরটি আমাদের লাইন ফ্রিকোয়েন্সি দেয়
    lfreqv = eval (লাইন (1)); % ফ্রিকোয়েন্সি
    lfreqN = eval ([লাইন (1), 'এন']); ফ্রিকোয়েন্সি% অনুভূমিক সূচক
    প্রতিটি লাইনের উপরে ছোট লুপটি শুরু করুন
    কে = 3 এর জন্য: (অঙ্ক (লাইন)) - 1
        if (strcmp (line (k), '-')) || (strcmp (লাইন (কে), '|')) || (strcmp (লাইন (কে), 'h')) || (strcmp (লাইন) (ট), 'খ'))
            গান (k-2, lfreqN) = 0;
        আর
            গান (k-2, lfreqN) = ডাব্লু (lfreqv, ডাবল (লাইন (কে)));
        শেষ
    শেষ
    লাইন = fgetl (ফাইল);
শেষ
fclose সাথে (ফাইল);
% এটি গানটি ধরে রাখবে
সুর ​​= [];
ভলস = জিরোস (1,6);
প্লেফ = জিরোস (1,6);
গানের ইন্ডেক্সের জন্য = 1: আকার (গান, 1)
    সিটিউন = [];
    কে = 1: 6 এর জন্য
        যদি গান (songIndex, k) == 0
            ভোলস (কে) = 2 * ভোলস (কে) / 4;
        আর
            ভলস (কে) = 1;
            playf (k) = গান (songIndex, কে);
        শেষ
        ctune (ট, 1: T * 8192) = টি ভল (ট) * পাপ (0.5 * পাই * playf (ট) * (1: (টি * 8192)) / 8192);
    শেষ
    সুর ​​= [টিউন সিটিউন];
শেষ
soundsc (SUM (সুর));

প্রথম পরীক্ষার ইনপুটটির শব্দের একটি লিঙ্ক এখানে।

এখানে তৃতীয় পরীক্ষার ইনপুটটির শব্দটির লিঙ্ক। (স্টার স্পাঙ্গলেড ব্যানার বা আইসক্রিম ট্রাক?)

দ্বিতীয় পরীক্ষার ইনপুটটি আমার কাছে বেশ খারাপ লাগছিল, তবে এটি হতে পারে কারণ এতে প্রচুর পরিমাণে bএবং hস্ক্রিপ্ট ব্যবহার করা হয় যা স্ক্রিপ্ট উপেক্ষা করে।

আপনি শুনতে পাচ্ছেন, আউটপুটটি মূলটির মতো একই মানের নয়। এটি এমন ধরণের শোনাচ্ছে যা পটভূমিতে একটি মেট্রোনম বাজছে। আমি মনে করি এই সুরগুলির চরিত্র আছে।


বাহ, এটি মিউজিক বক্সের মতো শোনাচ্ছে ... সত্যিই দুর্দান্ত!
বিটা ক্ষয়

5

পাইথন ঘ

আমাকে এটি চেষ্টা করে দেখতে হয়েছিল।

এটি একটি ট্যাবকে একটি মিডিয়ো ফাইলে রূপান্তর করে যা পিয়ানোতে খেলে। পিয়ানোতে বাঁকানো স্ট্রিং কীভাবে করবেন তা আমার কোনও ধারণা নেই, সুতরাং এটি এটি করতে পারে না, তবে হাতুড়ি-অন এবং পুল-অফগুলি সোজা are

আমি পরীক্ষার ফাইলগুলি তৈরি করেছিলাম: সেকেন্ডে একক নোটের দৈর্ঘ্য $ python3 tab.py The-weight.txt 0.14কোথায় 0.14

from midiutil.MidiFile3 import MIDIFile
import sys

# Read the relevant lines of the file
lines = []
if len(sys.argv) > 1:
    filename = sys.argv[1]
    try:
        beats_per_minute = 60 / float(sys.argv[2])
    except:
        beats_per_minute = 756
else:
    filename = 'mattys-tune.txt'
    beats_per_minute = 756
with open(filename) as f:
    for line in f:
        if len(line) > 3 and (line[1] == '|' or line[2] == '|'):
            line = line.replace('\n', '')
            lines.append(line)
assert len(lines) % 6 == 0

# Initialize the MIDIFile object (with 1 track)
time = 0
duration = 10
volume = 100
song = MIDIFile(1)
song.addTrackName(0, time, "pianized_guitar_tab.")
song.addTempo(0, time, beats_per_minute)

# The root-pitches of the guitar
guitar = list(reversed([52, 57, 62, 67, 71, 76])) # Assume EADGBe tuning
def add_note(string, fret):
    song.addNote(0, string, guitar[string] + fret, time, duration, volume)

# Process the entire tab
for current in range(0, len(lines), 6):  # The current base string
    for i in range(len(lines[current])): # The position in the current string
        time += 1
        for s in range(6):               # The number of the string
            c = lines[current + s][i]
            try: next_char = lines[current + s][i + 1]
            except: next_char = ''
            if c in '-x\\/bhp':
                # Ignore these characters for now
                continue
            elif c.isdigit():
                # Special case for fret 10 and higher
                if next_char.isdigit():
                    c += next_char
                    lines[current + s] = lines[current + s][:i+1] + '-' + lines[current + s][i+2:]
                # It's a note, play it!
                add_note(s, int(c))
            else:
                # Awww
                time -= 1
                break

# And write it to disk.
def save():
    binfile = open('song.mid', 'wb')
    song.writeFile(binfile)
    binfile.close()
    print('Done')
try:
    save()
except:
    print('Error writing to song.mid, try again.')
    input()
    try:
        save()
    except:
        print('Failed!')

কোডটি গিথুব-এও রয়েছে, https://github.com/Mattias1/ascii-tab , যেখানে আমি ওপি কর্তৃক প্রদত্ত উদাহরণগুলির ফলাফলও আপলোড করেছি। আমি এটি নিজের কয়েকটি ট্যাবেও চেষ্টা করেছি। এটি একটি পিয়ানো বাজানো শুনতে বেশ অদ্ভুত, তবে এটি খারাপ নয়।

উদাহরণ:

আমি কয়েকটি প্রত্যক্ষ লিঙ্ক যুক্ত করেছি, তবে তারা কতক্ষণ থাকেন তা নিশ্চিত নয়, তাই আমি পুরানো ডাউনলোড লিঙ্কগুলিও রেখে দেব।

  1. ওজন , বা খেলুন
  2. টিন স্পিরিটের মতো গন্ধ বা খেলা
  3. স্টার স্প্রিংড ব্যানার , বা খেলুন
  4. ম্যাটির সুর , বা খেলুন
  5. ডিএম টিউন , বা খেলুন

এবং নীচে ম্যাটির টিউনটি থেকে আমার ট্যাবটি (আমার প্রিয়):

    Am/C        Am            F          G             Am/C        Am
e |------------------------|----------------0-------|------------------------|
B |-1--------1--1--------1-|-1--------1--3-----3----|-1--------1--1--------1-|
G |-2-----2-----2-----2----|-2-----2--------------0-|-2-----2-----2-----2----|
D |----2-----------2-------|----2-------------------|----2-----------2-------|
A |-3-----2-----0----------|-------0--------0--2----|-3-----------0----------|
E |-------------------3----|-1-----------3----------|------------------------|

    F        G               Am/C        Am           F           G
e |------------------------|------------------------|----------------0-------|
B |-1--------3-------------|-1--------1--1--------1-|-1--------1--3-----3----|
G |----------4-------------|-2-----2-----2-----2----|-2-----2--------------0-|
D |-------3--5-------------|----2-----------2-------|----2-------------------|
A |----3-----5--------0--2-|-3-----2-----0----------|-------0--------0--2----|
E |-1--------3-----3-------|-------------------3----|-1-----------3----------|

    Am/C        Am           F        G
e |------------------------|------------------------|
B |-1--------1--1--------1-|-1----------3-----------|
G |-2-----2-----2-----2----|------------4-----------|
D |----2-----------2-------|-------3---5------------|
A |-3-----------0----------|----3------5------------|
E |------------------------|-1--------3-------------|

1
ওহো, 756 বিপিএম ?! আমি আশা করি এটি চূড়ান্ত বীট নয় ...
বিটা ডেকে

হাহাহা, আচ্ছা, আমি একটু ঠকাই। 2/3এই 'বিট' আসলে ড্যাশ হয়।
ম্যাটি

ওহ, ম্যাটির সুরটি বেশ দুর্দান্ত লাগছে। এটি গিটারের মতো কী?
বিটা ক্ষয়

1
ধন্যবাদ @ বেটাডেকে, আমি এটি তৈরি করেছি এমন একটি সুর, (বেসলাইন) টমি ইমানুয়েলের নীল চাঁদ দ্বারা অনুপ্রাণিত ( youtube.com/watch?v=v0IY3Ax2PkY )। তবে তিনি কীভাবে এটি করেন তার চেয়ে অর্ধেকটা ভাল লাগে না।
ম্যাটি

4

জাভা স্ক্রিপ্ট

দ্রষ্টব্য: ওয়েব ডেভলপমেন্ট অডিও কিট ব্যবহার করে; এটি আইই লিগের বাইরে যাওয়ার উপায়; গুগল ক্রোমে পরীক্ষিত

আপনি টেক্সারে ট্যাবগুলি রাখতে পারেন। IE আপনি ম্যাটির পোস্টটি ম্যাটির পোস্ট থেকে টেক্সারিয়ায় রেখে দিতে পারেন (নোটগুলির উপরে বর্ণগুলি দিয়ে) এবং এটি এখনও সঠিকভাবে বিশ্লেষণ করবে।

প্রোগ্রাম চালানোর জন্য ক্লিক করুন

javascript:

context = new AudioContext;
gainNode = context.createGain();
gainNode.connect(context.destination);

gain= 2;

function getValue(i) {
    return document.getElementById(i).value;
}

function addValue(i, d) {
    document.getElementById(i).value += d;
}

function setValue(i, d) {
    document.getElementById(i).value = d;
}

document.getElementById("tada").onclick = updateLines;

function updateLines(){
    var e=getValue("ta").replace(/[^-0-9\n]/g,'').replace("\n\n","\n").split("\n");
    for(var l=0;l<e.length;l+=6){
        try{
        addValue("littleE",e[l]);
        addValue("B",e[l+1]);
        addValue("G",e[l+2]);
        addValue("D",e[l+3]);
        addValue("A",e[l+4]);
        addValue("E",e[l+5]);
        }catch(err){}
    }
    updateDash();
}

document.getElementById("littleE").oninput = updateDash;
document.getElementById("B").oninput = updateDash;
document.getElementById("G").oninput = updateDash;
document.getElementById("D").oninput = updateDash;
document.getElementById("A").oninput = updateDash;
document.getElementById("E").oninput = updateDash;


function updateDash() {
    max = 10;
    findDashMax("littleE");
    findDashMax("B");
    findDashMax("G");
    findDashMax("D");
    findDashMax("A");
    findDashMax("E");
    applyMax();
    i = "littleE";
    dash = new Array();
    for (var l = 0; l < getValue(i).length; l++) {
        if (getValue(i).charCodeAt(l) == 45) {
            dash[l] = true;
        } else {
            dash[l] = false;
        }
    }
    /*applyDash("B");
    applyDash("G");
    applyDash("D");
    applyDash("A");
    applyDash("E");*/
}

function findDashMax(i) {
    if (getValue(i).length > max) {
        max = getValue(i).length;
    }
}

function applyMax() {
    if (max < 50) {
        document.getElementById("stepe").size = 50;
        document.getElementById("littleE").size = 50;
        document.getElementById("B").size = 50;
        document.getElementById("G").size = 50;
        document.getElementById("D").size = 50;
        document.getElementById("A").size = 50;
        document.getElementById("E").size = 50;
    } else {
        document.getElementById("stepe").size = max + 1;
        document.getElementById("littleE").size = max + 1;
        document.getElementById("B").size = max + 1;
        document.getElementById("G").size = max + 1;
        document.getElementById("D").size = max + 1;
        document.getElementById("A").size = max + 1;
        document.getElementById("E").size = max + 1;
    }
}

function applyDash(i) {
    var old = getValue(i);
    setValue(i, "");
    for (var l = 0; l < old.length || dash[l] == true; l++) {
        if (dash[l] == true) {
            addValue(i, "-");
        } else {
            if (old.charCodeAt(l) != 45) {
                addValue(i, old.charAt(l));
            }
        }
    }
}
document.getElementById("next").onclick = begin;

function addDash(i) {
    while (getValue(i).length < max) {
        addValue(i, "-");
    }
}

function begin() {
    setValue("littleE",getValue("littleE").replace(/[^-0-9]/g,''));
    setValue("B",getValue("B").replace(/[^-0-9]/g,''));
    setValue("G",getValue("G").replace(/[^-0-9]/g,''));
    setValue("D",getValue("D").replace(/[^-0-9]/g,''));
    setValue("A",getValue("A").replace(/[^-0-9]/g,''));
    setValue("E",getValue("E").replace(/[^-0-9]/g,''));
    addDash("littleE");
    addDash("B");
    addDash("G");
    addDash("D");
    addDash("A");
    addDash("E");
    setValue("next", "Stop");
    //playing = true;
    findLength();
    document.getElementById("next").onclick = function () {
        clearInterval(playingID);
        oscillator["littleE"].stop(0);
        oscillator["B"].stop(0);
        oscillator["G"].stop(0);
        oscillator["D"].stop(0);
        oscillator["A"].stop(0);
        oscillator["E"].stop(0);
        setValue("next", "Play");
        document.getElementById("next").onclick = begin;
    }
    step = -1;
    playingID = setInterval(function () {
        step++;
        setValue("stepe", "");
        for (var l = 0; l < step; l++) {
            addValue("stepe", " ");
        }
        addValue("stepe", "V");
        if (lg[step]) {
            oscillator["littleE"].stop(0);
            oscillator["B"].stop(0);
            oscillator["G"].stop(0);
            oscillator["D"].stop(0);
            oscillator["A"].stop(0);
            oscillator["E"].stop(0);
        }
        qw=0
        doSound("littleE");
        doSound("B");
        doSound("G");
        doSound("D");
        doSound("A");
        doSound("E");

    }, getValue("s") * 1000);
}

function doSound(i) {
    switch (getValue(i).charAt(step)) {
        case ("-"):
        case ("x"):
        case (""):
        case (" "):
            break;
        default:
            qw++;
            makeSound(fretToHz(getHz(i), getValue(i).charAt(step)), i);

    }
    checkTop();
}

function checkTop(){
    switch(qw){
        case 0:
            break;
        case 1:
            gain=2;
            break;
        case 2:
            gain=1;
            break;
        case 3:
            gain=.5;
            break;
        default:
            gain=.3;
            break;
    }
}

function getHz(i) {
    switch (i) {
        case "littleE":
            return 329.63;
        case "B":
            return 246.94;
        case "G":
            return 196;
        case "D":
            return 146.83;
        case "A":
            return 110;
        case "E":
            return 82.41;
    }
}

function fretToHz(v, f) {
    return v * (Math.pow(2, (f / 12)));
}

/*function getTime() {
    var u = 1;
    while (lg[step + u] == false) {
        u++;
    }
    return u;
}*/

function findLength() {
    lg = new Array();
    for (var h = 0; h < getValue("littleE").length; h++) {
        lg[h] = false;
        fl(h, "littleE");
        fl(h, "B");
        fl(h, "G");
        fl(h, "D");
        fl(h, "A");
        fl(h, "E");
    }
    console.table(lg);
}

function fl(h, i) {
    var l = getValue(i).charAt(h);
    switch (l) {
        case "-":
        case "|":
            break;
        default:
            lg[h] = true;
    }
}

oscillator = new Array();

function makeSound(hz, i) {
    console.log("playing " + hz + " Hz" + i);
    oscillator[i] = context.createOscillator();
    oscillator[i].connect(gainNode);
    oscillator[i].frequency.value = hz;
    oscillator[i].start(0);
}

soundInit("littleE");
soundInit("B");
soundInit("G");
soundInit("D");
soundInit("A");
soundInit("E");

function soundInit(i) {
    makeSound(440, i);
    oscillator[i].stop(0);
}
setInterval(function () {
    gainNode.gain.value = .5 * getValue("v") * gain;
    document.getElementById("q").innerHTML = "Volume:" + Math.round(getValue("v") * 100) + "%";
}, 100);

আপনি এই গানটি সনাক্ত করতে পারেন?


1
এটি এর মতো চরিত্রগুলিতে ক্রাশ হয় | / b h p। কেন কেবল তাদের সাথে প্রতিস্থাপন করার জন্য কিছুটা স্ট্রিং পার্সিং করবেন না -? এটি বেশ ঠিক শোনাবে এবং এটি কাজ করে। (এবং সম্ভবত একটি ইনপুট বাক্স ব্যবহার করে নিউলাইনগুলিতে বিভক্ত। এটি এটিকে খেলতে একটি মজাদার স্ক্রিপ্ট তৈরি করবে।
ম্যাটি

আমি যা করার পরিকল্পনা করছিলাম, আমি কখনই এটির কাছে যাইনি।
গ্রান্ট ডেভিস

আমি সম্মত, প্রতিটি স্ট্রিংয়ের জন্য পৃথক লাইন একটি ব্যথা তবে অন্যথায় ভাল লাগে
বিটা ডেকে

উফ পোস্ট সম্পাদনা করার আগে লগইন করতে ভুলে গেছেন।
অনুদান ডেভিস

আমি টিউনটি চিনতে পারি তবে আমি এটিতে কোনও নাম রাখতে পারি না ... যদিও দুর্দান্ত
লাগছে

2

জাভা

এই প্রোগ্রামটি একটি ট্যাবলেটরে 16-বিট ডাব্লুএইভি ফর্ম্যাটকে রূপান্তর করে।

প্রথমত, আমি ট্যাবল্যাচার পার্সিং কোডের পুরো গুচ্ছটি লিখেছিলাম। আমার পার্সিং পুরোপুরি সঠিক কিনা তা আমি নিশ্চিত নই, তবে আমি মনে করি এটি ঠিক আছে। এছাড়াও, এটি ডেটার জন্য আরও বৈধতা ব্যবহার করতে পারে।

এর পরে, আমি অডিওটি তৈরি করার জন্য কোডটি তৈরি করেছিলাম। প্রতিটি স্ট্রিং পৃথকভাবে উত্পন্ন হয়। প্রোগ্রামটি বর্তমান ফ্রিকোয়েন্সি, প্রশস্ততা এবং পর্বের উপর নজর রাখে। এরপরে এটি আপ-আপ আপেক্ষিক প্রশস্ততাগুলির সাথে ফ্রিকোয়েন্সিটির জন্য 10 ওভারটোন তৈরি করে এবং এগুলি যুক্ত করে। অবশেষে, স্ট্রিংগুলি একত্রিত করা হয় এবং ফলাফলটি স্বাভাবিক হয়। ফলাফলটি ডাব্লুএভি অডিও হিসাবে সংরক্ষণ করা হয়েছে, যা আমি এর অতি-সরল বিন্যাসের জন্য বেছে নিয়েছি (কোনও লাইব্রেরি ব্যবহৃত হয়নি)।

এটি হ্যামারিং ( h) এবং টানাকে (সমর্থন করে ) "সমর্থন করে" pযেহেতু সত্যই তাদের কাছে খুব আলাদা শব্দ করার সময় আমার কাছে ছিল না। ফলাফলটি কিছুটা গিটারের মতো শোনাচ্ছে, যদিও (শ্রুতিতে আমার গিটার বিশ্লেষণ করতে কয়েক ঘন্টা স্পেকট্রাম কাটিয়েছে)।

এছাড়াও, এটি নমন ( b), রিলিজিং ( r) এবং স্লাইডিং ( /এবং \, বিনিময়যোগ্য) সমর্থন করে।xস্ট্রিং নিঃশব্দ হিসাবে প্রয়োগ করা হয়।

আপনি কোডটির শুরুতে কনস্ট্যান্টগুলি টুইট করার চেষ্টা করতে পারেন। বিশেষত হ্রাস silenceRateপ্রায়শই ভাল মানের দিকে পরিচালিত করে।

উদাহরণ ফলাফল

কোড

আমি যে কোনও জাভা শুরুর দিকে সতর্ক করতে চাই: এই কোডটি থেকে কিছু শেখার চেষ্টা করবেন না , এটি ভয়ানকভাবে লেখা। এছাড়াও, এটি দ্রুত এবং ২ টি সেশনে লিখিত হয়েছিল এবং এটি আর কখনও ব্যবহৃত হবে না তাই এটির কোনও মন্তব্য নেই। (পরে কিছু যোগ করুন: পি)

import java.io.*;
import java.util.*;

public class TablatureSong {

    public static final int sampleRate = 44100;

    public static final double silenceRate = .4;

    public static final int harmonies = 10;
    public static final double harmonyMultiplier = 0.3;

    public static final double bendDuration = 0.25;

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("Output file:");
        String outfile = in.nextLine();
        System.out.println("Enter tablature:");
        Tab tab = parseTablature(in);
        System.out.println("Enter tempo:");
        int tempo = in.nextInt();
        in.close();

        int samples = (int) (60.0 / tempo * tab.length * sampleRate);
        double[][] strings = new double[6][];
        for (int i = 0; i < 6; i++) {
            System.out.printf("Generating string %d/6...\n", i + 1);
            strings[i] = generateString(tab.actions.get(i), tempo, samples);
        }

        System.out.println("Combining...");
        double[] combined = new double[samples];
        for (int i = 0; i < samples; i++)
            for (int j = 0; j < 6; j++)
                combined[i] += strings[j][i];

        System.out.println("Normalizing...");
        double max = 0;
        for (int i = 0; i < combined.length; i++)
            max = Math.max(max, combined[i]);
        for (int i = 0; i < combined.length; i++)
            combined[i] = Math.min(1, combined[i] / max);

        System.out.println("Writing file...");
        writeWaveFile(combined, outfile);
        System.out.println("Done");
    }

    private static double[] generateString(List<Action> actions, int tempo, int samples) {
        double[] harmonyPowers = new double[harmonies];
        for (int harmony = 0; harmony < harmonyPowers.length; harmony++) {
            if (Integer.toBinaryString(harmony).replaceAll("[^1]", "").length() == 1)
                harmonyPowers[harmony] = 2 * Math.pow(harmonyMultiplier, harmony);
            else
                harmonyPowers[harmony] = Math.pow(harmonyMultiplier, harmony);
        }
        double actualSilenceRate = Math.pow(silenceRate, 1.0 / sampleRate);

        double[] data = new double[samples];

        double phase = 0.0, amplitude = 0.0;
        double slidePos = 0.0, slideLength = 0.0;
        double startFreq = 0.0, endFreq = 0.0, thisFreq = 440.0;
        double bendModifier = 0.0;
        Iterator<Action> iterator = actions.iterator();
        Action next = iterator.hasNext() ? iterator.next() : new Action(Action.Type.NONE, Integer.MAX_VALUE);

        for (int sample = 0; sample < samples; sample++) {
            while (sample >= toSamples(next.startTime, tempo)) {
                switch (next.type) {
                case NONE:
                    break;
                case NOTE:
                    amplitude = 1.0;
                    startFreq = endFreq = thisFreq = next.value;
                    bendModifier = 0.0;
                    slidePos = 0.0;
                    slideLength = 0;
                    break;
                case BEND:
                    startFreq = addHalfSteps(thisFreq, bendModifier);
                    bendModifier = next.value;
                    slidePos = 0.0;
                    slideLength = toSamples(bendDuration);
                    endFreq = addHalfSteps(thisFreq, bendModifier);
                    break;
                case SLIDE:
                    slidePos = 0.0;
                    slideLength = toSamples(next.endTime - next.startTime, tempo);
                    startFreq = thisFreq;
                    endFreq = thisFreq = next.value;
                    break;
                case MUTE:
                    amplitude = 0.0;
                    break;
                }
                next = iterator.hasNext() ? iterator.next() : new Action(Action.Type.NONE, Integer.MAX_VALUE);
            }

            double currentFreq;
            if (slidePos >= slideLength || slideLength == 0)
                currentFreq = endFreq;
            else
                currentFreq = startFreq + (endFreq - startFreq) * (slidePos / slideLength);

            data[sample] = 0.0;
            for (int harmony = 1; harmony <= harmonyPowers.length; harmony++) {
                double phaseVolume = Math.sin(2 * Math.PI * phase * harmony);
                data[sample] += phaseVolume * harmonyPowers[harmony - 1];
            }

            data[sample] *= amplitude;
            amplitude *= actualSilenceRate;
            phase += currentFreq / sampleRate;
            slidePos++;
        }
        return data;
    }

    private static int toSamples(double seconds) {
        return (int) (sampleRate * seconds);
    }

    private static int toSamples(double beats, int tempo) {
        return (int) (sampleRate * beats * 60.0 / tempo);
    }

    private static void writeWaveFile(double[] data, String outfile) {
        try (OutputStream out = new FileOutputStream(new File(outfile))) {
            out.write(new byte[] { 0x52, 0x49, 0x46, 0x46 }); // Header: "RIFF"
            write32Bit(out, 44 + 2 * data.length, false); // Total size
            out.write(new byte[] { 0x57, 0x41, 0x56, 0x45 }); // Header: "WAVE"
            out.write(new byte[] { 0x66, 0x6d, 0x74, 0x20 }); // Header: "fmt "
            write32Bit(out, 16, false); // Subchunk1Size: 16
            write16Bit(out, 1, false); // Format: 1 (PCM)
            write16Bit(out, 1, false); // Channels: 1
            write32Bit(out, 44100, false); // Sample rate: 44100
            write32Bit(out, 44100 * 1 * 2, false); // Sample rate * channels *
                                                    // bytes per sample
            write16Bit(out, 1 * 2, false); // Channels * bytes per sample
            write16Bit(out, 16, false); // Bits per sample
            out.write(new byte[] { 0x64, 0x61, 0x74, 0x61 }); // Header: "data"
            write32Bit(out, 2 * data.length, false); // Data size
            for (int i = 0; i < data.length; i++) {
                write16Bit(out, (int) (data[i] * Short.MAX_VALUE), false); // Data
            }
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void write16Bit(OutputStream stream, int val, boolean bigEndian) throws IOException {
        int a = (val & 0xFF00) >> 8;
        int b = val & 0xFF;
        if (bigEndian) {
            stream.write(a);
            stream.write(b);
        } else {
            stream.write(b);
            stream.write(a);
        }
    }

    private static void write32Bit(OutputStream stream, int val, boolean bigEndian) throws IOException {
        int a = (val & 0xFF000000) >> 24;
        int b = (val & 0xFF0000) >> 16;
        int c = (val & 0xFF00) >> 8;
        int d = val & 0xFF;
        if (bigEndian) {
            stream.write(a);
            stream.write(b);
            stream.write(c);
            stream.write(d);
        } else {
            stream.write(d);
            stream.write(c);
            stream.write(b);
            stream.write(a);
        }
    }

    private static double[] strings = new double[] { 82.41, 110.00, 146.83, 196.00, 246.94, 329.63 };

    private static Tab parseTablature(Scanner in) {
        String[] lines = new String[6];
        List<List<Action>> result = new ArrayList<>();
        int longest = 0;
        for (int i = 0; i < 6; i++) {
            lines[i] = in.nextLine().trim().substring(2);
            longest = Math.max(longest, lines[i].length());
        }
        int skipped = 0;
        for (int i = 0; i < 6; i++) {
            StringIterator iterator = new StringIterator(lines[i]);
            List<Action> actions = new ArrayList<Action>();
            while (iterator.index() < longest) {
                if (iterator.get() < '0' || iterator.get() > '9') {
                    switch (iterator.get()) {
                    case 'b':
                        actions.add(new Action(Action.Type.BEND, 1, iterator.index(), iterator.index()));
                        iterator.next();
                        break;
                    case 'r':
                        actions.add(new Action(Action.Type.BEND, 0, iterator.index(), iterator.index()));
                        iterator.next();
                        break;
                    case '/':
                    case '\\':
                        int startTime = iterator.index();
                        iterator.findNumber();
                        int endTime = iterator.index();
                        int endFret = iterator.readNumber();
                        actions.add(new Action(Action.Type.SLIDE, addHalfSteps(strings[5 - i], endFret), startTime,
                                endTime));
                        break;
                    case 'x':
                        actions.add(new Action(Action.Type.MUTE, iterator.index()));
                        iterator.next();
                        break;
                    case '|':
                        iterator.skip(1);
                        iterator.next();
                        break;
                    case 'h':
                    case 'p':
                    case '-':
                        iterator.next();
                        break;
                    default:
                        throw new RuntimeException(String.format("Unrecognized character: '%c'", iterator.get()));
                    }
                } else {
                    StringBuilder number = new StringBuilder();
                    int startIndex = iterator.index();
                    while (iterator.get() >= '0' && iterator.get() <= '9') {
                        number.append(iterator.get());
                        iterator.next();
                    }
                    int fret = Integer.parseInt(number.toString());
                    double freq = addHalfSteps(strings[5 - i], fret);
                    actions.add(new Action(Action.Type.NOTE, freq, startIndex, startIndex));
                }
            }
            result.add(actions);
            skipped = iterator.skipped();
        }
        return new Tab(result, longest - skipped);
    }

    private static double addHalfSteps(double freq, double halfSteps) {
        return freq * Math.pow(2, halfSteps / 12.0);
    }

}

class StringIterator {
    private String string;
    private int index, skipped;

    public StringIterator(String string) {
        this.string = string;
        index = 0;
        skipped = 0;
    }

    public boolean hasNext() {
        return index < string.length() - 1;
    }

    public void next() {
        index++;
    }

    public void skip(int length) {
        skipped += length;
    }

    public char get() {
        if (index < string.length())
            return string.charAt(index);
        return '-';
    }

    public int index() {
        return index - skipped;
    }

    public int skipped() {
        return skipped;
    }

    public boolean findNumber() {
        while (hasNext() && (get() < '0' || get() > '9'))
            next();
        return get() >= '0' && get() <= '9';
    }

    public int readNumber() {
        StringBuilder number = new StringBuilder();
        while (get() >= '0' && get() <= '9') {
            number.append(get());
            next();
        }
        return Integer.parseInt(number.toString());
    }
}

class Action {
    public static enum Type {
        NONE, NOTE, BEND, SLIDE, MUTE;
    }

    public Type type;
    public double value;
    public int startTime, endTime;

    public Action(Type type, int time) {
        this(type, time, time);
    }

    public Action(Type type, int startTime, int endTime) {
        this(type, 0, startTime, endTime);
    }

    public Action(Type type, double value, int startTime, int endTime) {
        this.type = type;
        this.value = value;
        this.startTime = startTime;
        this.endTime = endTime;
    }
}

class Tab {
    public List<List<Action>> actions;
    public int length;

    public Tab(List<List<Action>> actions, int length) {
        this.actions = actions;
        this.length = length;
    }
}

আমি জানি যে আমি এটি নির্দিষ্ট করে নেই, তবে আপনি কি কিছু পরীক্ষার পোস্টগুলি পোস্ট করতে পারেন যা লোকেদের উত্তরগুলিতে পছন্দ করতে পারে?
বিটা ক্ষয়

@ বেটাডে আমার উত্তর আপডেট করেছেন, এখন একগুচ্ছ পরীক্ষাগুলি রয়েছে
পূর্কাকাডারী

এই লিঙ্কগুলি কার্যকর হয় না: /
বিটা ডিকায়

@ বেটাডেকে আমি যে ব্রাউজারটি ব্যবহার করি না তার ছদ্মবেশী মোডে আমি অন্য সংযোগটিতে ডাবল চেক করেছি। তারা আমার পক্ষে কমপক্ষে কাজ করে।
পুরক্কা কুডারী

ভাল, আমি আপনার ম্যাটিসের সংস্করণটি অনেক পছন্দ করি, যদিও বেসটি শুনতে কখনও কখনও শক্ত হয়।
ম্যাটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.