Tôi đã không thực hiện bất kỳ chương trình MIDI nào trong nhiều năm, nhưng ý tưởng cơ bản của bạn là rất hợp lý (không chơi chữ).
MIDI là một dòng "sự kiện" (hoặc "tin nhắn"), hai trong số những điều cơ bản nhất là "ghi chú trên" và "ghi chú tắt" mang theo số ghi chú (0 = C năm quãng tám dưới giữa C, đến 127 = G năm quãng tám trên G trên giữa C, trong bán âm). Những sự kiện này mang số "vận tốc" trên bàn phím nhạy cảm với vận tốc ("nhạy cảm với cảm ứng"), với một lực (bạn đoán nó) trong khoảng từ 0 đến 127.
Giữa vận tốc, từ ngữ và bàn đạp, tôi nghĩ bạn có thể tạo ra một giao diện "gõ" khá tốt cho bàn phím piano. Nói riêng, từ ngữ có thể là một kỹ thuật rất mạnh mẽ - như tôi đã đề cập trong các bình luận, đó là lý do tại sao các nhà viết tốc ký xếp hạng và tập tin có thể sử dụng một máy in khuôn mẫu để theo kịp những người nói chuyện hàng giờ liền, khi mà ngay cả những người đánh máy hàng đầu cũng không không thể kéo dài thời gian thông qua bàn phím kiểu chữ thông thường. Cũng như viết tốc ký máy, bạn cần có một "từ điển" về ý nghĩa của hợp âm và chuỗi hợp âm. (Bạn có thể nói tôi đã từng làm việc trong phần mềm của tốc độ máy không?)
Để làm điều này, các phần cơ bản là:
- Nhận đầu vào MIDI. Đừng cố gắng tự làm điều này, hãy sử dụng một thư viện. Chỉnh sửa : Rõ ràng, API âm thanh Java hỗ trợ MIDI , bao gồm nhận các sự kiện từ bộ điều khiển MIDI. Mát mẻ. Trang này cũng có thể hữu ích.
- Chuyển đổi dữ liệu đó thành tổ hợp phím bạn muốn gửi, ví dụ như qua từ điển tôi đã đề cập ở trên.
- Xuất các tổ hợp phím cho máy tính.
Để tương thích rộng rãi nhất với phần mềm, bạn phải viết phần này dưới dạng trình điều khiển thiết bị bàn phím. Đây là một bổ trợ cho hệ điều hành đóng vai trò là nguồn cho các sự kiện bàn phím, nói chuyện với phần cứng bên dưới (trong trường hợp của bạn là bàn phím piano). Đối với Windows và Linux, có lẽ bạn sẽ muốn sử dụng C cho điều đó.
Tuy nhiên, vì bạn chỉ tạo ra tổ hợp phím (không cố gắng chặn chúng, điều mà tôi đã cố gắng thực hiện nhiều năm trước), bạn có thể sử dụng bất kỳ tính năng nào mà hệ điều hành có để gửi tổ hợp phím nhân tạo. Windows có một giao diện để thực hiện điều đó (có thể là một số giao diện mà tôi đang nghĩ đến SendInput
nhưng tôi biết có một giao diện "nhật ký" nào đó tương tự) và tôi chắc chắn các hệ điều hành khác cũng làm như vậy. Điều đó có thể đủ cho mục đích của bạn - đó là nơi tôi bắt đầu, vì tuyến đường trình điều khiển thiết bị sẽ trở nên khó xử và có lẽ bạn phải sử dụng một ngôn ngữ khác cho ngôn ngữ đó so với Java. (Tôi là một fan hâm mộ lớn của Java, nhưng các giao diện mà các hệ điều hành sử dụng để nói chuyện với trình điều khiển thiết bị có xu hướng dễ dàng sử dụng hơn thông qua C và tương tự.)
Cập nhật : Thông tin thêm về "từ điển" của hợp âm cho tổ hợp phím:
Về cơ bản, từ điển là một Trie (nhờ, @ Adam) mà chúng ta tìm kiếm với kết hợp dài nhất-prefix. Chi tiết:
Trong viết tốc ký máy, người viết tốc ký viết bằng cách nhấn nhiều phím trên máy in khuôn mẫu cùng một lúc, sau đó phát hành tất cả. Họ gọi đây là "đột quỵ" của bàn phím; nó giống như chơi một hợp âm trên piano. Các nét thường xuyên (nhưng không phải luôn luôn) tương ứng với một âm tiết của ngôn ngữ nói. Giống như âm tiết, đôi khi một nét (hợp âm) có ý nghĩa riêng, đôi khi nó chỉ có ý nghĩa kết hợp với các nét sau. (Hãy nghĩ "tốt" so với "tốt" theo sau là "tạm biệt"). Mặc dù họ sẽ bị ảnh hưởng nặng nề bởi ngôi trường nơi họ theo học, mỗi người viết tốc ký sẽ có "từ điển" của riêng họ về những nét mà họ sử dụng để nói về điều gì, một cuốn từ điển họ sẽ tiếp tục trong suốt cuộc đời làm việc của họ. Từ điển sẽ có các mục trong đó phần viết tắt ("steno", viết tắt) là một nét dài hoặc nhiều nét dài. Thông thường, sẽ có một vài mục có cùng một nét bắt đầu được phân biệt bởi độ dài của chúng và bởi các nét tiếp theo. Chẳng hạn (và tôi sẽ không sử dụng steno thật ở đây, chỉ là giữ chỗ), có thể có những mục sau:
A = alpha
A / B = bảng chữ cái
A / B / C = chữ cái
A / C = máy lạnh
B = ong
B / C = vì
C = biển
D = chó
D / D = Dee Dee
(Những chữ cái đó không có nghĩa là những nốt nhạc, chỉ là những dấu hiệu trừu tượng.)
Lưu ý rằng A
bắt đầu nhiều mục và cũng lưu ý rằng cách bạn dịch C
đột quỵ tùy thuộc vào việc trước đây bạn đã thấy một A
, a B
hoặc bạn đang bắt đầu mới.
Cũng lưu ý rằng (mặc dù không được hiển thị trong mẫu rất nhỏ ở trên), có thể có nhiều cách để "chơi" cùng một từ hoặc cụm từ, thay vì chỉ một. Người viết tốc ký làm điều đó để dễ dàng chuyển từ từ trước sang từ tiếp theo tùy theo vị trí tay. Có một sự tương đồng rõ ràng với âm nhạc ở đó, và bạn có thể sử dụng nó để làm cho việc gõ phím của bạn giống với việc phát nhạc hơn, để ngăn chặn điều này ảnh hưởng tiêu cực đến việc chơi piano của bạn và tối đa hóa khả năng điều này thực sự giúp ích cho RSI.
Khi dịch steno thành văn bản tiêu chuẩn, một lần nữa chúng ta sử dụng tìm kiếm "khớp tiền tố dài nhất": Thuật toán dịch bắt đầu bằng nét đầu tiên được viết và tìm kiếm các mục bắt đầu bằng nét đó. Nếu chỉ có một mục nhập và dài một nét, thì chúng ta có thể nói một cách đáng tin cậy "đó là mục nhập để sử dụng", xuất văn bản tương ứng và sau đó bắt đầu làm mới với nét tiếp theo. Nhưng nhiều khả năng, đột quỵ đó bắt đầu nhiều mục có độ dài khác nhau. Vì vậy, chúng tôi xem xét các nét tiếp theo và xem nếu có các mục bắt đầu với hai nét đó theo thứ tự; và cứ như vậy cho đến khi chúng tôi có được một trận đấu.
Vì vậy, với từ điển ở trên, giả sử chúng ta đã thấy trình tự này:
Ngân hàng ACBBCABCABD
Đây là cách chúng tôi dịch nó:
A
là sự khởi đầu của ba mục có độ dài khác nhau; nhìn vào đột quỵ tiếp theo:C
A/C
chỉ khớp với một mục; đầu ra "điều hòa không khí" và bắt đầu làm mới với cú đánh tiếp theo:B
B
bắt đầu hai mục; nhìn vào đột quỵ tiếp theo:B
B/B
không bắt đầu bất cứ điều gì; lấy trận đấu dài nhất trước đó ( B
) và xuất ra ("con ong")
- Có đầu ra
B
= "con ong", chúng ta vẫn có một B
nét trong bộ đệm. Nó bắt đầu hai mục, vì vậy hãy nhìn vào nét tiếp theo:C
B/C
phù hợp với một mục; xuất "bởi vì" và bắt đầu mới với đột quỵ tiếp theo:A
A
bắt đầu ba mục; nhìn vào cú đánh tiếp theo:B
A/B
bắt đầu hai mục; nhìn vào cú đánh tiếp theo:C
A/B/C
chỉ phù hợp với một mục; xuất "alphabetic" và bắt đầu làm mới với nét tiếp theo:A
A
bắt đầu ba mục; nhìn vào đột quỵ tiếp theo:B
A/B
bắt đầu hai mục; nhìn vào đột quỵ tiếp theo:D
A/B/D
không khớp với bất cứ thứ gì, vì vậy hãy lấy kết quả khớp dài nhất trước đó ( A/B
) và sử dụng nó để xuất "bảng chữ cái". Điều đó khiến chúng ta D
vẫn còn trong bộ đệm.
D
bắt đầu hai mục, vì vậy chúng ta thường nhìn vào nét tiếp theo - nhưng chúng ta đã xử lý tất cả các nét, vì vậy hãy xem xét nó một cách cô lập. Trong sự cô lập, nó dịch là "con chó" vì vậy đầu ra mà.
Các khía cạnh trên cần lưu ý:
- Bạn có một bộ đệm các nét bạn đã đọc nhưng chưa được dịch.
- Bạn luôn muốn khớp nhiều nét nhất với một mục mà bạn có thể.
A/B
nên được dịch là "bảng chữ cái", không phải "alpha" và "ong".
- (Không được hiển thị ở trên) Bạn cũng có thể có các chuỗi các nét mà bạn không thể dịch, vì chúng không khớp với bất cứ thứ gì trong từ điển. (Người Steno sử dụng danh từ "chưa dịch" - ví dụ, với từ điển của chúng tôi, các nét
E
sẽ là "chưa dịch".)
- (Không được hiển thị ở trên) Một số lý thuyết về steno cho phép cùng một tập hợp các nét có nghĩa nhiều hơn một điều, dựa trên bối cảnh rộng hơn. Người Steno gọi đây là những "xung đột". Bạn có thể muốn không cho phép họ trong dự án của bạn và trên thực tế khi steno được dịch bởi người viết tốc ký, các xung đột vẫn ổn vì họ biết ngay trong câu nào họ là lựa chọn đúng, nhưng với sự gia tăng về dịch máy, các lý thuyết không xung đột về steno nảy sinh đặc biệt để tránh phải thông qua văn bản dịch kết quả và xung đột "sửa chữa".
- Dịch theo thời gian thực (mà bạn đang thực hiện) có nghĩa là nếu bạn nhận được một phần khớp, bạn sẽ muốn giữ nó trong khi chờ hợp âm tiếp theo - nhưng có lẽ chỉ đến một khoảng thời gian chờ, tại thời điểm đó bạn sẽ dịch những gì bạn có trong bộ đệm tốt nhất có thể. (Hoặc có thể bạn không muốn thời gian chờ; đó là cuộc gọi của bạn.)
- Có lẽ tốt nhất để có một đột quỵ nói rằng "bỏ qua các đột quỵ trước"
- Có lẽ tốt nhất để có một đột quỵ nói rằng "hoàn toàn xóa bộ đệm mà không xuất ra bất cứ điều gì"