精华内容
下载资源
问答
  • 以下哪些对象可以添加到库中
    万次阅读 多人点赞
    2019-07-28 16:59:38

    本系列文章主要结合Python语言实现知识图谱构建相关工程,具有一定创新性和实用性,非常希望各位博友交流讨论,相互促进成长。前面两篇文章详细讲解了哈工大Pyltp工具,包括中文分词、词性标注、实体识别、依存句法分析和语义角色标注等。但是其中文分词效果不是很理想,如“贵州财经大学”总是切分成“贵州”、“财经”和“大学”,这是因为词典中这些词的权重较高。这篇文章主要介绍最经典的自然语言处理工具之一——Jieba,包括中文分词、添加自定义词典及词性标注等内容。

    知识图谱系列文章:
    [知识图谱实战篇] 一.数据抓取之Python3抓取JSON格式的电影实体
    [知识图谱实战篇] 二.Json+Seaborn可视化展示电影实体
    [知识图谱实战篇] 三.Python提取JSON数据、HTML+D3构建基本可视化布局
    [知识图谱实战篇] 四.HTML+D3+CSS绘制关系图谱
    [知识图谱实战篇] 五.HTML+D3添加鼠标响应事件显示相关节点及边
    [知识图谱实战篇] 六.HTML+D3实现点击节点显示相关

    更多相关内容
  • Demo3D 模型(链式穿梭车 螺旋提升机 条码扫描 自动码盘模型)
  • JDK5的多线程并发

    2013-03-22 15:00:55
    JDK5的多线程并发
  • Here are the three ways you can add trailers to your movie collection (with their respective benefits and shortcomings): 您可以通过以下三种方式将预告片添加到电影收藏(具有各自的优点和缺点): ...
    预告片下载网站

    预告片下载网站

    If you’re a fan of movie trailers, pre-rolls, and the build up of anticipation leading up to the cinematic experience, then we’ve got a treat for you: Plex Media Server makes it dead simple to recreate that theater magic right at home with both trailers from your own movie collection as well as those of upcoming releases.

    如果您是电影预告片,预告片和对电影体验的期待的忠实拥护者,那么我们为您提供了一种享受:Plex Media Server使重现影院魔力变得非常简单在家中,既有自己电影收藏的预告片,也有即将上映的电影的预告片。

    You may already be aware that Plex supports trailers, but not many people know that you can leverage trailers into something much cooler than something you manually load up now and then. Tucked away in the settings of your Plex Media Server is a neat little bonus feature that can add a little cinema magic and authenticity to your movie night experience. With a little bit of prep work and a few small changes, Plex can do the following things:

    您可能已经知道Plex支持预告片,但是没有多少人知道您可以利用预告片来构建比现在不时手动加载的东西更酷的东西。 Plex Media Server的设置中隐藏了一个巧妙的小奖励功能,可以为您的电影之夜体验增加一点电影魔力和真实性。 通过一些准备工作和一些小的更改,Plex可以执行以下操作:

    • Play trailers for movies from your personal movie collection (including trailers for all movies or just your unwatched films).

      播放个人电影收藏中电影的预告片(包括所有电影或未观看电影的预告片)。
    • Play trailers for new and upcoming theater releases (Plex Pass premium users only).

      播放预告片,用于新的和即将上映的影院(仅限Plex Pass高级用户)。
    • Play trailers for new and upcoming Blu-ray releases (Plex Pass premium users only).

      播放新的和即将发行的Blu-ray的预告片(仅适用于Plex Pass高级用户)。
    • Play a custom video pre-roll (a video clip that will play right before the feature film starts—like the THX loto or an old-timey “Welcome to the movies!” clip).

      播放自定义的视频前片(将在长片开始之前播放的视频剪辑,例如THX乐透或老式的“ Welcome to the movie!”剪辑)。

    By taking advantage of these features, you can get a gentle nudge to check out great movies already in your collection, or see what’s new in theaters and about to come out on Blu-ray. Plus it’ll feel like you’re actually at the movies.

    通过利用这些功能,您可以轻拍一下以查看收藏中已有的精彩电影,或者查看影院中的最新消息以及即将在Blu-ray上推出的消息。 另外,感觉就像您真的在看电影。

    如何下载预告片和预卷 (How to Download Your Trailers and Pre-Roll)

    Of the four potential features we outlined above, there are only two that require you to do any prep work: trailers from your own movie collection and custom movie pre-rolls. Trailers for upcoming theater and Blu-ray releases are downloaded automatically for Plex Pass subscribers and, if that’s all your interested in, you can skip this entire section and jump down to “Enable Trailers, Previews, and Pre-Rolls”.

    在上面概述的四个潜在功能中,只有两个需要您进行任何准备工作:您自己的电影收藏中的预告片和自定义电影中的预卷。 将为Plex Pass订户自动下载即将上映的剧院和Blu-ray发行的预告片,如果您对此感兴趣,则可以跳过整个部分,然后跳至“启用预告片,预览和预卷”。

    Here are the three ways you can add trailers to  your movie collection (with their respective benefits and shortcomings):

    您可以通过以下三种方式将预告片添加到电影收藏中(具有各自的优点和缺点):

    • Manually: Labor intensive, but you get the exact files you want and they are stored locally with the movie file in your media directory.

      手动:劳动密集型,但是您可以获得所需的确切文件,它们与电影文件一起存储在本地媒体目录中。
    • Third Party Media Managers: Automated, and stores trailers with movies. Requires additional software and setup.

      第三方媒体管理器:自动化,并存储带有电影的预告片。 需要其他软件和设置。
    • Third Party Plugins: Automated, but stores trailers hidden away in the Plex database, not in your media directory.

      第三方插件:自动,但是将隐藏的预告片存储在Plex数据库中,而不是在您的媒体目录中。

    If you’re a media purist who wants control over which trailers you have and where they are stored, you’re stuck with the extra work of the first two options. If you just want trailers and couldn’t care less where they’re stored, pick option three and let the plugin do the heavy lifting for you.

    如果您是一位媒体纯粹主义者,希望控制您拥有的预告片以及它们的存储位置,那么前两个选项将使您无所适从。 如果您只想要预告片而又不在乎它们的存储位置,请选择选项三,让该插件为您完成繁重的工作。

    手动添加电影预告片 (Adding Movie Trailers Manually)

    To manually set a trailer for a movie you simply need to download that trailer video from some source and then placing it in the folder where the movie is located, with the filename set to descriptivename-trailer.ext, where “descriptivename” is the a clear description of what the file is and .ext is simply whatever the existing extension of the movie is.

    要手动设置电影的预告片,您只需从某个来源下载该预告片视频,然后将其放置在电影所在的文件夹中,文件名设置为descriptivename-trailer.ext ,其中“ descriptivename”是文件是什么的清晰描述,.ext就是电影的现有扩展名。

    Let’s say we wanted to manually add a trailer to the 2012 cinematic masterpiece, Abraham Lincoln: Vampire Hunter. We have the trailer in MP4 format, so we simply browse to the location of Abraham Lincoln: Vampire Hunter in our collection, paste the downloaded trailer into the directory, and rename it to match the file name of the movie file, like so:

    假设我们想手动向2012年电影巨著《 亚伯拉罕·林肯:吸血鬼猎人》中添加预告片。 我们拥有MP4格式的预告片,因此我们只需浏览到我们收藏中的Abraham Lincoln:Vampire Hunter的位置,将下载的预告片粘贴到目录中,然后将其重命名以匹配电影文件的文件名,如下所示:

    Simply repeat this process for as many movie trailers as you wish to add to your collection.

    只需对要添加到收藏中的尽可能多的电影预告片重复此过程。

    使用媒体管理器添加电影预告片 (Adding Movie Trailers with a Media Manager)

    Manually adding a movie trailer here or there is one thing, but if you want to add trailers to hundreds of movies, that’ll get old really fast. If you want the trailers stored with your movie files but you don’t want to manually download and rename them all, you need to use third party tools like Ember Media Manager or Media Companion.

    在此处手动添加电影预告片或只有一件事,但是如果您想在数百部电影中添加预告片,那将会很快老化。 如果您想将预告片与电影文件一起存储,但又不想手动下载并重命名它们,则需要使用第三方工具,例如Ember Media ManagerMedia Companion

    For our purposes today, we’ll be using Media Companion. The interface is cluttered to the point of being almost overwhelming, but if you know which switches to flip, it makes short work of downloading trailers for even a Library of Congress size collection.

    就我们今天的目的而言,我们将使用Media Companion。 界面杂乱无章,几乎让人难以接受, 但是如果您知道要翻转的开关,那么即使是为国会图书馆的馆藏收藏下载预告片也很容易。

    Once you’ve downloaded and installed Media Companion, launch the application.  First, make sure “Movies” is selected in the control bar (it should be selected by default) and then click on the “Folders” tab in the GUI, located towards the right hand side of the tab list, as seen below:

    下载并安装Media Companion后,启动应用程序。 首先,确保在控制栏中选择了“电影”(默认情况下应选中它),然后单击位于选项卡列表右侧的GUI中的“文件夹”选项卡,如下所示:

    Next, look at the bottom of the Folders tab for the entry “Manually Add path to Movie Root Folder”. Put the full directory path to your movie collection here (e.g. C:\Media\Movies\,  \\homeserver\movies\, or wherever your movies are located). Click “Add”.

    接下来,在“文件夹”选项卡的底部查找“手动向电影根文件夹添加路径”条目。 将完整目录路径放入电影收藏集的此处(例如C:\ Media \ Movies \,\\ homeserver \ movies \或电影所在的任何位置)。 点击“添加”。

    Once you’ve added the directory, Media Companion will scan the folder and populate the file browser. Go to the file browser now by selecting the first tab “Main Browser”. You’ll see a list of movies on the left-hand side. Let’s download the trailer for a single movie now to demonstrate the process. Select a movie and right click on it.

    添加目录后,Media Companion将扫描该文件夹并填充文件浏览器。 现在通过选择第一个标签“ Main Browser”进入文件浏览器。 您会在左侧看到电影列表。 现在,我们为一部电影下载预告片以演示该过程。 选择电影,然后右键单击它。

    In the right-click context menu, you have two tasks. First, head to Rescrape Specific > Trailer. This will scrape IMDB for the URL of the movie trailer and save it to the Media Companion database. Second, return to that same sub-menu and choose Rescrape Specific > Download Trailer. This will instruct Media Companion to follow that URL and download the trailer to the matching movie directory.

    在右键单击上下文菜单中,您有两个任务。 首先,转到“重新抓取特定对象”>“预告片”。 这将为影片预告片的URL刮取IMDB并将其保存到Media Companion数据库。 其次,返回到同一子菜单,然后选择“特定于重新抓取”>“下载预告片”。 这将指示Media Companion遵循该URL,并将预告片下载到匹配的电影目录。

    After you select “Download Trailer”, you’ll see a progress bar and the trailer will be saved to your movie directory in the format moviename-trailer.ext. Confirm, by browsing to the directory, that this has occurred. If everything went smoothly, then all you need to do is return to Media Companion, select all the movies you want to scrape trailers for, and then repeat the same process in bulk with multiple movies selected.

    选择“下载预告片”后,您将看到一个进度条,预告片将以moviename-trailer.ext格式保存到您的电影目录中。 通过浏览到目录确认发生了这种情况。 如果一切顺利,那么您需要做的就是返回Media Companion,选择要为其抓取预告片的所有电影,然后批量选择多个电影,然后重复相同的过程。

    Adding Movie Trailers with a Plugin

    使用插件添加电影预告片

    If you don’t care about where the trailers are stored, using an automatic plugin is definitely the fastest and easiest way to get trailers for your movies. To get started with this method, visit the website for the Trailer Addict Plex plugin (which pulls trailers from the Trailer Addict website) and click the green “Clone or download” button.

    如果您不关心预告片的存储位置,那么使用自动插件无疑是获取电影预告片的最快,最简单的方法。 要开始使用此方法,请访问Trailer Addict Plex插件的网站(可从Trailer Addict网站提取拖车),然后单击绿色的“克隆或下载”按钮。

    Save the resulting .zip file to your computer and open it. Inside you’ll find a folder labeled “TrailerAddict.bundle-master”.  Extract that folder to the plugins directory of your Plex Media Server. The location of the plugin directory varies by operating system:

    将生成的.zip文件保存到计算机并打开。 在其中,您会找到一个标有“ TrailerAddict.bundle-master”的文件夹。 将该文件夹解压缩到Plex Media Server的plugins目录。 插件目录的位置因操作系统而异:

    • Windows: %LOCALAPPDATA%\Plex Media Server\Plug-ins\

      Windows: %LOCALAPPDATA%\ Plex Media Server \插件\

    • macOS: ~/Library/Application Support/Plex Media Server/Plug-ins

      macOS: 〜/ Library / Application Support / Plex Media Server /插件

    • Linux: $PLEX_HOME/Library/Application Support/Plex Media Server/Plug-ins

      Linux: $ PLEX_HOME /库/应用程序支持/ Plex Media Server /插件

    Once you have copied the bundle, rename it to “TrailerAddict.bundle” by removing the “-master” suffix. Restart your Plex Media Server. After you’ve restarted the server, open up the web interface and navigate to settings by clicking on the  and click on the tool icon in the upper right corner.

    复制捆绑软件后,通过删除“ -master”后缀将其重命名为“ TrailerAddict.bundle”。 重新启动Plex Media Server 。 重新启动服务器后,打开Web界面并通过单击并单击右上角的工具图标来导航至设置。

    Select “Server” and then “Agents”.

    选择“服务器”,然后选择“代理”。

    Within the “Movies” tab, select “The Movie Database” and check “Trailer Addict”. Repeat this process for “Plex Movie”. The location of “Trailer Addict” in the list is not important.

    在“电影”选项卡中,选择“电影数据库”并选中“预告片”。 对“ Plex Movie”重复此过程。 列表中“ Trailer Addict”的位置并不重要。

    To get the trailers, you need to refresh your movie library. To do so, return to the main menu of the Plex web interface and click on the menu icon beside your movie library. Select “Refresh All”. If you have multiple movie libraries you want to add trailers to, repeat this process for each of them.

    要获取预告片,您需要刷新电影库。 为此,请返回Plex Web界面的主菜单,然后单击电影库旁边的菜单图标。 选择“全部刷新”。 如果要向其中添加预告片的多个电影库,请对每个预告片重复此过程。

    In the background, the TrailerAddict plugin will download all the trailers for your current movies and, in the future, will automatically add trailers for new movies added to your library. Note that they won’t be stored with your movies, like the above two methods—they’ll be stored in the Plex database somewhere.

    在后台,TrailerAddict插件将下载当前电影的所有预告片,并在将来自动为添加到库中的新电影添加预告片。 请注意,它们不会像上面的两种方法一样与电影一起存储-它们将存储在Plex数据库中的某个位置。

    选择和添加预卷 (Selecting and Adding a Pre-Roll)

    With the trailer situation all squared away, we have one final consideration before we jump into setting it all up: selecting a pre-roll video and adding it to our Plex library. What you use as a pre-roll is totally up to you: as long as it can play in Plex it’s fair game.

    由于预告片的情况全都摆平了,在进入全部设置之前,我们有最后一个考虑:选择前置视频并将其添加到我们的Plex库中。 用作预卷的完全取决于您:只要可以在Plex中播放,它就是公平的游戏。

    If you want a more traditional pre-roll (like the THX sound check), we highly recommend checking out the extensive collection of pre-roll clips at Demo World. With hundreds of high definition clips to choose from, there’s bound to be something that entices you.

    如果您想要更传统的预卷(例如THX声音检查),我们强烈建议您在Demo World上查看大量的预卷片段。 有数百种高清剪辑可供选择,一定会吸引您。

    If you want something a bit more unique, you can always search the web for old drive-in theater pre-rolls, countdowns, or movie theater public announcements and download those instead.

    如果您想获得更多与众不同的内容,则可以始终在网络上搜索旧的露天影院预演,倒计时或电影院公开公告,然后下载这些内容。

    Once you have the clip in hand, it’s time to add it to your Plex Media Server. Rather than dump the file into the same folder where you store your movies, you need to make a separate folder for the pre-roll videos. Where this folder is doesn’t matter as long as it is accessible to the Plex Media Server software and not a subdirectory of an existing folder used by one of your existing Plex libraries. The purpose of this is to avoid confusion and clutter in your primary movie library (where “THX Sound Check” doesn’t need to be its own unique entry beside real movies).

    拥有剪辑后,就可以将其添加到Plex Media Server中了。 您无需将文件转储到存储电影的相同文件夹中,而是需要为前置视频创建一个单独的文件夹。 只要该文件夹可以由Plex Media Server软件访问,而不是由您现有的Plex库之一使用的现有文件夹的子目录访问,则该文件夹的位置无关紧要。 这样做的目的是避免在主电影库中造成混乱和混乱(在“ THX Sound Check”中,除真实电影外,“ THX Sound Check”不需要是其自己的唯一条目)。

    In the web interface, click on the “+” symbol next to “Libraries” in the left-hand navigation column.

    在Web界面中,单击左侧导航栏中“库”旁边的“ +”符号。

    In the library creation wizard, select “Other Videos” and then name the folder “Extras” or something similar. Click “Next”.

    在库创建向导中,选择“其他视频”,然后将文件夹命名为“其他”或类似名称。 点击下一步”。

    Click “Browse for Media Folder” and select your new media folder with the pre-roll video in it. Click “Add Library”.

    单击“浏览媒体文件夹”,然后选择其中包含前置视频的新媒体文件夹。 点击“添加库”。

    Confirm, by selecting your “Extras” library that the video is present.

    通过选择“其他”库来确认存在视频。

    Now that we have our trailers and pre-roll videos in place, it’s time for the easy part: turning everything on.

    现在我们已经准备好了预告片和前贴片视频,现在是时候开始简单了:打开所有内容。

    启用预告片,预览和预卷 (Enable Trailers, Previews, and Pre-Rolls)

    The prep work of actually getting the trailers and/or configuring the plugin was the hard part, we promise! All we need to do now if flip a few toggles inside our Plex Media Server and then turn on  the trailer function in our individual Plex clients.

    我们保证,实际获得预告片和/或配置插件的准备工作是艰巨的工作! 现在,只要在Plex Media Server中进行一些切换,然后打开各个Plex客户端中的预告片功能,我们现在需要做的所有事情。

    在服务器上启用预告片 (Enabling Trailers on the Server)

    To turn on the trailer and pre-roll features, all you need to do is jump into your Plex control panel again, navigate to Settings > Server once more, and select “Extras” left hand navigation bar.

    要打开预告片和预告片功能,您需要做的就是再次跳入Plex控制面板,再次导航至“设置”>“服务器”,然后选择“其他”左侧导航栏。

    There you’ll find the four options (if you don’t see the bottom entry for “pre-roll video” click the “Show Advanced” button near the upper right of the screen control panel).

    在那里,您会找到四个选项(如果您没有看到“前置视频”的底部条目,请单击屏幕控制面板右上方附近的“显示高级”按钮)。

    For the most part, the settings here are very self-explanatory. To control what trailers you see from your personal movie collection, you can check and uncheck “Include Cinema Trailers from movies in my library” and then toggle the “Choose Cinema Trailers” between “Only unwatched movies” and “All movies”.

    在大多数情况下,此处的设置非常不言自明。 要控制从个人电影收藏中看到的预告片,可以选中和取消选中“包括我库中电影的电影预告片”,然后在“仅未观看的电影”和“所有电影”之间切换“选择电影预告片”。

    Plex Pass subscribers can toggle “Include Cinema Trailers from new and upcoming movies in theaters” and “movies on Blu-ray” on to enable those features. New and up-to-date trailers will be streamed each time you launch a movie.

    Plex Pass订户可以启用“包括电影院中新电影和即将上映电影的电影预告片”和“蓝光电影”以启用这些功能。 每次启动电影时,都会流式传输新的和最新的预告片。

    Finally, both standard and Plex Pass subscribers can select a video for the pre-roll. In order to do this you need the URL (from within the Plex Media control center panel) for the detailed view of the the particular video you wish to use. Simply locate that video and click on it to see the detailed view. Copy the URL of that detailed view as it appears in your browser’s address bar, as seen below, and paste it into the “Cinema Trailers pre-roll video” box.

    最后,标准订户和Plex Pass订户都可以选择视频作为预片。 为此,您需要URL(来自Plex Media控制中心面板内)以获取想要使用的特定视频的详细视图。 只需找到该视频,然后单击它即可查看详细视图。 复制该详细视图的URL,如下图所示,它出现在浏览器的地址栏中,然后将其粘贴到“ Cinema Trailers预卷视频”框中。

    Here’s what the Extras menu looks like with all the settings toggled on and the URL in place:

    这是Extras菜单的样子,其中所有设置均已打开且URL已设置:

    With the boxes checked and the pre-roll URL in place, click “Save Changes”. That’s it: we’re done with everything server-side at this point.

    选中相应的复选框,并放置预贴网址,然后点击“保存更改”。 就是这样:现在,我们已经完成了服务器端的所有工作。

    在Plex客户端上启用预告片 (Enabling Trailers on Your Plex Clients)

    The absolute final step of the whole process is to tell your Plex clients to load the trailers (and how many you want loaded). While we were initially annoyed at this extra step, we actually appreciate it now: it gives you granular control over which of your Plex clients will load the trailers, which won’t, and how many trailers they’ll load. You may, for example, want the Plex client in your home theater to always play five trailers. You might not want Plex for Windows, installed on your laptop, to play any trailers at all though, because you don’t want to deal with the buffering and waiting while you’re using your laptop to watch movies on a business trip.

    整个过程的绝对最后一步是告诉您的Plex客户端加载预告片(以及要加载的预告片数量)。 当我们最初对这个额外的步骤感到烦恼时,我们现在实际上很感激:它使您可以精确控制哪些Plex客户端将加载预告片,哪些将不加载,以及将加载多少个预告片。 例如,您可能希望家庭影院中的Plex客户端始终播放五个预告片。 您可能根本不希望笔记本电脑上安装的Windows版Plex完全播放任何预告片,因为您不想在使用笔记本电脑出差看电影时处理缓冲和等待。

    To enable the trailers on the client side, you just have to pop into the settings menu. While the location of the setting varies slightly (it’s under Preferences > Playback > Extras in Plex Home Theater, for example, but Settings > Media in Plex for Windows), it’ll always look more or less like the screenshot below when you find it:

    要在客户端启用预告片,您只需弹出设置菜单。 尽管设置的位置略有不同(例如,位于Plex Home Theater中的“偏好设置”>“播放”>“其他”下,但是位于Windows的Plex中为“设置”>“媒体”下),但找到它时,它看起来总是与下面的屏幕截图差不多:

    Just select between 0-5, start a movie from your library, and boom:

    只需在0-5之间选择,从图库中开始播放电影,然后开始播放即可:

    That familiar green ratings screen pops up, a trailer starts playing, and it feels like you’re sitting in a cinema proper, anticipating the movie to come.

    熟悉的绿色分级屏幕弹出,预告片开始播放,感觉就像您坐在电影院里一样,正期待着电影的来临。

    翻译自: https://www.howtogeek.com/305607/how-to-add-trailers-to-your-plex-movies-for-a-true-movie-theater-experience/

    预告片下载网站

    展开全文
  • JFugue4.0 中文说明

    千次阅读 2020-09-18 18:24:15
    Jfugue 可以简单并且允许工程师去快速创建音乐的原因是 MusicString,一个特殊格式描述音乐的字符串对象。 例如,播放 C(哆) 音符,可以使用如下简单的程序 Player player = new Player(); player.play("C"); ...

    简介

    由音符、八度、音长、音色(乐器,默认乐器为钢琴)组成
    和弦、连音、速冻、控制器、键签名

    Jfugue 可以简单并且允许工程师去快速创建音乐的原因是 MusicString,一个特殊格式描述音乐的字符串对象。

    例如,播放 C(哆) 音符,可以使用如下简单的程序

    Player player = new Player(); 
    player.play("C");
    

    JFugue 解析 MusicString 并且创建对象标识每一个音符、乐器等。这些对象将用来生成音乐,并且通过扬声器播放。JFugue MusicString 不区分大小写。接下来的例子将会看到大小一致的样式,虽然 JFugue 不需要解析这种特定样式即可正确解析 MusicString,但尽可能让 MusicString 可读。

    学习部分 MusicString

    例子

     Player player = new Player(); 
     player.play("C"); 
     player.play("C7h"); 
     player.play("C5maj7w"); 
     player.play("G5h+B5h+C6q_D6q"); 
     player.play("G5q G5q F5q E5q D5h"); 
     player.play("T[Allegro] V0 I0 G6q A5q V1 A5q G6q"); 
     player.play("V0 Cmajw V1 I[Flute] G4q E4q C4q E4q"); 
     player.play("T120 V0 I[Piano] G5q G5q V9 [Hand_Clap]q Rq");
    

    每个通过空格分来的一个或多个字符,被称为一个 Token,一个token 代表一个音符、和弦或停顿;一个一起改变;一个声音或者层的改变;一个速度指示;一个控制事件;一个不变的定义;或者其他,更多的详情在这个章节展开。上面的例子第一个,前四个 MusicString 每个包含一个 Token,并且后面的 MUsicString 每个包含 8 个Token。

    音符、停顿、和弦

    音符和停顿的说明以音符名称或者停顿字符开始,分别是如下
    C(哆), D(来), E(咪), F(发), G(索), A(拉), B(西), or R(停顿)。除了音符说明本身,还可以追加一些 尖、平、八度、音长、和弦等等。

    一个音符也可以用数字表示,这个可用于创建“算法”音乐,每个音符都可以使用数组只而不是字母。一个数字音符将提供描述一个音符 MIDI 值,在方括号中,例如 [60]。八度已经作为因复制的因数,因此在提供音符值的时候不必指定八度(也不可能)。数值不能超过 127

    OctaveCC#/DbDD#/EbEFF#/GbGG#/AbAA#/BbB
    001234567891011
    1121314151617181920212223
    2242526272829303132333435
    3363738394041424344454647
    4484950515253545556575859
    5606162636465666768697070
    6727374757677787980818283
    7848586878889909192939495
    896979899100101102103104105106107
    9108109110111112113114115116117118119
    10120121122123124125126127

    尖、平、自然

    可以使用 # 字符表示尖音,用 b 字符标识平音,#b紧跟字符即可,例如 一个 B-平 可以表示为 Bb,JFugue 也支持 双尖 或者 双平 分别使用 ##bb 表示。

    如果使用 键值标识(Key Signatures),你可以表示一个自然的音符通过在音符后使用 n,例如 B-自然 可以表示为 Bn。如果没有指明 B 为一个自然的,JFugue将自动改变音符的只基于键值标识(如果键值为 F-major,那么 B 将自动被覆盖通过 B-平)。后续将对 键值标识丛详细阐述。

    八度

    默认 音符 5,和弦 3
    允许给音符指定八度,使用 0-10 之间的数字表示。例如 C6 播放一个 C 音节在第六八度。如果没有八度说明,默认一个音节为第五八度,并且默认一个和弦第三八度。

    在这里插入图片描述

    和弦

    表示和弦需要先指定和弦的跟,JFugue支持多种和弦,下标中有详细描述

    表格中的间隔表示和弦音符,例如,一个大和弦包含三个音符,用 0,4,7表示,这里定义的和弦是由跟(0),跟家四个半步(4)和跟加七个半步(7)组成。然而一个 C-majo 和弦是有音符 C,E,G 组成。
    在这里插入图片描述

    在 MusicString 中指明和弦,提供一个跟音符紧跟着通过上表中“JFugue Name”。例如 播放一个 C-major 和弦在默认八度中,可以使用 C-major MusicString,这个等效于 C+E+C,JFugue 会根据指定的和弦去填充对应的音符。回想一下,和弦的默认八度是第三个八度,它低于单个音符的默认五度。

    若要指定带有和弦的八度,请在和弦根后面跟随八度数。例如,E-flat,6th,major 和弦 可以使用 Eb6maj。记住八度音阶放置位置的一种简单方法是,八度音阶更详细地描述了根音,因此它应该在根音旁。如果和弦名称后面有一个数字,则该数字与和弦本身相关联:例如,Cmaj7 描述的是C大调第七和弦,而不是七八度音阶的C大和弦。

    和弦反转

    和弦反转是演奏和弦音符的另一种方法,通过改变和弦中的那个音作为根音。有时候将其称为“和弦发声”。

    第一次倒置表示和弦的常规根音应上移八度,使和弦中的第二个音符成为新的低音音符。第二个倒置表示和弦的根音和第二个音符应高八度,使和弦的第三个音符成为新的贝斯音符。具有三个以上成员的和弦可以进行第三次反转,具有四个以上成员的和弦可以进行四个反转,依此类推。和弦反转的例子如下图

    在这里插入图片描述

    和弦反转也可以明确的指出将要成为新低音音符的音符来描述。可能在分页乐谱中看到 C/E 和弦。 C-Major 表示用E音符作为基础音符。

    有两种方法可以再 JFugue 中指定和弦反转。第一个与指示和弦的第一,第二,第三等倒置一致。如上街所述,指出和弦(例如 Cmaj 为 CMajor)然后再每个反转音符后加入 ^。如上图所示,第一次反转变成Cmaj^,第二次反转变成Cmaj^^。带有更多音符的和弦可能会进行其他反转。

    第二种方法与指示和弦的新低音音符一致,请按照上一节中的指示说出和弦(对于C-Major,为Cmaj),然后使用尖号字符^,后跟新的低音音符。例如将 E 作为新的低音音符的 C-Major 反转将为 Cmaj^E,将 G 作为新的低音音符的 C-Major 反转将为 Cmaj^G

    音长

    默认为 四分(q

    音长表示音符将播放多长时间,它放置在八度音阶之后(如果指定了和弦,则放置在和弦之后),或紧接在音符本身之后(如果省略了八度)或将音符指定为值。音长可由下面字母之一表示,如果未指定工期,将使用默认的四分。

    DurationCharacter
    wholew
    halfh
    quarterq
    eighthi
    sixteenths
    thirty-secondt
    sixty-fourthx
    one-twenty-eightho

    例如,一个 C6 音符,半分音长即为 C6h。一个 D-flat major 音符, 全音长即为 DbmajW.

    点线的音长可以使用音长后使用.字符来指定。带点的半音使用 h 后面加英文句号h.来表示。一个点表示原始持续时间的 1.5 倍。半分加线等于四分之半分加四分。

    持续时间可以彼此附加以创建较长持续时间的音符。这类似音乐中的一个 “tie”,例如播放 D6 三个节拍,可以使用 D6www

    持续时间也可以通过数字指定。这种情况下,提供等于整个音符部分的十进制。要表示数字持续时间,请使用斜杠字符,后跟一个十进制值。例如播放 A4 音符四分音长,可以使用 A4/0.25。1.0 表示整个时间,小数位数大于 1.0 表示音符跨多个小节。例如 上面给出的例子 D6www 等价于 D6/3.0。使用数字作为音长可能对”算法“ 音乐有用处。它们也会在JFugue解析MIDI文件时生成MusicStrings时创建。下面是一些关于音长的例子。

     player.play("Aw"); // A5 whole note 
     player.play("E7h"); // E7 half note
     player.play("[60]wq"); // Middle-C (C5) whole+quarter note
     player.play("G8i."); // G8 dotted-eighth note
     player.play("Bb6/0.5"); // B-flat, 6th octave, half note
    // C-major chord, second inversion, 7th octave, quarter note 
     player.play("C7maj^^q");
    

    三连音和其他连音

    连音是一组音符,音符的音长会被调节,使得该组音符的持续时间与下一个最长的音符音长一致,如下图

    在这里插入图片描述

    三连音是连音一种特殊形式,该组有是哪个音符。三连音是最常见的连音符,其他连音符也可能存在(在音乐理论和 JFugue中)。三连音,三个音符以接下来最大的音长相同的方式演奏。这事一个 3:2 三连音。一个三连音组成四分音符,正如上图所属,这意味着该组音符将在一个半音符中播放,所以每个音符将在正常音长的 2/3 中播放。

    例如更多音符 - ,一个五重奏,包括五个音符,如果他们是一个 5:4 连音,那么五个四分音符将播放在同样的音长中作为整个音符 每个音符将播放正常四分音长的 4/5。

    在JFugue中指定连音符,使用型号 *,在连音符的音符持续时间符号后。三连音,这样做就可以了。其他连音,星号后面必须紧跟描述连音的比例,例如 5:4 。每个连音在音符中都必须有连音符号,并且连音符的每个比例都相同(如果不是不会影响解析,只是音乐挺起来回变得很怪)。

    例子,这些行中的每行将以三重奏的形式演奏三个四分音符,四分之三的组的持续时间为四分之三(等于二分音符)

    player.play("Eq* Fq* Gq*"); // These two lines create
    player.play("Eq*3:2 Fq*3:2 Gq*3:2"); // equivalent music
    

    这五个八分音符(五重奏)将在四个八分音符(相同的一半音符)的持续时间内演奏。

    player.play("Ci*5:4 Ei*5:4 Gi*5:4 Ei*5:4 Gi:5*4");
    

    小节(tie)

    在乐谱中,tie 链接两个相同音高的音符。并只是将两个音符作为一个音符演奏,总持续时间等于并列音符的持续时间之和。乐谱中经常使用 tie 来描绘音符,该音符的持续时间跨越两个小节之间的小节线,如下图。tie通产被用来创建音符的持续音长,所以不能用注释代替掉,例如半音符加八分音符。

    在这里插入图片描述

    在 JFugue 破折号 - 备用来表示 tie。对于一个 tie 开始的音符,追加破折号到其音长的结尾。对于在 tie 结尾的音符,将破折号放在持续时间的开头,如果一个音符在一系列连在一起的音符中间,使用两个破折号,持续时间前后都加。使用破折号表示 tie 是否 ”跟随“ 音符的音长,是否”继续“音符的音长, 节点是否在 tie 中,这种情况下,tie 即”跟随“又”继续“持续时间。它将使用”测量“符号(垂直线或者竖线字符 ”|“),如下图
    在这里插入图片描述

    Attack(起) and Decay(落) 速度

    默认 64 attack, 64 decay

    音符可以指定起音及落音速度,这些速度表明音符“预热”到其全部音量需要多长时间,并且从峰值”消散“,例如 一个音符需要一个很长的起音和一个很快的落音,就像建立的时候需要一段时间,很快关闭。长时间发作的音符听起来有些空灵,具有长衰减声的音符像被敲击的铃铛或吉他弦一样,在被敲击后会继续产生共鸣。

    音符的起音和落音可以分别使用字母ad来指定,每个字母后面紧跟数字 0-127,默认为 0。较低的值表示起音或者落音的更快,较高的值表示其更长。起落音可单独使用(如果他们一块出现,需要先指定起音)

    例如,下面这些带有起落速度的音符

    player.play("C5qa0d127"); // Sharp attack, long decay
    player.play("E3wwd0"); // Default attack, sharp decay
    player.play("C7maja30"); // C7, E7, and G7 (components of 
    // C7maj) will all play with an 
    // of attack 30
    

    音符演奏旋律及和声

    这事演奏旋律的音符 -,一个接一个–用空格分隔的单个标记表示。至此,所有MusicStrings示例都显示了旋律演奏的音符。
    如下图所示,
    在这里插入图片描述

    音符也可以与其他音符一起和谐演奏,这可以通过将标记与加号+结合使用来指明而不是空格,如下图所示。当然,和弦中的音符自动和声演奏,+标记可让您和声演奏任何音符。

    在这里插入图片描述

    还会发现在某些情况下要和声地演奏一个音符而两个或多个音符会以旋律演奏。表示在与其他音符和声演奏时应一起演奏的音符,使用下划线字符_连接应一起演奏的音符。C5音符会连续播放,而E5G5音符会依次播放。

    在这里插入图片描述

    和弦和休息音也可以和声或组合演奏使用加号和下划线字符作为连接符的和声/旋律,只有音符,和弦和休止符可以使用+_字符。

    计量

    JFugue MusicStrings的创建旨在使音乐创作变得容易,它们不是为提供代表乐谱的完整语法而开发的。在MusicString中指示小节线|不会影响MusicString的音乐输出。但是,在MusicString中指示小节之间的中断通常很有用。要指示条形线,请使用垂直线(或竖线)字符|,该字符必须与MusicString中的其他标记分隔并带有空格。

    键值标识(Key Signature)

    默认为: C-major

    一个键值标识被用来指明JFugue以特定的键或音阶播放MusicString。指明键值标识,使用字母K,后面紧跟键值的根,然后是 majmin 主要或次要规模。例如 KCbmaj 将被记做键至为 C-flat major.

    JFugue 将自动为受键值标识影响的音符调整音符值。例如,如果设置键值为 F-major,那么播放一个 B 音符在 MusicString 中,JFugure 将自动替换 BB-flat。如果想 B 保持自然形式,必须在每个音符后通过使用自然符号标识n,这种情况,演奏 B 作为自然音符需要令牌 n

    仪器

    默认为 Piano(钢琴)

    JFugue 产生的音乐使用 MIDI 来渲染由 Java Sound 音库中的乐器播放的音频,MIDI 规范描述了128种不同的乐器并且可能支持更多。大多数 MIDI 设备的前128个乐器使用相同的定义,尽管声音的质量因设备和音库而异。例如,MIDI 乐器#0通常代表一架钢琴,但是各种 MIDI 设备渲染的钢琴声音可能不同。

    在 JFugue 的 MusicString 中选择这些乐器,使用工具令牌,它是I字符,后跟0到127之间的工具编号。例如要指定钢琴,可以输入 MusicString I0。或者 JFugue 使用仪器名称定义了可用于指定仪器的常量。这往往更容易阅读和记住,例如 钢琴常熟为 PIANO,因此用于指定钢琴的 MusicString 也可能显示为I[Piano]。也可以定义自己的常量,本章后面将更详细地描述常量。如下表包含仪器编号及 JFugue 常数的列表。某些乐器可能包含多个常熟,可以使用任何一个常数,它们都将解析为相同的仪器编号。一下常量也可以不区分大小写

    idname
    Piano钢琴
    0PIANO or ACOUSTIC_GRAND
    1BRIGHT_ACOUSTIC
    2ELECTRIC_GRAND
    3HONKEY_TONK
    4ELECTRIC_PIANO or ELECTRIC_PIANO1
    5ELECTRIC_PIANO2
    6HARPISCHORD
    7CLAVINET
    Chromatic Percussion打击乐器
    8CELESTA
    9GLOCKENSPIEL
    10MUSIC_BOX
    11VIBRAPHONE
    12MARIMBA
    13XYLOPHONE
    14TUBULAR_BELLS
    15DULCIMER
    Organ
    16DRAWBAR_ORGAN
    17PERCUSSIVE_ORGAN
    18ROCK_ORGAN
    19CHURCH_ORGAN
    20REED_ORGAN
    21ACCORIDAN
    22HARMONICA
    23TANGO_ACCORDIAN
    Guitar吉他
    24GUITAR or NYLON_STRING_GUITAR
    25STEEL_STRING_GUITAR
    26ELECTRIC_JAZZ_GUITAR
    27ELECTRIC_CLEAN_GUITAR
    28ELECTRIC_MUTED_GUITAR
    29OVERDRIVEN_GUITAR
    30DISTORTION_GUITAR
    31GUITAR_HARMONICS
    Bass贝斯
    32ACOUSTIC_BASS
    33ELECTRIC_BASS_FINGER
    34ELECTRIC_BASS_PICK
    35FRETLESS_BASS
    36SLAP_BASS_1
    37SLAP_BASS_2
    38SYNTH_BASS_1
    39SYNTH_BASS_2
    Strings
    40VIOLIN
    41VIOLA
    42CELLO
    43CONTRABASS
    44TREMOLO_STRINGS
    45PIZZICATO_STRINGS
    46ORCHESTRAL_STRINGS
    47TIMPANI
    Ensemble合奏
    48STRING_ENSEMBLE_1
    49STRING_ENSEMBLE_2
    50SYNTH_STRINGS_1
    51SYNTH_STRINGS_2
    52CHOIR_AAHS
    53VOICE_OOHS
    54SYNTH_VOICE
    55ORCHESTRA_HIT
    Brass铜器
    56TRUMPET
    57TROMBONE
    58TUBA
    59MUTED_TRUMPET
    60FRENCH_HORN
    61BRASS_SECTION
    62SYNTHBRASS_1
    63SYNTHBRASS_2
    Reed
    64SOPRANO_SAX
    65ALTO_SAX
    66TENOR_SAX
    67BARITONE_SAX
    68OBOE
    69ENGLISH_HORN
    70BASSOON
    71CLARINET
    Pipe
    72PICCOLO
    73FLUTE
    74RECORDER
    75PAN_FLUTE
    76BLOWN_BOTTLE
    77SKAKUHACHI
    78WHISTLE
    79OCARINA
    Synth Lead
    80LEAD_SQUARE or SQUARE
    81LEAD_SAWTOOTH or SAWTOOTH
    82LEAD_CALLIOPE or CALLIOPE
    83LEAD_CHIFF or CHIFF
    84LEAD_CHARANG or
    CHARANG
    85LEAD_VOICE or VOICE
    86LEAD_FIFTHS or FIFTHS
    87LEAD_BASSLEAD or BASSLEAD
    Synth Pad合成
    88PAD_NEW_AGE or NEW_AGE
    89PAD_WARM or WARM
    90PAD_POLYSYNTH or
    POLYSYNTH塑料
    91PAD_CHOIR or CHOIR
    92PAD_BOWED or BOWED
    93PAD_METALLIC or METALLIC
    94PAD_HALO or HALO
    95PAD_SWEEP or SWEEP
    Synth Effects合成器
    96FX_RAIN OR RAIN
    97FX_SOUNDTRACK or SOUNDTRACK
    98FX_CRYSTAL or CRYSTAL
    99FX_ATMOSPHERE or ATMOSPHERE
    100FX_BRIGHTNESS or BRIGHTNESS
    101FX_GOBLINS or GOBLINS
    102FX_ECHOES or ECHOES
    103FX_SCI-FI or SCI-FI
    Ethnic种族
    104SITAR
    105BANJO
    106SHAMISEN
    107KOTO
    108KALIMBA
    109BAGPIPE
    110FIDDLE
    111SHANAI
    Percussive打击乐器
    112TINKLE_BELL
    113AGOGO
    114STEEL_DRUMS
    115WOODBLOCK
    116TAIKO_DRUM
    117MELODIC_TOM
    118SYNTH_DRUM
    119REVERSE_CYMBAL
    Sound Effects声音特效
    120GUITAR_FRET_NOISE
    121BREATH_NOISE
    122EASHORE
    123BIRD_TWEET
    124TELEPHONE_RING
    125HELICOPTER
    126APPLAUSE
    127GUNSHOT

    音色(Voice)

    音乐通常会分解成多种声音,也称为频道( channels)或曲目(tracks)。每个声音都包含一个旋律,通常会用特定的乐器演奏。例如一个解释音乐,节能有不同的鼓声、萨克管、贝斯、钢琴等。或者在钢琴独奏中,可以为高音谱使用一种声音,为低音谱使用一种声音。

    MIDI支持16个同时通道,JFugue通过音色命令来表示。音色命令是 V,后面紧跟数字 0-15。

    MIDI 允许随意打开或者关闭任意通道来播放音乐,这样就可以专注于音乐的一部分,或听到没有特定声音的歌曲的声音。

    MIDI 打击轨道

    第 10 个 MIDI 通道(即V9)比较特殊,它是唯一能够为非彩色打击乐器产生声音的通道,通常是鼓。在第十通道中,每个音符分配给不同的打击乐器,例如,如果第 10 通道给了 A5 音符,将不会演奏 A5 ,二十播放拨浪鼓的声音。

    JFugue 提供了另一种在 V9 中指定注释的方法,可以更简单的为指定鼓声。可以使用常量来表达乐器,而不是输入 V9 A5q 来代表拨浪鼓。可以使用 V9 [Hi_Bongo]q来替代。代表打击乐声音的常量列表如下表所示:

    Note ValueJFugue Constant
    35ACOUSTIC_BASE_DRUM
    36BASS_DRUM
    37SIDE_KICK
    38ACOUSTIC_SNARE
    39HAND_CLAP
    40ELECTRIC_SNARE
    41LOW_FLOOR_TOM
    42CLOSED_HI_HAT
    43HIGH_FLOOR_TOM
    44PEDAL_HI_TOM
    45LOW_TOM
    46OPEN_HI_HAT
    47LOW_MID_TOM
    48HI_MID_TOM
    49CRASH_CYMBAL_1
    50HIGH_TOM
    51RIDE_CYMBAL_1
    52CHINESE_CYMBAL
    53RIDE_BELL
    54TAMBOURINE
    55SPLASH_CYMBAL
    56COWBELL
    57CRASH_CYMBAL_2
    58VIBRASLAP
    59RIDE_CYMBAL_2
    60HI_BONGO
    61LOW_BONGO
    62MUTE_HI_CONGA
    63OPEN_HI_CONGA
    64LOW_CONGO
    65HIGH_TIMBALE
    66LOW_TIMBALE
    67HIGH_AGOGO
    68LOW_AGOGO
    69CABASA
    70MARACAS
    71SHORT_WHISTLE
    72LONG_WHISTLE
    73SHORT_GUIRO
    74LONG_GUIRO
    75CLAVES
    76HI_WOOD_BLOCK
    77LOW_WOOD_BLOCK
    78MUTE_CUICA
    79OPEN_CUICA
    80MUTE_TRIANGLE
    81OPEN_TRIANGLE

    创建打击乐器的”和弦“跟其他音符的规则一致,例如V9 [Hand_Clap]q+[Crash_Cymbal_1]q 将在四分音长中同时演奏这两种声音

    层(Layer)

    一层提供了一种方法,用于指定要以相同声音播放的单独旋律。层不属于 MIDI 规范的一部分,是 JFugue的特色。引入层是为了客服第十通道 MIDI (演奏打击乐器)的难题。特别要提醒,如果有很多旋律每个旋律都有自己的节奏,很难讲这些组合成声音的”和弦“。使用层,可以轻松的将多种旋律融合起来。

    此外,层也可以用在其他声音中,可以利用它来模拟从 MIDI 系统中同时获取 16 个以上的旋律。它还可以用于同一音轨中发送多个事件,在弹奏音符时改变音高轮,产生对演奏音符的调制。

    类似音色,层用 L 来表示,后面可以跟数字 0-15

    速度(Tempo)

    默认每分钟 120 次,大致为快板

    速度是指一首音乐的播放速度。它通常是 MusicString 中设置的第一件事,因为它适用于跟随节奏命令的所有音乐事件。

    节拍代表每分钟节拍(BPM),在 JFugue 的旧版本中,速度表示“每季度脉冲数”(PPQ),表示要给一个四分音符多少个时钟周期。PPQ 与 BPM 成反比,当然 PPQ 不够直观,因此,JFugue现在支持使用BPM表达速度。幸好,最常见的速度是 120 ,恰好是 PPQ 和 BPM 的等等效值,(120 PPQ = 120 BPM)。

    速度的标识为 T,后面紧跟数字或者使用常量,例如T[Adagio],下表示关于速度的常亮。

    JFugue ConstantBeats Per Minute (BPM)
    Grave40
    Largo45
    Larghetto50
    Lento55
    Adagio60
    Adagietto65
    Andante70
    Andantino80
    Moderato95
    Allegretto110
    Allegro (default)120
    Vivace145
    Presto180
    Pretissimo220

    变音轮(Pitch Wheel)

    音调轮用于将一个点的音调改变百分之一半或几分,变音轮可用于更改单个音符的向下或向上方向的频率 8192 分

    音高转盘可用于在音乐中创建类似 Theremin 的效果。JFugue 还使用变音轮对音符进行正弦调整,使某些东方风格的音乐易于播放。

    用于调节变音轮的命令是 & 后面紧跟数字 0-16383,0-8191 会使音调降低,8193-16383 使音调变高。重置变音轮使其不变,可以使用&8192

    频道压力(Channel Pressure)

    许多MIDI设备都能够对给定通道上播放的所有音符施加“压力”

    频道压力的命令为 + 后面紧跟数字 0-127,它适用于 MusicString 中使用的最新语音令牌指示的频道。

    在通道压力情况下,由于解析方式不同,请勿将此标记与+的使用相混淆以使音符和谐地相连,将+放在开头。

    复音压力(Polyphonic Pressure)

    和弦压力,也称为按键压力,是施加到单个音符的压力。这是比“通道压力”更高级的功能,并且并非所有的MIDI设备都支持它。

    复印压力的命令为 * 其后是键值(即音符值),指定为0到127之间的值,然后是逗号,最后是0到127之间的压力值。

    例如,施加 75 的压力 到 C5 音符上可以使用 *60,75,注意此处的命令不支持音符值,所以使用 *C5,75 会发生错误。

    通道压力与复音压力之间的差异在于,通道压力会同等地应用于给定通道中演奏的所有音符,而和弦压力则分别应用于通道中的每个音符。切记 JFugue 命令在通道压力与复音压力之间的区别的一种方法是,代表通道压力的加号 +代表比星号字符*代表复音压力稍微更简单。

    控制事件(Controller Events)

    MIDI规范定义了大约100个控制器事件,这些事件用于指定控制音乐声音的各种设置。 这些功能包括踏板,左右平衡,滑音(音符彼此滑入),颤音等等。关于完整的文档可以参考 MIDI 规范。

    JFugue 控制命令使用 X

    Xcontroller_number=value 
    X37=18 
    X[Chorus_Level]=64
    

    如果您熟悉MIDI控制器,则可能知道有 14 个同时具有“粗”和“细”设置的控制器。这些控制器实质上具
    有16位数据,而不是其他大多数控制器的典型 8 位(一个字节)。可以通过两种方式指定粗略设置和精细设置。
    第一种方式

     X[Foot_Pedal_Coarse]=10 
     X[Foot_Pedal_Fine]=65
    

    当然,JFugue可以比这好用,对于具有粗略和精细成分的 14 个控制器事件中的任何一个,您可以同时指定两个值:

    X[Foot_Pedal]=1345
    

    想要音量设置为 10200 或者 16383,无需弄清楚10200的高字节和低字节,只需要使用 X[Volume]=10200,JFugue 将值分为高字节和低字节。

    很多控制器具有两个设置 ON/OFF,通常 ON 表示 127,OFF 表示为 0,JF 定义两个常亮 ON/OFF 可以使用常量来代替如 X[Local_Keyboard]=ON。JFugue 默认为 DEFAULT 为 64。可以和 X 一块使用的常亮如下:

    ControllerJFugue-Constant
    0BANK_SELECT_COARSE
    1MOD_WHEEL_COARSE
    2BREATH_COARSE
    4FOOT_PEDAL_COARSE
    5PORTAMENTO_TIME_COARSE
    6DATA_ENTRY_COARSE
    7VOLUME_COARSE
    8BALANCE_COARSE
    10PAN_POSITION_COARSE
    11EXPRESSION_COARSE
    12EFFECT_CONTROL_1_COARSE
    13EFFECT_CONTROL_2_COARSE
    16SLIDER_1
    17SLIDER_2
    18SLIDER_3
    19SLIDER_4
    32BANK_SELECT_FINE
    33MOD_WHEEL_FINE
    34BREATH_FINE
    36FOOT_PEDAL_FINE
    37PORTAMENTO_TIME_FINE
    38DATA_ENTRY_FINE
    39VOLUME_FINE
    40BALANCE_FINE
    42PAN_POSITION_FINE
    43EXPRESSION_FINE
    44EFFECT_CONTROL_1_FINE
    45EFFECT_CONTROL_2_FINE
    64HOLD_PEDAL-or-HOLD
    65PORTAMENTO
    66SUSTENUTO_PEDAL-or-SUSTENUTO
    67SOFT_PEDAL-or-SOFT
    68LEGATO_PEDAL-or-LEGATO
    69HOLD_2_PEDAL-or-HOLD_2
    70SOUND_VARIATION
    71SOUND_TIMBRE
    72SOUND_RELEASE_TIME
    73SOUND_ATTACK_TIME
    74SOUND_BRIGHTNESS
    75SOUND_CONTROL_6
    76SOUND_CONTROL_7
    77SOUND_CONTROL_8
    78SOUND_CONTROL_9
    79SOUND_CONTROL_!10
    80GENERAL_BUTTON_1
    81GENERAL_BUTTON_2
    82GENERAL_BUTTON_3
    83GENERAL_BUTTON_4
    91EFFECTS_LEVEL
    92TREMULO_LEVEL
    93CHORUS_LEVEL
    94CELESTE_LEVEL
    95PHASER_LEVEL
    96DATA_BUTTON_INCREMENT
    97DATA_BUTTON_DECREMENT
    98NON_REGISTERED_COARSE
    99NON_REGISTERED_FINE
    100REGISTERED_COARSE
    101REGISTERED_FINE
    120ALL_SOUND_OFF
    121ALL_CONTROLLERS_OFF
    122LOCAL_KEYBOARD
    123ALL_NOTES_OFF
    124OMNI_MODE_OFF
    125OMNI_MODE_ON
    126MONO_OPERATION
    127POLY_OPERATION

    组合的控制器常数。 可以将整数分配给如下表整数,而JFugue将找出高字节和低字节:

    Combined-ContollerJFugue-Constant
    16383BANK_SELECT
    161MOD_WHEEL
    290BREATH
    548FOOT_PEDAL
    677PORTAMENTO_TIME
    806DATA_ENTRY
    935VOLUME
    1074BALANCE
    1322PAN_POSITION
    1451EXPRESSION
    1580EFFECT_CONTROL_1
    1709EFFECT_CONTROL_2
    12770NON_REGISTERED
    13028REGISTERED

    常数(Constants)

    在编写音乐时,主要任务是有没的旋律,而不是被随机无意义的数字所干扰。设置 VOLUME 并使用FLUTE ,不必记住 VOLUME 是控制器编号 935(或 VOLUME 由粗略值和精细值组成) FLUTE 是乐器编号73。为了使数字有意义,并且易于使用,JFugue 定义了很多常量并在 MustringString 转换成音乐时中解析。

    设置常数命令如下:

    $WORD=DEFINITION
    

    或者 $ELEC_GRAND=2,当然 JFugue 也可以定义 ELECTRIC_GRAND = 2。但是也许您想使用一个较短的名称,或者您可能会为该乐器使用一个更易记的名称,例如 ELEC。当您想引用此特定乐器时,可以在 MusicString 中使用您的简称。

    JFugue为乐器名称,打击乐器,速度和控制器事件之类的东西定义了一堆常数(大约375)。创建这些常量的类是 JFugueDefinitions

    如果需要设置或者更改常量,假设您想用自己喜欢的乐器弹奏一些音乐,您可以将FAV_INST定义为0,然后随时使用I[Fav_Inst]。如果乐器发生了变化,那么在音乐字符串中所要做的就是改变FAV_INST 的定义,不必在引用乐器的每个位置上进行更改。

    可以在需要数字的任何地方使用常数,但八度值除外(因为只将音符本身和八度指定为一个数字),并且使用 一个持续时间常数,您必须使用十进制持续时间值(并在持续时间前加上斜杠/)。

    在 MusicString 中使用常量时,需要将单词放在方括号中。

    时间信息(Timing Information)

    当从乐谱上抄音符时,通过休息和音符持续时间的组合,可以创建音符之间具有适当时间延迟的音乐。但是从 MIDI 文件中读取音乐时,不能保证音符以这种正确的方式相互跟随。因为 JFugue 使用时间令牌来表示序列中播放音符及其他标识的毫秒数。创建音乐时不会用到此功能,但是如果将音乐从 MIDI 转换成 MusicString 时就会用到它。

    时间信息的指令是 & 后面加一个毫秒数。当指令后面有时间信息命令时就需要被播放。

    时间不需要是连续的,完整的 JFugue MusicString 在呈现音乐之前已解析,并且表示任何时间的定时信息将在播放期间的正确时间播放。

    MusicString Style(样式)

    建议遵循以下准则,以帮助您创建易于阅读和共享的 MusicStrings,虽然 MusicString 不区分大小写,但使用大写和小写字符来最大化 MusicString 的可读性。

    1. 使用大写字母表示代表指令的字符:I, V, L, T, X, K(分别指 Voice, Layer, Tempo, Controller, and Key Signature, respectively)
    2. 使用大写作为音符,C, D, E, F, G, A, B, R
    3. 指定和弦时,请使用小写字母:maj, min, aug
    4. 注释持续时间使用小写字母 w, h, q, i, s, t, x, o。如果您持续使用和弦后的持续时间,则在音符持续时间中使用大写字母可能更易读
    5. 使用混合大小写(或者成为驼峰)代表乐器名称,percussion names, tempo names, or controller names 分别是 I[Piano], [Hand_Clap], T[Adagio] , X[Hold_Petal]
    6. 在定义和引用常量时使用全大写加下划线形式$MY_WORD=10
    7. 每个指令间留一个空格,但是如果要写多种声音的音乐,如下所示,将每个声音放在自己的行上并使用空格使音符对齐非常有用。
    8. 使用竖线字符(也称为竖线)|来指示 MusicString 中的小节

    以下是一些符合规范的例子

    Player player = new Player(); 
     // First two measures of "Für Elise", by Ludwig van Beethoven 
     player.play("V0 E5s D#5s | E5s D#5s E5s B4s D5s C5s " + 
    "					V1 Ri             | Riii                                         "); 
     // First a few simple chords 
     player.play("T[Vivace] I[Rock_Organ] Db4minH C5majW C4maj^^");
    

    JFugue 元素:使用对象代替 MusicString

    至此,已经了解如何使用 JFugue 的符号创建 MusicSting,还可以通过创建许多单独的音符对象并将它们添加在一起来构造歌曲,这种方式创建音乐非常繁琐。制作MusicString很容易,让JFugue在幕后创建对象。

    然而,很多情况下需要通过单个实例对象来创建音乐。或者需要构建一个音符的循环,或者需要在编译是才传递具体的乐器类型。

    JFugue 提供了通过实例化一个类并将音乐元素添加到 Pattern 中来创建任何音乐元素的功能。在下一章中,您将学到更多有关Patterns的知识,但与此同时,您需要知道的是Pattern是一种可以由播放器播放的音乐,您可以向其中添加音乐元素。

    下面是创建音乐时可以调用的各种事件,可以使用预定义的常量来表示值,例如 Tempo.ADAGIO或者Instrument.PIANO

    // Create a new Voice instance 
    Voice voice = new Voice(byte voiceValue);
    // Create a new Layer instance 
    Layer layer = new Layer(byte layerValue);
    // Create a new Tempo instance (two examples) 
    Tempo tempo = new Tempo(int tempoInBPM); 
    Tempo tempo = new Tempo(Tempo.ADAGIO);
    // Create a new Instrument instance (two examples) 
    Instrument instrument = new Instrument(byte instrumentValue);
    Instrument instrument = new Instrument(Instrument.PIANO);
    // Create a new Note instance (four examples) 
    Note note = new Note(byte value, long durationInMilliseconds); 
    Note note = new Note(byte value, double decimalDuration);
    Note note = new Note(byte value, long durationInMilliseconds, byte attackVelocity, byte decayVelocity);
    Note note = new Note(byte value, double decimalDuration, byte attackVelocity, byte decayVelocity);
    // Create a new Pitch Bend instance 
    PitchBend pitchBend = new PitchBend(byte leastSignificantByte, byte mostSignificantByte); 
    // Create a new Channel Pressure instance 
    ChannelPressure channelPressure = new ChannelPressure(bytepressure); 
    // Create a new Polyphone Pressure instance 
    PolyphonicPressure polyPressure = new PolyphonicPressure(bytekey, byte pressure);
    // Create a new Measure instance 
    // (which is purely decorative and results in no music) 
    Measure measure = new Measure();
    // Create a new Key Siganture instance 
    // keySig: a value from -7 to +7. -7 means 7 flats, +7 
    // means 7 sharps, 0 means no flats or sharps. 
    // scale: 0 for major, 1 for minor 
    // This follows the MIDI Specification on Key Signature. 
    KeySignature keySig = new KeySignature(byte keySig, bytescale); 
    // Create a new Controller instance 
    // Note that for controllers that have a Coarse and Fine 
    // setting, each of those settings has to be 
    // instantiated individually. 
    Controller controller = new Controller(byte index, bytevalue); 
    // Create a new Time instance 
    // milliseconds: The millisecond position of the next 
    // musical event
    Time time = new Time(long milliseconds);
    

    创建这些对象后可以使用 addElement(JFugueElement element)

     Pattern pattern = new Pattern(); 
     pattern.addElement(voice); 
     pattern.addElement(instrument); 
     pattern.addElement(note); 
     Player player = new Player(); 
     player.play(pattern);
    

    这种模式产生的音乐将等同于从 MusicString 产生的音乐,其中包含与 JFugue 表示法相同的音乐事件:

    Player player = new Player(); 
    player.play("V0 I[Piano] C5q");
    

    还可以创建一个音符值和持续时间数组,并使用它们来构造大量的音符对象,然后将音符对象添加到模板中并播放该模板。

    // Define the value and decimal duration for each note 
    byte[] noteValues = new byte[] 
    { 64, 69, 72, 71, 64, 71, 74, 72, 76, 68, 76 }; 
    double[] durations = new double[] 
    { 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 
    0.125, 0.125, 0.125, 0.125 }; 
    1.
    // Create a Pattern and set the tempo and instrument
    Pattern pattern = new Pattern(); 
    pattern.addElement(new Tempo(110)); 
    pattern.addElement(new Instrument(Instrument.HARPISCHORD)); 
    
    // Build up the pattern using the note values and durations
    for (int i=0; i < noteValues.length; i++) { 
        Note note = new Note(noteValues[i], durations[i]); 
        pattern.addElement(note); 
    } 
    
    // Play the pattern
    Player player = new Player(); 
    player.play(pattern);
    

    在您复制已知音乐的情况下,这种创建音乐的方法并不是最佳选择。但是,通过算法创建音乐时可能会有用,这更多的是为了合理化,而非实际使用。

    获取音符协助(Getting Assistance with Notes)

    有人可能会说音符对于创造音乐至关重要,在MusicString之外的各种情况下都使用音符。例如,在第7章中,您将学习间隔符号,它使您可以根据间隔(音符之间的差异)来指定音乐,而不是具体音符本身。然后,您将根便笺传递给Interval表示法类,以根据提供的时间间隔创建便笺的特定实例。

    正如您所知,可以使用 C5 等符号在 MusicString 中指定音符。可以使用MIDI音符值来指定音符,例如[60]。MusicStringParser 能够将C5之类的东西转换为有意义的音符值。大多数方法不受MusicStringParser支持,这些方法需要音符值。问题在于,像C5这样的符号会在一段时间后变得非常舒适。

    为了使音乐创作尽可能简单,Note 类具有许多静态方法,这些方法可以产生给定 MusicString 类记法的 MIDI 音符值。此外,您可能发现有必要将音符值转换为字符串,查找特定十进制持续时间的持续时间字母,等等。Note类包含以下随时可以使用的静态方法:

     // Returns a MusicString represention of the given MIDI note value. 
     // For example, given 60, this method returns C5. 
    public static String getStringForNote(int noteValue) 
     // Returns a MusicString represention of the given MIDI note value 
     // and decimal duration. For example, given 60 and 0.5, 
     // this method returns C5h. 
    public static String getStringForNote(int noteValue, double decimalDuration) 
     // Returns the frequency, in Hertz, for the given note value. 
     // For example, the frequency for A5 (MIDI note 69) is 440.0 
    public static double getFrequencyForNote(int noteValue)
    

    JFugue 还包含以下用于将十进制值转换为表示持续时间的 MusicString 的方法,反之亦然。很多方法中的一种 getStringForDuration(double decimalDuration),返回给定十进制持续时间的MusicString表示形式。例如 给定0.5,此方法返回h。此方法仅转换单个持续时间值(不支持符合,3.0)代表整个,一半,四分之一,八分之一,十六分,三十二秒,六十四分之一和一百二十八分的持续时间;以及与这些持续时间相关的点缀持续时间(例如 0.75 代表 h)。此方法不转换合并持续时间(例如 0.625代表hi)任何大于1.0的持续时间(例如,4.0 代表 wwww)。对于这些值,原始的十进制持续时间以字符串形式返回,并以/开头,以使返回的值成为有效的MusicString持续时间指示符。

    第二种方法,getDecimalForDuration(String stringDuration),行为相似:它接受一个表示单个持续时间字符或带点缀的持续时间字符的String,并返回对应于该持续时间的十进制值。此方法不适用于合并的持续时间字符串,例如hiwwww

    最后,Note 类包含一个公共的静态 String 数组 NOTES,该数组包含一个八度音阶中十二个音符的每一个的字符串表示形式:

    public static final String[] NOTES = new String[] { "C", "C#", "D", "Eb", "E", "F", "F#", "G", "G#", "A", "Bb", "B" };
    

    将乐谱转录为JFugue MusicString

    本节介绍如何将乐谱转换为JFugue表示法,在本演示中,我们将使用 “Spring” 这首音乐。以下示例使用了Pattern类,您将在下一章中详细了解。现在,您只需要知道Pattern类是一个包含MusicString的对象。

    首先要注意的是,有两个谱号,高音谱号和低音谱号,这意味着我们需要将音乐输入两种声音-即可以和谐播放的两种音乐。我们会将高音谱号的音符放入音色0,将低音谱号的音符放入音色1。这里有一个节奏,所以我们也可以输入它。所以 我们会有这样一个 MusicString:

     Pattern pattern = new Pattern("T[Allegro]"); 
     pattern.add("V0 notes-for-treble-clef"); 
     pattern.add("V1 notes-for-bass-clef"); 
     Player player = new Player(); 
     Player.play(pattern);
    

    活页乐谱中有一个时间签名,但是JFugue当前不包含时间表示。这是因为时间标识对于了解小节中出现多少音符非常重要。然而,JFugue能够播放节奏和音符持续时间的音符。事实上,在JFugue的符号中,连竖线也是可选的。

    让我们开始输入高音谱号的音符,我们首先看到 C 音符,四分音长。回顾图2.2,该音符在第五个八度音阶中。这意味着我们有C5q

    接下来是一条条线,指示第一个小节的结束。我们将在音乐字符串中添加一个竖线符号|; 这将有助于音乐的清晰度。

    然后我们看到CE音符和谐地演奏,这些又是四分音符。这些注释的可以表示为E5q + C5q。并且 我们连续有三个。

    接下来是两个八分音符,DC。尽管它们被禁止在一起,但是该 bar 是风格上的,并且不会改变八音符的演奏方式。我们需要将D5iC5i添加到我们的 MusicString 中。

    然后还有另一个测量 bar,因此添加另一个管道符号。然后有两个音符,EG,以半点缀的虚线持续演奏。我们需要添加Eh.+ Gh. 到 MusicString 。

    此时,我们的MusicString应该如下所示:

    V0 C5q | E5q+C5q E5q+C5q E5q+C5q D5i C5i | Eh.+Gh.
    

    继续,有第八个G和F音符,所以添加 G5i F5i

    接下来的八个音符是我们已经输入的音符的副本,我们在这里有几种选择。最明显的选择是我们可以重新输入音符,我们可以将重复的音符放在自己的模式中,并在看到这组八个音符时使用该模式。或者,我们也可以使用 Pattern 类上的方法来重复已经输入的音符子集。由于在下一章之前不会详细讨论“模式”,所以我们将“模式”选项放在一边,只需要重新键入(或复制并粘贴)便笺即可。

    因此,我们的MusicString现在看起来像这样:

    V0 C5q | E5q+C5q E5q+C5q E5q+C5q D5i C5i | Eh.+Gh. G5i F5i | 
    E5q+C5q E5q+C5q E5q+C5q D5i C5i | Eh.+Gh. G5i F5i
    

    现在我们可以制作低音谱号了。 首先,要休息四分之一。将其余部分添加到 MusicString 中非常重要,这样谱号才能正确排列。将Rq添加到低音谱号。 也添加一条线。

    接下来,我们看到一堆C音符,持续时间为一半。根据图2.2,这些注释位于八度 4中。将这些音符添加到低音谱号,MusicString 应该如下所示:

    V1 Rq | C4h C4h | C4h C4h | C4h C4h | C4h C4h
    

    因此,程序本身应如下所示:

    Pattern pattern = new Pattern("T[Allegro]"); 
    pattern.add("V0 C5q | E5q+C5q E5q+C5q E5q+C5q D5i C5i | 
    Eh.+Gh. G5i F5i | E5q+C5q E5q+C5q E5q+C5q D5i C5i | Eh.+Gh. G5i 
    F5i"); 
    pattern.add("V1 Rq | C4h C4h | C4h C4h | C4h C4h | C4h C4h");
    

    由于MusicString中允许有多余的空格,因此您可以将谱号隔开,以便它们更清晰地排列:

    
    // This looks better on a larger display! 
    Pattern pattern = new Pattern("T[Allegro]"); 
    pattern.add("V0 C5q | E5q+C5q E5q+C5q E5q+C5q D5i C5i | Eh.+Gh. G5i F5i | E5q+C5q E5q+C5q E5q+C5q D5i C5i | Eh.+Gh. G5i F5i"); 
    pattern.add("V1 Rq | C4h C4h | C4h C4h | C4h C4h | C4h C4h  "); 
    // Now, play the music! 
    Player player = new Player(); 
    Player.play(pattern);
    

    现在可以将音乐转录为 JFugue。

    将MIDI转换为 JFugue MusicStrings

    JFugue可以将MIDI文件转换为可以探索和操纵的MusicString。

    正如您将在第8章中了解到的那样,JFugue的架构使得任何Parser都可以解释数据并将音乐事件触发到任何ParserListener。例如,JFugue的MusicStringParser可以向JFugue的MidiRenderer触发事件(实现 ParserListener),从而将MusicStrings转换为MIDI。

    JFugue可用的解析器之一是MidiParser。JFugue可用的ParserListener之一是MusicStringRenderer。

    JFugue将MIDI转换为 MusicString 的功能非常好。这意味着您可以获取MIDI文件并以各种有趣的方式进行播放:

    • 从现有歌曲中跳动
    • 从歌曲中获取一个声音,翻转并反转它
    • 采样一首歌曲并将其用作循环
    • 学习特定歌曲的音符(打印出MusicString)
    • 对歌曲进行数学分析以识别其音调结构
    • 创建一个Hidden Markov Model,该模型可以为给定的艺术家识别一个音符跟随另一个音符的可能性; 然后用它来创作歌手风格的新歌,
    • 还有其他无限的可能性

    这个调用很简单,但是幕后的事情很复杂。首先,要将 MIDI 文件转换为 MusicString,请使用loadMidi()命令:

    Player player = new Player(); 
     Pattern pattern = player.loadMidi(new File("music-file.mid"));
    

    playMidiDirectly()一样,如果读取 MIDI 文件有问题,则 loadMidi()命令可能会引发 IOException 或InvalidMidiDataException,因此请务必捕获这些异常。

    在幕后,JFugue正在做很多事情:

    1. 获取MIDI文件格式,并从中获取音序的时间和分辨率,
    2. 将 MidiParser 连接到 MusicStringRenderer
    3. 从 MIDI 文件中获取一个序列并进行解析
    4. 从MusicStringRenderer返回一个新的Pattern

    生成的 Pattern 包含一个与 MIDI 文件非常相似的 MusicString 。 如果查看 MusicString,则会看到许多熟悉的命令。

    从MIDI文件创建的MusicString与可能自己创建的MusicString之间存在一些差异。首先 所有音符值和持续时间均使用其数值表示,因此用[60]/0.25代替了C5q,同样,您将看到乐器的数值(例如,用I0代替I[Piano])和其他带有值的MusicString命令。

    更令人惊讶的是,您会看到许多“时间”命令-一个标志 @,随后是播放下一个命令的时间(以毫秒为单位)。通常,几乎不会在自己创建的 MusicString 中使用Time命令。构建自己的 MusicString 时,您将使用音符时长和休止符来适当地隔开音乐。MIDI对音乐的定义不同:音符可以随时打开或关闭,而不一定在规定的持续时间内。而且,MIDI中没有明确的休止符; 只有“注解”和“注解”事件可以在不确定的时间发生。这就是为什么您会看到“时间”命令的原因,也是为什么您会看到音符持续时间不适合典型的整个下半年等的原因。代替[60] /0.25,您更有可能会看到类似[60] /0.0242555568的信息

    FilePlayer

    JFugue FilePlayer(org.jfugue.extras.FilePlayer)旨在用作命令行实用程序,它将JFugue模式文件作为输入并播放MIDI

    可以在模式上使用 saveMusicString() 方法创建JFugue模式文件,也可以在任何文本编辑器中创建一个JFugue模式文件。

    无论哪种情况,每行都可以包含MusicString。 文件中的所有MusicStrings将被串联在一起以创建一个新的Pattern实例

    以井号()开头的行被视为注释。 请注意,注释行必须以井号开头; 如果英镑符号位于行中的其他位置,则JFugue会忽略它,因为代表清晰音符的键也是 pound。

    JFugue模式文件不支持使用Rhythm,IntervalNotation或MicrotoneNotation类创建的音乐。以下是一个示例JFugue模式文件,其中包含贝多芬“FürElise”的前几个小节

    # 
    # "Fur Elise", Ludwig van Beethoven 
    # Transcribed into JFugue by David Koelle 
    # http://www.jfugue.org 
    # 
    T200 
    V0 E5s D#5s | E5s D#5s E5s B4s D5s C5s | A4i Rs C4s E4s A4s | 
    B4i Rs E4s G#4s B4s | C5i Rs E4s E5s D#5s | E5s D#5s E5s B4s 
    D5s C5s | A4i Rs C4s E4s A4s | B4i Rs E4s C5s B4s | A4q 
    V1 Ri | Riii | A2s E2s A3s Rsi | 
    E2s E3s G#3s Rsi | A2s E2s A3s Rsi | Riii | A2s E2s A3s 
    Rsi | E2s E3s G#3s Rsi | Riii
    

    Midi2JFugue

    Midi2JFugue 程序(org.jfugue.extras.Midi2JFugue)使用 JFugue 的解析器和渲染器将 MIDI 文件转换为 JFugue 模式文件。
    与 FilePlayer 一样,它旨在用作命令行实用程序。

    传递给 Midi2JFugue 的参数包括现有 MIDI 文件的文件名和目标模板文件的文件名。

    然后可以使用 FilePlayer 播放模式文件,或使用 Pattern.loadMusicString(File) 方法将其加载到 JFugue 模式中

    例子

    播放经典的音乐

     Player player = new Player(); 
     player.play("C D E F G A B"); 
     player.close(); 
    

    保存音乐为 MIDI 文件

    Player player = new Player(); 
    Pattern pattern = new Pattern("A5q B5q C5q");
    player.saveMidi(pattern, new File("MySong.midi"));
    

    加载播放 MIDI 文件

    Player player = new Player();
    player.playMidiDirectly(new File("MySong.midi"));
    

    保存 Pattern

    Pattern pattern = new Pattern("A5q B5q C5q");
    pattern.saveMusicString(new File("pattern.jfugue"));
    

    加载 Pattern

    Player player = new Player(); 
    Pattern pattern = null;
     pattern = Pattern.loadMusicString(new File("pattern.jfugue")); 
     player.play(pattern);
    

    如何加载 MIDI 文件并将其转换为 JFugue MusicString

    这将获取一个MIDI文件并将其转换为JFugue模式,然后可以根据需求对其做修改,如果您对它的工作方式感兴趣,那么它是JFugue解析器-渲染器体系结构的一个很好的例子。

     Player player = new Player(); 
     Pattern pattern = null; 
    try { 
     	pattern = player.loadMidi(new File("MySong.midi")); 
     	System.out.println(pattern); // Show the pattern
     } catch (IOException e) 
     { 
    // handle IO Exception
     } catch (InvalidMidiDataException e) 
     { 
    // handle Invalid MIDI Data Exception
     }
    

    结合 Patterns

     Pattern pattern1 = new Pattern("A5q"); 
     Pattern pattern2 = new Pattern("C5q C5q G5q"); 
     pattern1.add(pattern2); // Add patterns together
     pattern1.add("F6h"); // Add a MusicString to a pattern
    

    重复 Patterns

     Pattern pattern1 = new Pattern("A5q C5q G5q"); 
    // Repeat this pattern 4 times
     pattern1.repeat(4); 
    // Repeat twice the pattern starting at position 4
    // (results in A5q C5q G5q C5q G5q C5q G5q)
     pattern1.repeat(2, 4); 
    // Repeat twice the subset of the pattern from position 4
    // through position 6 (results in A5q C5q G5q C5q C5q)
     pattern1.repeat(2, 4, 6);
    

    创建匿名 ParserListener

    public class GetInstrumentsUsedTool extends ParserListenerAdapter 
    { 
    	private List<Instrument> instruments; 
    	public GetInstrumentsUsedTool()
     { 
    	instruments = new ArrayList<Instrument>(); 
     } 
    @Override
    public void instrumentEvent(Instrument instrument) 
     { 
    	if (!instruments.contains(instrument)) { 
    		instruments.add(instrument); 
    	 } 
     } 
    public List<Instrument> getInstrumentsUsed(Pattern pattern) 
     { 
    	 MusicStringParser parser = new MusicStringParser(); 
    	 parser.addParserListener(this); 
    	 parser.parse(pattern); 
    	return instruments; 
     } 
    }
    

    创建解析器 Parser

    1. 创建解析器的子类
    2. 创建一个parse()方法,该方法获取您要解析的任何对象,并在解析某些音乐事件时触发事件
    3. 在适当的时候构造JFugue元素,并使用Parser类中可用的fireXxxxEvent()方法将它们触发到任何ParserListener:
    protected void fireVoiceEvent(Voice event) 
    protected void fireTempoEvent(Tempo event) 
    protected void fireInstrumentEvent(Instrument event) 
    protected void fireLayerEvent(Layer event) 
    protected void fireTimeEvent(Time event) 
    protected void fireKeySignatureEvent(KeySignature event) 
    protected void fireMeasureEvent(Measure event) 
    protected void fireControllerEvent(Controller event) 
    protected void fireChannelPressureEvent(ChannelPressure  event) 
    protected void firePolyphonicPressureEvent(PolyphonicPressure event) 
    protected void firePitchBendEvent(PitchBend event) 
    protected void fireNoteEvent(Note event) 
    protected void fireParallelNoteEvent(Note event) 
    protected void fireSequentialNoteEvent(Note event)
    

    创建渲染器 Renderer

    1. 创建一个类实现 ParserListener
    2. 覆盖其方法
    public void voiceEvent(Voice voice); 
    public void tempoEvent(Tempo tempo); 
    public void instrumentEvent(Instrument instrument); 
    public void layerEvent(Layer layer); 
    public void measureEvent(Measure measure); 
    public void timeEvent(Time time); 
    public void keySignatureEvent(KeySignature keySig); 
    public void controllerEvent(Controller controller); 
    public void channelPressureEvent(ChannelPressure channelPressure); 
    public void polyphonicPressureEvent(PolyphonicPressure polyphonicPressure); 
    public void pitchBendEvent(PitchBend pitchBend); 
    public void noteEvent(Note note); 
    public void parallelNoteEvent(Note note); 
    public void sequentialNoteEvent(Note note);
    

    链接解析器及渲染器

    YourParser parser = new YourParser(); 
    YourRenderer renderer = new YourRenderer(); 
     parser.addParserListener(renderer); 
     parser.parse(whatever object your parser parses);
    

    解析 MIDI 并渲染为 MusicString

    MidiParser parser = new MidiParser(); 
     MusicStringRenderer renderer = new MusicStringRenderer(); 
     parser.addParserListener(renderer); 
     parser.parse(MIDI sequence);
    

    解析并 MusicString 渲染为 MIDI

    MusicStringParser parser = new MusicStringParser(); 
     MidiRenderer renderer = new MidiRenderer(); 
     parser.addParserListener(renderer); 
     parser.parse(MusicString);
    

    创建韵律 Rhythm

    Rhythm rhythm = new Rhythm(); 
    // Set up your substitutions. Examples:
     rhythm.addSubstitution('O', "[ACOUSTIC_BASS_DRUM]s"); 
     rhythm.addSubstitution('o', "[ACOUSTIC_SNARE]s"); 
     rhythm.addSubstitution('\'', "[CLOSED_HI_HAT]s"); 
     rhythm.addSubstitution('`', "[OPEN_HI_HAT]s"); 
     rhythm.addSubstitution('.', "Rs");
     // Create layers using your substitutions. Examples:
     rhythm.setLayer(1, "O.OO...O.OO....O"); 
     rhythm.setLayer(2, "....o.......o..."); 
     rhythm.setLayer(3, "'.`.'.`.'.`.'.`."); 
    // Generate a Pattern from the Rhythm
     Pattern pattern = rhythm.getPattern(); 
    // Play the pattern!
     Player player = new Player(); 
     player.play(pattern);
    

    使用间隔符号

    // Specify a MusicString using intervals 
     IntervalNotation riff = new IntervalNotation( 
    "<1>q <5>q <8>q <1>q+<5>q+<8>q <1>majq"); 
     // Get a Pattern specifically tailored to the C5 note 
     Pattern pattern = riff.getPatternForRootNote("C5"); 
     // Play the pattern 
     Player player = new Player(); 
     player.play(pattern); 
     // Compare the result against a pattern that explicitly 
     // uses C5, just to demonstrate that this works! 
     player.play("C5q E5q G5q C5q+E5q+G5q C5majq"); 
     // Get riffs for multiple root notes, then play them together 
     Pattern p1 = riff.getPatternForRootNote("C5"); 
     Pattern p2 = riff.getPatternForRootNote("E5"); 
     Pattern p3 = riff.getPatternForRootNote("C5"); 
     Pattern p4 = riff.getPatternForRootNote("G5"); 
     Pattern fullPattern = new Pattern(p1, p2, p3, p4); 
     new Player().play(fullPattern);
    

    结合间隔和旋律

    Rhythm rhythm = new Rhythm(); 
    // Step 1a. Hammer out your beat – this example is 8-beat 
    rhythm.setLayer(1, "O.OO...O.OO....O"); 
    rhythm.setLayer(2, "....o.......o..."); 
    rhythm.setLayer(3, "^.`.^.`.^.`.^.`."); 
    rhythm.setVoice(1, "1...234.....11..");
    rhythm.setVoice(2, "W V ....W "); 
    // Step 1b. Set voice details (like instruments) 
    rhythm.setVoiceDetails(1, "I[Piano]"); 
    rhythm.setVoiceDetails(2, "I[String_Ensemble_2]"); 
    // Step 2. Identify instruments to use in the beat 
    // (ensure the MusicString for each is the same duration) 
    rhythm.addSubstitution('O', "[ACOUSTIC_BASS_DRUM]s"); 
    rhythm.addSubstitution('o', "[ACOUSTIC_SNARE]s"); 
    rhythm.addSubstitution('^', "[CLOSED_HI_HAT]s"); 
    rhythm.addSubstitution('`', "[OPEN_HI_HAT]s"); 
    rhythm.addSubstitution('.', "Rs"); 
    rhythm.addSubstitution('1', "<1>s"); 
    rhythm.addSubstitution('2', "<2>s"); 
    rhythm.addSubstitution('3', "<3>s"); 
    rhythm.addSubstitution('4', "<4>s"); 
    rhythm.addSubstitution('W', "<1>qa120d120"); 
    rhythm.addSubstitution('V', "<4>qa120d120"); 
    // Step 3. Get the Pattern, repeat it, and play it 
    Pattern p1 = rhythm.getPatternWithInterval (new Pattern("C3")); 
    Pattern p2 = rhythm.getPatternWithInterval (new Pattern("E3")); 
    Pattern p3 = rhythm.getPatternWithInterval (new Pattern("C3")); 
    Pattern p4 = rhythm.getPatternWithInterval (new Pattern("G3")); 
    Pattern pattern = new Pattern(p1, p2, p3, p4); 
    pattern.repeat(2); 
    Player player = new Player(); 
    player.play(pattern);
    

    使用微调符号

    MicrotoneNotation microtone = new MicrotoneNotation(); 
     // Map your desired frequencies to keys. Examples:
     microtone.put("Be", 400.00); 
     microtone.put("Bf", 405.50); 
     microtone.put("Bt", 415.67); 
     microtone.put("Bv", 429.54); 
     // Create a pattern containing your keys in brackets 
     Pattern pattern = microtone.getPattern("<Be>q <Bt>q <Bf>q 
    <Bv>q"); 
     Player player = new Player(); 
     player.play(pattern);
    

    发送 MIDI 到外接设备

     DeviceThatWillReceiveMidi device = null; 
    try { 
     	device = new DeviceThatWillReceiveMidi(); 
     } catch (MidiUnavailableException e) { 
    // handle MIDI Unavailable Exception
     } 
     Sequence sequence = null; 
    try { 
     	sequence = MidiSystem.getSequence(new File("MySong.mid")); 
     } catch (InvalidMidiDataException e) 
     { 
    // handle Invalid MIDI Data Exception
     } catch (IOException e) 
     { 
    // handle IO Exception
     } 
     device.sendSequence(sequence);
    

    发送 Pattern 到外部设备

     DeviceThatWillReceiveMidi device = null; 
    try { 
     	device = new DeviceThatWillReceiveMidi(); 
     } catch (MidiUnavailableException e) { 
    // handle MIDI Unavailable Exception
     } 
     Player player = new Player(); 
     Pattern pattern = new Pattern("A5q B5q C5q"); 
     Player.play(pattern); 
     Sequence sequence = player.getSequencer().getSequence(); 
     device.sendSequence(sequence);
    

    从外部设备录音

    DeviceThatWillTransmitMidi device = null; 
    try { 
     	device = new DeviceThatWillTransmitMidi(); 
     } catch (MidiUnavailableException e) { 
    // handle MIDI Unavailable Exception
     }
     System.out.println("Listening for 5 seconds..."); 
     device.startListening(); 
    // Wait long enough to play a few notes on the keyboard
    try { 
     	Thread.sleep(5000); 
     } catch (InterruptedException e) 
     { 
    // handle Interrupted Exception
     } 
    // Close the device (at program exit)
     device.stopListening(); 
     System.out.println("Done listening"); 
     Pattern pattern = device.getPatternFromListening(); 
     System.out.println("Pattern from listening: "+pattern); 
     Player player = new Player(); 
     player.play(pattern); 
     player.close();
    

    使用 JFugue 加载音库

    音乐库参考链接

    // Make sure gervill.jar is in your classpath
     Synthesizer synth = MidiSystem.getSynthesizer(); 
     Soundbank soundbank = MidiSystem.getSoundbank(new
    File(soundbank filename)); 
     Sequencer sequencer = 
    player.getSequencerConnecedToSynthesizer(synth); 
     Pattern pattern = new Pattern(your pattern); 
     Player player = new Player(sequencer); 
     player.play(pattern);
    
    展开全文
  • ElasticSearch基础:从排索引说起,快速认知ES

    千次阅读 多人点赞 2021-06-27 10:01:48
    Type:类型,相当于数据库中的table概念,在6.0版本之前,一个Index中可以有多个type,7.0版本后彻底废弃多type,每个索引只能有一个type,即“ _doc”。这个概念就不用太关注了。 Document:文档,存储在ES中的...

    1 ElasticSearch认知

    ElasticSearch(简称ES)是什么?按照 ElasticSearch官网 的定义,Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎。

    很官方,但也很晦涩。所以,接下来我们尝试比较直白地去描述它。

    1.1 关于搜索

    首先,需要弄明白下面几个问题:

    1. 什么是搜索?
    2. 为什么数据库不适合处理搜索?
    3. 什么是全文检索和Lucene?

    提到搜索,人们会立刻联想到在百度、谷歌上输入关键词获取相关的内容的场景。但搜索不等于百度,大部分APP支持的站内搜索更加大行其道。

    数据库是储存和查询数据的利器,那么数据库是否适合做搜索呢?答案是不合适。第一个原因是,当数据库存储了大量数据后,查询效率大幅降低。

    另外有些搜索场景,数据库也是不支持的,例如在下表中,我们试图通过“中国足球”这个关键词搜索数据,数据库是无法查询到相应内容的。

    idname
    1中国男子足球队
    2中国男子田径队
    3中国女子排球队
    4中国女子跳水队

    1.2 倒排索引

    什么是倒排索引?倒排索引也叫反向索引,我们通常理解的索引是通过key寻找value,与之相反,倒排索引是通过value寻找key,故而被称作反向索引。

    下面我们用一个简单的例子描述一下倒排索引的作用过程:

    假如现在有三份数据文档,内容分别是:

    Doc 1:Java is the best programming language
    
    Doc 2:PHP is the best programming language
    
    Doc 3:Javascript is the best programming language
    

    为了创建索引,ES引擎通过分词器将每个文档的内容拆成单独的词(称之为词条,或term),再将这些词条创建成不含重复词条的排序列表,然后列出每个词条出现在哪个文档,结果如下:

    termDoc 1Doc 2Doc 3
    Java
    is
    the
    best
    programming
    language
    PHP
    Javascript

    这种结构由文档中所有不重复的词的列表构成,对于其中每个词都有至少一个文档与与之关联。这种由属性值来确定记录的位置的结构就是倒排索引,带有倒排索引的文件被称为倒排文件。

    将上表转为更直观的图片来展示倒排索引:
    在这里插入图片描述
    其中,几个核心术语需要着重理解:

    1. 词条(term):索引里面最小的存储和查询单元,对于英文来说是一个词,对于中文来说一般指分词后的一个词。
    2. 词典(Term Dictionary):也叫字典,是词条的组合。搜索引擎的通常索引单位是单词,单词词典是文档集合中出现过的所有单词构成的字符串集合,单词词典内每条索引项记载单词本身的一些信息以及指向倒排所有的指针。
    3. 倒排表(Post list):一个文档通常由多个词组成,倒排表记录的是某个词在哪些文档里出现过及出现的位置。每个记录称为一个倒排项(Posting),倒排表记录的不单单是文档编号,还记录了词频等信息。
    4. 倒排文件(Inverted File):所有单词的倒排列表往往顺序地存储在磁盘的某个文件里,这个文件被称之为倒排文件,倒排文件是存储倒排索引的物理文件。

    词典和倒排表是 Lucene这种很重要的两种数据结构,是实现快速检索的重要基石。词典和倒排文件是分两部分存储的,词典在内存中而倒排文件存储在磁盘。

    1.3 Lucene

    至于Lucene,直白地说,它就是一个jar包,封装好了各种建立倒排索引、匹配索引进行搜索的各种算法。我们可以引入Lucene,基于它的API进行开发。

    ElasticSearch就在Lucene的基础上实现的,对Lucene进行了良好的封装,简化开发,并提供了很多高级功能。

    ElasticSearch生态

    ElasticSearch 为快速检索和分析大数据而生,目前已形成丰富的生态。
    在这里插入图片描述
    例如目前比较流行的ELK体系:

    • Elasticsearch是位于Elastic堆栈核心的分布式搜索和分析引擎。
    • LogstashBeats有助于收集、聚合和丰富数据,并将其存储在Elasticsearch中。
    • Kibana使您能够以交互方式探索、可视化和共享对数据的见解,并管理和监视堆栈。

    1.4 ES基本概念

    要了解 Elasticsearch ,首先要先了解下面的几个专有名词:索引(Index)、类型(Type)、文档(Document)、映射(mapping)

    既然 Elasticsearch 能够存储和查询数据,那么我们自然要将其和最具知名度的数据库-Mysql进行一番对比,两者之间可以通过下表做一个并不非常严谨的类比,主要是为了方便理解。

    MysqlElasticsearch
    索引(Index)库(Database)
    类型(Type)表(Table)
    文档(Document)行(Row)
    字段(Field)列(Column)
    映射(Mappings)表结构(schema)
    • Index:索引,相当于关系数据库中的database概念,是一类数据的集合,是一个逻辑概念。
    • Type:类型,相当于数据库中的table概念,在6.0版本之前,一个Index中可以有多个type,7.0版本后彻底废弃多type,每个索引只能有一个type,即“ _doc”。这个概念就不用太关注了。
    • Document:文档,存储在ES中的主要实体叫文档,可以理解为关系型数据库中表的一行数据记录。每个文档由多个字段(field)组成。区别于关系型数据库的是,ES是一个非结构化的数据库,每个文档可以有不同的字段,并且有一个唯一标识。
    • Field:字段,存在于文档中,字段是包含数据的键值对,可以理解为Mysql一行数据的其中一列。
    • Mapping:映射,是对索引库中的索引字段及其数据类型进行定义,类似于关系型数据库中的表结构。ES默认动态创建索引和索引类型的Mapping。

    ES和Mysql直观对比:
    在这里插入图片描述

    1.5 ES集群概念

    Elasticsearch 设计上是天然支持分布式的,下面我们了解一下集群相关概念。

    • cluster:集群,一个ES集群由多个节点(node)组成, 每个集群都有一个共同的集群名称最为标识。
    • node:节点,一个ES实例即为一个节点,一台机器可以有多个节点。
    • shard:分片,如果某个索引包含大量数据,以至于一台机器无法存储,ES可以将一个索引中的数据切分为多个shard,分布在多台服务器上存储。这样,ES就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。每个shard都是一个最小工作单元,承载部分数据,具有一个lucene实例和完整的建立索引、处理请求的能力。
    • replica:副本,就是shard的冗余备份,它可以防止数据丢失以及shard异常时负责容错和负载均衡。

    在实际生产中,ES通常与Mysql等存储系统联合使用,例如下面这个设计:
    在这里插入图片描述

    2 SpringBoot集成ES

    Springboot集成ES非常方便,只要三步操作:

    1、pom.xml添加依赖:

    <dependency>
    	<groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.8.0</version>
    </dependency>
    <dependency>
    	<groupId>org.elasticsearch.client</groupId>
    	<artifactId>elasticsearch-rest-client</artifactId>
    	<version>7.8.0</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>7.8.0</version>
    </dependency>
    

    2、application.yml增加配置:

    elasticsearch:
      host: 11.50.36.97
      port: 9200
    

    3、新建config类:

    @Configuration
    @ConfigurationProperties(prefix = "elasticsearch")
    @Data
    public class ESConfig {
    
        private String host;
    
        private Integer port;
    
        @Bean(destroyMethod = "close")
        public RestHighLevelClient client(){
            return new RestHighLevelClient(RestClient.builder(new HttpHost(host, port)));
        }
    }
    

    写个测试方法测试一下:

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = DemoApplication.class)
    @Slf4j
    public class BasicTest {
        @Autowired
        private RestHighLevelClient client;
    
    	 /**
         * 添加索引
         *
         * @throws IOException
         */
        @Test
        public void addIndex() throws IOException {
            //1.使用client获取操作索引对象
            IndicesClient indices = client.indices();
            //2.具体操作获取返回值
            //2.1 设置索引名称
            CreateIndexRequest createIndexRequest = new CreateIndexRequest("person");
    
            CreateIndexResponse createIndexResponse = indices.create(createIndexRequest, RequestOptions.DEFAULT);
            //3.根据返回值判断结果
            System.out.println(createIndexResponse);
        }
        
        /**
         * 查询所有的索引
         *
         * @throws IOException
         */
        @Test
        public void indexTest() throws IOException {
            GetAliasesRequest request = new GetAliasesRequest();
            GetAliasesResponse alias = client.indices().getAlias(request, RequestOptions.DEFAULT);
    
            Map<String, Set<AliasMetadata>> map = alias.getAliases();
            map.forEach((k, v) -> {
                if (!k.startsWith(".")) {
                    System.out.println(k);
                }
            });
        }
    }
    

    3 ElasticSearch安装

    3.1 下载与安装

    下载地址:https://www.elastic.co/cn/downloads/elasticsearch
    在这里插入图片描述
    安装:

    1、将压缩包上传到linux服务器到特定目录,比如 /export/test
    2、解压压缩包:tar -zxvf elasticsearch-7.13.2-linux-x86_64.tar.gz

    ES目录介绍:

    • bin:可执行文件在里面,运行es的命令就在这个里面,包含了一些脚本文件等
    • config:配置文件目录
    • JDK:java环境
    • lib:依赖的jar,类库
    • logs:日志文件
    • modules:es相关的模块
    • plugins:可以自己开发的插件
    • data:自建目录,后面要用,用来放置索引

    3.2 修改配置

    首先,我们需要做一些系统配置,要使用有权限的用户,例如root用户。

    1、配置用户

    因为root用户不能直接运行ES,所以新增一个用户(如果有非root用户,直接用也可以)

    useradd es
    passwd es 
    chown -R es elasticsearch
    

    2、设置最大句柄数(nofile)和最大进程数(nproc):

    vim /etc/security/limits.conf
    

    在末尾追加内容(已有的话忽略):

    *        soft       nofile        65536
    *        hard       nofile        65536
    *        soft       nproc         4096
    *        hard       nproc         4096
    

    3、调整vm.max_map_count的大小

    max_map_count文件包含限制一个进程可以拥有的VMA(虚拟内存区域)的数量

    vim /etc/sysctl.conf
    

    在文尾追加(已有的话则忽略此步):

    vm.max_map_count=262144
    

    执行以下命令使该配置生效:

    sysctl -p
    

    接下来,切换到刚刚创建的用户,修改ES配置文件:

    su es
    vim config/elasticsearch.yml
    

    主要修改以下几项:

    # 1. 修改集群名称
    cluster.name: test-es
    # 2. 修改当前的es节点名称
    node.name: node-1
    # 3. 修改data数据保存地址(按自己的实际路径填写)
    path.data: /export/test/elasticsearch-7.13.2/data
    # 4. 日志数据保存地址(按自己的实际路径填写)
    path.logs: /export/test/elasticsearch-7.13.2/logs
    # 5. 绑定es网络ip
    network.host: 0.0.0.0
    # 6. 修改初始化master节点
    cluster.initial_master_nodes: ["node-1"]
    

    启动es服务:

    cd bin
    ./elasticsearch
    

    访问 http://192.168.1.13:9200/,出现以下信息,表示es启动成功。

    {
      "name" : "node-1",
      "cluster_name" : "elasticsearch",
      "cluster_uuid" : "vMavXuuVTbmqykZpDEM0zQ",
      "version" : {
        "number" : "7.13.2",
        "build_flavor" : "default",
        "build_type" : "zip",
        "build_hash" : "4d960a0733be83dd2543ca018aa4ddc42e956800",
        "build_date" : "2021-06-10T21:01:55.251515791Z",
        "build_snapshot" : false,
        "lucene_version" : "8.8.2",
        "minimum_wire_compatibility_version" : "6.8.0",
        "minimum_index_compatibility_version" : "6.0.0-beta1"
      },
      "tagline" : "You Know, for Search"
    }
    

    设置后台启动:

    ./bin/elasticsearch -d
    

    3.3 配置Kibana

    下载地址:https://www.elastic.co/cn/downloads/kibana

    Kibana是Java应用,解压即可。解压后,进入文件目录的config目录中,编辑kibana.yml文件,修改该项:

    # 指向我们安装好的ES服务地址
    elasticsearch.hosts: ["http://11.50.36.97:9200/"]
    

    然后,进入bin目录,双击kibana.bat 即可启动。

    以上是ElasticSearch基础的内容,后续将持续添加更多内容,敬请关注!

    展开全文
  • 帆软软件FineReport考试题库FCRA题库

    千次阅读 多人点赞 2020-12-18 11:39:15
    FineReport考试题库FCRA题库一、FCRA-入门基础二、FCRA-数据集,数据连接三、FCRA-模板四、FCRA-报表设计五、FCRA-参数六、FCRA-图表七、FCRA-填报八...最新FCRA题库,问题实在太多,答案还要f豆,只能后续学习持续更
  • 简介(Introduction)Martin Odersky和Lex Spoon在许多人看来,新的集合框架是Scala 2.8最显著的改进。此前Scala也有集合(实际上新框架大部分地兼容了旧框架),但2.8的集合类在通用性、一致性和功能的丰富性上...
  • 一、实例化对象有哪几种方式 new clone() 通过反射机制创建 //用 Class.forName方法获取类,在调用类的newinstance()方法 Class<?> cls = Class.forName("com.dao.User"); User u = (User)cls.
  • 单选题 1、信息素养的核心是( )。...3、从对文献的生产加工与组织层次来看,文献可以分成一次文献、二次文献和三次文献。一次文献主要有( )。 A、专著、报纸、期刊 B、书目、索引、文摘 C、百科全书、年鉴、手册 D、
  • Linux 题库( 一 ) 一、选择题 (每小题2分,共50分) 4. 下面哪个命令是用来定义shell的全局变量( D ) ...12. 当运行在多用户模式下时,用Ctrl+ALT+F*可以切换多少虚拟用户终端( B ) A. 3...
  • 排索引、搜索引擎

    千次阅读 2017-03-27 21:05:07
    通常可以采用以下方式之一:   1: Wtf = 1 + log(TF)   2: Wtf = a + (1- a)* TF /Max (TF)  其中a为调节因子,经验取值a=0.5 最新研究表明是0.4效果更好。     单词 的文档频率DF...
  • 牛逼!Java 从入门到精通,超全汇总版

    万次阅读 多人点赞 2021-05-06 19:40:33
    Java 控制流程 Java 访问控制权限 面向对象 继承 封装 多态 面向对象最主要有三大特征:继承、封装和多态,你可以参考这篇博客 面向对象的三大基本特征和五大基本原则 Java 抽象类和接口 ,也可以参考这篇文章 深入...
  • 成熟的框架有很多,这里选用Asio网络库原因有:简单方便、作者写的代码比较规范、可能进入下一代的C++标准库中。 可移植性好: 在windows下可能使用iocp,在linux下可能使用epoll,在bsd下可能使用kqueue。 可扩展...
  • A、主机和输出设备 B、CPU和存储器 C、主机和外部设备 D、CPU和外部设备 15、以下说法正确的是( )。 A、计算机系统包括硬件系统和软件系统 B、小型机亦称为微机 C、计算机按其处理能力分为模拟计算机和...
  • Python attrs,提高面向对象编程效率

    千次阅读 2021-11-30 18:12:23
    Python是面向对象的语言,一般情况下使用面向对象编程会使得开发效率更高,软件质量更好,并且代码更易于扩展,可读性和可维护性也更高。但是如果在一个较大的项目,如果实体类非常多并且有非常复杂的属性,你就会...
  • 长文梳理Muduo核心代码及优秀编程细节剖析

    千次阅读 多人点赞 2022-04-08 16:09:44
    长文梳理Muduo核心代码(Multi-Reactor架构代码)及优秀编程细节思想剖析。
  • 选择题 ...3.(B)是软件开发过程普遍存在的一种内在现象。 A、综合 B、迭代 C、建模 D、归纳 4.数据流图具有(D)种最基本的符号。 A、1 B、2 C、3 D、4 (知识点)“→”箭头,表示数据流; 〇:圆或椭
  • 日常Java练习题(每天进步一点点系列)

    万次阅读 多人点赞 2021-07-23 18:03:06
    提示:好多小伙伴反映,直接看到答案不太好,那我把答案的颜色设置为透明,答案位置还是在题目后面,需要鼠标选中才能看见(操作如下图),同时为了手机端的小伙伴(手机端也可以长按选中查看),我还会把所有答案放...
  • 1.sklearn的安装

    千次阅读 2020-12-28 19:08:50
    sklearn库集成了一些常用的机器学习方法,在进行机器学习任务时,并不需要实现算法,只需要简单的调用sklearn库中提供的模块就能完成大多数的机器学习任务。sklearn库是在Numpy、Scipy和matplotlib的基础上开发而成...
  • 依赖倒置如何升华架构设计

    千次阅读 2022-02-08 20:22:32
    进一步讨论依赖关系中对象的行为,从现有的java的框架实际上使用以下三种基本技术的框架执行服务和部件间的绑定: 类型1 (基于接口): 可服务的对象需要实现一个专门的接口,该接口提供了一个对象可以重用这个对象...
  • 第一章 对象的概念

    千次阅读 2020-04-02 23:05:47
    第一章 对象的概念 “我们没有意识到惯用语言的结构有多大的力量。可以毫不夸张地说,它通过语义反应机制奴役我们。语言表现出来并在无意识给我们留下深刻印象的结构会自动投射到我们周围的世界。” -- Alfred ...
  • java 程序设计题库

    万次阅读 多人点赞 2019-06-18 09:25:00
    答题要求:单选题,每题只有一个正确答案,选择正确给分,不正确不给分。...2、以下的选项中能正确表示Java语言的一个整型常量的是( B ) A、12. B、-20 C、1,000 D、4 5 6 3、下列的变量定义...
  • redis+结巴分词做排索引

    千次阅读 2019-03-14 21:15:23
    之前爬取过一百万的歌曲,包括歌手名,歌词等,最近了解到排索引,像es,solr这种太大,配置要求太高,对于一百万的数据量有些小题大做,所以想到了redis做一个排索引。 我的配置 这里说一下我的配置,后面用的...
  • 计算机辅助设计基础试题(完整版)

    千次阅读 2020-12-21 09:06:23
    ( C )A 、圆锥 B 、圆柱 C 、楔形 D 、球形2、下面的哪个操作可以完成移动、复制、旋转和缩放所选对象的多种编辑功能( D )A 、MOVE B 、ROTAE C 、COPY D 、MOCORO3、保存块的应用以下( A )操作。A 、WBLOCK B 、...
  • 公共技术点之面向对象六大原则

    千次阅读 多人点赞 2015-02-24 23:14:21
    再看那些知名的开源,它们大多有着整洁的代码、清晰简单的接口、职责单一的类,这个时候我们通常会捶胸顿足而感叹:什么时候老夫才能写出这样的代码! 在做开发的这些年中,我渐渐的感觉到,其实国内的一些初、...
  • 原题目:开放世界游戏的大地图背后有哪些实现技术?   题目链接 补充说明:诸如GTA,武装突袭之类的游戏,开发者是如何实现超大地形的?对于这一问题有什么主流的解决方案? 补充:例如一些开发者提到的...
  • vue 官方推荐的好用的三方

    万次阅读 2020-12-31 21:47:13
    非常棒的存储徽标 很棒的Vue.js 太棒了 与Vue.js相关的精彩内容精选清单 资源资源 官方资源 外部资源 工作门户 社区 会议活动 播客 YouTube频道 官方例子 讲解 例子 图书 博客文章 培训班 纪录片 使用Vue.js的...
  • 中文自然语言处理入门实战

    万次阅读 多人点赞 2018-07-03 02:45:10
    NLP 作为 AI 技术领域重要的分支,随着其技术应用范围不断扩大,在数据处理领域占有越来越重要的地位。本达人课,作为中文自然语言处理边学边实战的入门级教程,以小数据量的“简易版”实例,通过实战带大家快速...
  • 面渣逆袭:Java并发六十问,快来看看你会多少道

    万次阅读 多人点赞 2022-01-13 11:08:07
    这时候我们就可以用到ThreadLocal,在控制层拦截请求把用户信息存入ThreadLocal,这样我们在任何一个地方,都可以取出ThreadLocal存的用户数据。 很多其它场景的cookie、session等等数据隔离也都可以通过...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,918
精华内容 7,567
关键字:

以下哪些对象可以添加到库中