2009-04-03 51 views
11

Không ai biết bất kỳ điều gì tồn tại trong thế giới Java để ánh xạ các số ghi chú giữa đến các tên ghi chú cụ thể và số quãng tám. Ví dụ, xem bảng tham khảo:Chuyển đổi số ghi chú Midi thành Tên và Octave

http://www.harmony-central.com/MIDI/Doc/table2.html

Tôi muốn ánh xạ một số midi note 60 đến tên của nó lưu ý tương ứng (MiddleC) trong quãng tám 4. Tôi có thể viết một lớp tiện ích/enum cho điều này, nhưng nó sẽ khá tẻ nhạt. Có ai biết gì không?

Tôi đặc biệt sử dụng này để viết một bản sao Tenori-On/Monome trong Java, vì vậy đến nay rất tốt ...

Giải pháp

Đây là những gì tôi đã kết thúc bằng:

String[] noteString = new String[] { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; 

int octave = (initialNote/12) - 1; 
int noteIndex = (initialNote % 12); 
String note = noteString[noteIndex]; 
+0

Jon, tôi đã thêm một số Java thực vào câu trả lời của mình. – paxdiablo

+0

tuyệt vời, cảm ơn cho các con trỏ ... – Jon

Trả lời

11

Tôi không thuyết phục đề xuất của bạn là rằng tẻ nhạt. Nó thực sự chỉ là một hoạt động chia-và-modulo, một người nhận được quãng tám, người còn lại nhận được ghi chú.

octave = int (notenum/12) - 1; 
note = substring("C C#D D#E F F#G G#A A#B ",(notenum % 12) * 2, 2); 

Trong Java thật, như trái ngược với pseudo-code trên, bạn có thể sử dụng một cái gì đó như:

public class Notes { 
    public static void main(String [] args) { 
    String notes = "C C#D D#E F F#G G#A A#B "; 
    int octv; 
    String nt; 
    for (int noteNum = 0; noteNum < 128; noteNum++) { 
     octv = noteNum/12 - 1; 
     nt = notes.substring((noteNum % 12) * 2, (noteNum % 12) * 2 + 2); 
     System.out.println("Note # " + noteNum + " = octave " + octv + ", note " + nt); 
    } 
    } 
} 
+0

Có lẽ Jon đang nghĩ đến việc tạo ra một enum cho mỗi sự kết hợp note + octave đơn lẻ? – Smashery

+0

Đó là gợi ý điên rồ ban đầu. Tôi đã tìm kiếm các thuật toán ... Tôi chắc chắn rằng tôi có thể làm việc một cái gì đó cho điều này, tôi không nghĩ rằng nó hợp lệ trong Java ... không nên mất nhiều thời gian để dịch ... – Jon

+0

Ngoài ra, có lẽ người ta có thể hy vọng cho một com nội tại. .Midi, rằng "tàu" với Java, có chứa một phương pháp như vậy. Tuy nhiên, nó vẫn sẽ không được giải quyết cho dù để gọi một lưu ý (61?) C# hoặc Db. Nếu một người có một chữ ký quan trọng, người ta có thể giải quyết điều đó (đối với nhiều trường hợp) theo chữ ký chính. Tức là, đối với khóa của B, nó sẽ b C#. Đối với khóa của Gb nó sẽ là Db. –

2

Trong JFugue, lớp Note có một phương pháp hữu ích mà không chính xác này - xem public static String getStringForNote(byte noteValue) .

EDIT: Tính đến JFugue 5.0 và sau đó, lớp Note có một số phương pháp hữu ích để có được một chuỗi đại diện từ một giá trị MIDI lưu ý:

  • getToneString(byte noteValue) chuyển đổi một giá trị của 60 vào chuỗi C5
  • getToneStringWithoutOctave(byte noteValue) chuyển đổi một giá trị của 60 vào chuỗi C
  • getPercussionString(byte noteValue) chuyển đổi một giá trị của 60 vào chuỗi "[AGOGO]"

Những thay bản gốc getStringForNote() phương pháp.

+0

Thú vị. Có vẻ như jFugue 5 không còn có 'org.jfugue.Note' nữa. Nó có 'org.jfugue.theory.Note' nhưng nó xuất hiện không có phương thức' getStringForNote'.Không chắc chắn lý do tại sao mọi người quyết định lấy đi chức năng hữu ích (đặc biệt là vì chi phí không cao) mặc dù có thể họ đang di chuyển đến nơi khác, không phải là tôi có thể tìm thấy nó :-) – paxdiablo

+0

Thực ra, Lớp lưu ý có nhiều chức năng tiện ích hơn phiên bản cũ hơn. GetStringForNote mới là getToneString (byte noteValue) - với giá trị là 60, điều này sẽ trả về "C5". Bây giờ cũng có getToneStringWithoutOctave (byte noteValue), sẽ trả về "C" cho 60. Bạn cũng có thể tìm thấy getPercussionString (byte noteValue), trong đó 60 sẽ trả về "[AGOGO]". Các phương pháp mới giàu hơn bản gốc, và yêu cầu tên hàm mới để làm rõ mục đích của chúng. –

Các vấn đề liên quan