Linux用のビート検出ソフトウェアはありますか?[閉まっている]


29

Amarok 2は、ID3v2タグの「bpm」フィールドを使用して音楽コレクションを検索できます。音楽コレクション全体にタグを付け直して、好きなトラックの「気分」を見つけることができるのはとてもいいことです。

しかし、私を助けてくれるビート検出ソフトウェアは見つかりませんでした。使用したことがありますか?CLI、できれば。また、同じ「bpm」フィールドでFLACにタグを付けるために似たようなものがあるかどうかにも興味があります。

ありがとう!:)

PSいい気分バー機能があることを知っていますが、検索には役に立たない。


3
このページを見たことがありますか?mmartins.com/mmartins/bpmdetection/bpmdetection.asp まさにあなたが探しているもののようです。
-DaveParillo

@DaveParilloは、「トラックの気分」リンクはハードディスクへのリンクであり、あなた以外の誰にとっても役に立たない
ジャスティンスミス

@Justinスミスは、彼がBpmDjドキュメント内のファイルを意味:)ここでのオンライン版です:bpmdj.yellowcouch.org/clustering.html
kolypto

@ジャスティン-ごめんなさい-震える引き金の指、私は推測する。
-DaveParillo

回答:


17

サイトで、DaveParilloはBpmDjプロジェクトを見つけたと提案しました。bpmcountbpmを計算する実行可能ファイルがあり、mplacとflacを処理します。

161.135 Metallica/2008 - Death Magnetic/01-That Was Just Your Life.flac
63.5645 Doom3.mp3

残っているのは、コレクションにタグを付け直すことだけです。成功するたびにこの回答を更新します。ありがとう!:)


ステップ1

bpmcountコレクション全体に対して実行し、結果をテキストファイルに保存します。問題は、bpmcountいくつかのファイルを処理するときに時々クラッシュし、最大2GBのメモリを消費しようとするため、ファイル名を1つずつ入力する必要があることです。このような:

musicdir='/home/ootync/music'
find "$musicdir" -iregex ".*\.\(mp3\|ogg\|flac\|ape\)" -exec bpmcount {} \; \
    | fgrep "$musicdir" > "$musicdir/BPMs.txt"

ステップ2

追加のパッケージが必要になります:apt-get install vorbis-tools flac python-mutagen。「bpm」タグを追加する方法を見てみましょう。

mid3v2 --TBPM 100 doom3.mp3
vorbiscomment -a -t "BPM=100" mother.ogg
metaflac --set-tag="BPM=100" metallica.flac

残念ながら、*。apeトラックはありません

これでBPMができました。コレクション全体にタグを付け直す必要があります。スクリプトは次のとおりです。

cat "$musicdir/BPMs.txt" | while read bpm file ; do
    bpm=`printf "%.0f" "$bpm"` ;
    case "$file" in 
        *.mp3) mid3v2 --TBPM "$bpm" "$file" > /dev/null ;; 
        *.ogg) vorbiscomment -a -t "BPM=$bpm" "$file" ;; 
        *.flac) metaflac --set-tag="BPM=$bpm" "$file" ;; 
        esac
    done

ステップ2.1再訪 これは、コレクションにBPMタグを追加するスクリプトです。

CPUコアごとに1つのプロセスを実行して、プロセスを高速化します。さらに、一時ファイルを使用せず、ファイルに既にタグが付けられているかどうかを検出できます。

さらに、FLACにはID3とVorbisCommentの両方が含まれていることがあることがわかりました。このスクリプトは両方を更新します。

#!/bin/bash

function display_help() {
    cat <<-HELP
            Recursive BPM-writer for multicore CPUs.
            It analyzes BPMs of every media file and writes a correct tag there.
            Usage: $(basename "$0") path [...]
            HELP
    exit 0
    }

[ $# -lt 1 ] && display_help

#=== Requirements
requires="bpmcount mid3v2 vorbiscomment metaflac"
which $requires > /dev/null || { echo "E: These binaries are required: $requires" >&2 ; exit 1; }

#=== Functions

function bpm_read(){
    local file="$1"
    local ext="${file##*.}"
    declare -l ext
    # Detect
    { case "$ext" in
        'mp3')  mid3v2 -l "$file" ;;
        'ogg')  vorbiscomment -l "$file" ;;
        'flac') metaflac --export-tags-to=- "$file" ;;
        esac ; } | fgrep 'BPM=' | cut -d'=' -f2
    }
function bpm_write(){
    local file="$1"
    local bpm="${2%%.*}"
    local ext="${file##*.}"
    declare -l ext
    echo "BPM=$bpm @$file"
    # Write
    case "$ext" in
        'mp3')  mid3v2 --TBPM "$bpm" "$file" ;;
        'ogg')  vorbiscomment -a -t "BPM=$bpm" "$file" ;;
        'flac') metaflac --set-tag="BPM=$bpm" "$file"
                mid3v2 --TBPM "$bpm" "$file" # Need to store to ID3 as well :(
                ;;
        esac
    }

#=== Process
function oneThread(){
    local file="$1"
    #=== Check whether there's an existing BPM
        local bpm=$(bpm_read "$file")
        [ "$bpm" != '' ] && return 0 # there's a nonempty BPM tag
    #=== Detect a new BPM
    # Detect a new bpm
    local bpm=$(bpmcount "$file" | grep '^[0-9]' | cut -f1)
    [ "$bpm" == '' ] && { echo "W: Invalid BPM '$bpm' detected @ $file" >&2 ; return 0 ; } # problems
    # Write it
    bpm_write "$file" "${bpm%%.*}" >/dev/null
    }

NUMCPU="$(grep ^processor /proc/cpuinfo | wc -l)"
find $@ -type f -regextype posix-awk -iregex '.*\.(mp3|ogg|flac)' \
    | while read file ; do
        [ `jobs -p | wc -l` -ge $NUMCPU ] && wait
        echo "$file"
        oneThread "$file" &
        done

楽しい!:)


優れた!私はこの昨夜やってみようとはしなかった。コマンドラインのタグ付けに関しては、少なくともEx Fがコマンドライン編集をサポートするまで、mid3v2:linux.die.net/man/1/mid3v2を試してみてください 。id3v2 tad idはTBPM
DaveParillo

1
おかげで、私は数日で試して結果を投稿します:) FLACがそのようなことをサポートしているかどうか疑問に思います:これをチェックアウトする必要があります。
-kolypto

1
ステップ#2の素晴らしい作業。二度投票できたらいいのに!
-DaveParillo

1
ありがとう:)残念ながら、私のAmarokは、FLACの新しいタグに気付きませんでした。
コリプト

どのようにインストールしましたか?それらが提供するrpmは私のコンピューターでは動作しないようで、コンパイルに苦労しています。
ペドロサウリオ


6

私はkolyptoの元のスクリプトを使用しbpmcount、それをbpm-tag(ユーティリティbpm-tools)に書き換えて使用しました。また、私自身のいくつかの改善を行いました。

GitHub https://github.com/meridius/bpmwrapで見つけることができます


(それはコメントが長すぎるため)これは私が以下の私自身の答えに含まれているMac、上の仕事にいくつかの変更を必要と
エイドリアン

2

あなたが探しているものを正確に実行するツールは知りませんが、MusicIPいじってみました

linux / javaバージョンを使用しました。音楽ライブラリを完全に分析するには時間がかかりますが、実際には機能します。他の曲に似ている曲を見つけることができます。生成されたプレイリストを右クリックし、オプションを選択して、選択した曲のように、より多いまたは少ない曲を選択できます。特定のジャンルを削除することもできます。それは一種のクールですが、すごい要因がすり減った後、私はそれを使用することを止めました。

無料版では、プレイリストを最大75曲(少なくとも)m3u形式でエクスポートします。

現在はサポートされていませんが、Predexisとして商用化しようとしていると思います。


1

あなたが探していると言うような単なるツールではありませんが、Bansheeメディアプレーヤーはbpmを検出できます。

私はすべての音楽の再生、整理、およびポータブルプレーヤーへの同期にBansheeを使用しています。私はアフィリエイトではありませんが、私が試したすべてのプログラムの中で一番好きです。また、bpmを含むトラックのあらゆる種類のプロパティに基づいて「スマートプレイリスト」を生成することもできます。

曲に関するあらゆる種類のことを分析し、あなたが演奏している曲に似た曲を見つける拡張機能があります。Mirageと呼ばれ、しばらく使用しましたが、さまざまな気分に合ったプレイリストを多数作成したので、もう使用しません(Mirageによると必ずしも同じではありません)。

Bansheeが検出したbpmをファイルのID3v2「bpm」タグに保存するかどうかはわかりません。誰かがプログラム外からbpmタグを簡単にチェックする方法を知っているなら、チェックします。



0

MP3ファイルに正しいBPM値をタグ付けする別のツールを見つけました。

BPMDetectと呼ばれます。オープンソース。QTライブラリはGnomeの下でも問題なく動作します。GUIが付属していますが、コンソールのみのバージョンとしてコンパイルできます(readme.txtに記載されている「scons console = 1」を実行します)。

それ以外の場合、最終的には、64ビットUbuntuホストでBPMDetectをコンパイルするのが困難だったため(fmodexの依存関係のため)、BpmDJの「bpmcount」も使用しました。そこで、上記の(非常にクールでよく書かれた)シェルスクリプト(以下を参照)、BpmDJ Webサイトで入手可能な[x64 .rpm] [3]から抽出された「bpmcount」バイナリ(.rpmを抽出しただけ)と

pm2cpio bpmdj-4.2.pl2-0.x86_64.rpm|cpio -idv

そしてそれは魅力のように働いた。上記のスクリプトを変更する必要があったのは、箱から出してすぐには動作しなかったためです(bpmcountバイナリのstdout / stderrの問題)。私の変更はファイルのリダイレクトに関するものです:

local bpm=$(bpmcount "$file" 3>&1 1>/dev/null 2>&3 | grep '^[0-9]' | cut -f1)

0

stackoverflowに関するこの質問で推奨される別のツールがあります:aubio、これはPythonモジュールに付属しています。

BpmDjをコンパイルするのに忙しかったので、試していませんでした。他の誰かが同様のトラブルに苦しんでいることに気付いた場合に備えて、絶対に確認することを強くお勧めします:

  1. BpmDjソースの最新リリースをダウンロードした
  2. 適切なブーストライブラリがインストールされている

最新のg ++​​コンパイラのアップグレードでは、特に最近のdebianおよびubuntuリリースに関していくつかの問題が発生したようです。彼がこれらの問題に気づくとすぐに、作者は現れた非互換性を修正し、今では魅力のようにコンパイルされる新しいリリースをまとめる親切さを持ちました。だから、最近容赦ないコンパイルエラーで絶望に陥っている人は誰でも:あなたは今救われています。

@ mmx、あなたのツールも見た目は良いSoXですが、デフォルトではmp3機能を持たないに依存しています。そのため、最初にLame / MADサポートを使用してSoXをコンパイルする必要がありますが、残念ながら私と同じくらい怠け者にとってはあまりにも手間がかかります。


0

Macで@meridiusのソリューションを動作させるには、少し余分な作業を行い、スクリプトを少し変更する必要がありました。

# Let's install bpm-tools
git clone http://www.pogo.org.uk/~mark/bpm-tools.git
cd bpm-tools
make && make install
# There will be errors, but they did not affect the result

# The following three lines could be replaced by including this directory in your $PATH
ln -s <absolute path to bpm-tools>/bpm /usr/local/bin/bpm
ln -s <absolute path to bpm-tools>/bpm-tag /usr/local/bin/bpm-tag
ln -s <absolute path to bpm-tools>/bpm-graph /usr/local/bin/bpm-graph
cd ..

# Time to install a bunch of GNU tools
# Not all of these packages are strictly necessary for this script, but I decided I wanted the whole GNU toolchain in order to avoid this song-and-dance in the future
brew install coreutils findutils gnu-tar gnu-sed gawk gnutls gnu-indent gnu-getopt bash flac vorbis-tools
brew tap homebrew/dupes; brew install grep

# Now for Mutagen (contains mid3v2)
git clone https://github.com/nex3/mutagen.git
cd mutagen
./setup.py build
sudo ./setup.py install
# There will be errors, but they did not affect the result
cd ..

それから、すべてのGNUバージョンを指すようにスクリプトを修正する必要がありました。

#!/usr/local/bin/bash

# ================================= FUNCTIONS =================================

function help() {
    less <<< 'BPMWRAP

Description:
    This BASH script is a wrapper for bpm-tag utility of bpm-tools and several
    audio tagging utilities. The purpose is to make BPM (beats per minute)
    tagging as easy as possible.
    Default behaviour is to look through working directory for *.mp3 files
    and compute and print their BPM in the following manner:
        [current (if any)] [computed] [filename]

Usage:
    bpmwrap [options] [directory or filenames]

Options:
    You can specify files to process by one of these ways:
        1) state files and/or directories containing them after options
        2) specify --import file
        3) specify --input file
    With either way you still can filter the resulting list using --type option(s).
    Remember that the script will process only mp3 files by default, unless
    specified otherwise!

    -i, --import file
        Use this option to set BPM tag for all files in given file instead of
        computing it. Expected format of every row is BPM number and absolute path
        to filename separated by semicolon like so:
            145;/home/trinity/music/Apocalyptica/07 beyond time.mp3
        Remember to use --write option too.
    -n, --input file
        Use this option to give the script list of FILES to process INSTEAD of paths
        where to look for them. Each row whould have one absolute path.
        This will bypass the searching part and is that way useful when you want
        to process large number of files several times. Like when you are not yet
        sure what BPM limits to set. Extension filtering will still work.
    -o, --output file
        Save output also to a file.
    -l, --list-save file
        Save list of files about to get processed. You can use this list later
        as a file for --input option.
    -t, --type filetype
        Extension of file type to work with. Defaults to mp3. Can be specified
        multiple times for more filetypes. Currently supported are mp3 ogg flac.
    -e, --existing-only
        Only show BPM for files that have it. Do NOT compute new one.
    -w, --write
        Write computed BPM to audio file but do NOT overwrite existing value.
    -f, --force
        Write computed BPM to audio file even if it already has one. Aplicable only
        with --write option.
    -m, --min minbpm
        Set minimal BPM to look for when computing. Defaults to bpm-tag minimum 84.
    -x, --max maxbpm
        Set maximal BPM to look for when computing. Defaults to bpm-tag maximum 146.
    -v, --verbose
        Show "progress" messages.
    -c, --csv-friendly
        Use semicolon (;) instead of space to separate output columns.
    -h, --help
        Show this help.

Note:
    Program bpm-tag (on whis is this script based) is looking only for lowercase
    file extensions. If you get 0 (zero) BPM, this should be the case. So just
    rename the file.

License:
    GPL V2

Links:
    bpm-tools (http://www.pogo.org.uk/~mark/bpm-tools/)

Dependencies:
    bpm-tag mid3v2 vorbiscomment metaflac

Author:
    Martin Lukeš (martin.meridius@gmail.com)
    Based on work of kolypto (http://superuser.com/a/129157/137326)
    '
}

# Usage: result=$(inArray $needle haystack[@])
# @param string needle
# @param array haystack
# @returns int (1 = NOT / 0 = IS) in array
function inArray() {
    needle="$1"
    haystack=("${!2}")
    out=1
    for e in "${haystack[@]}" ; do
        if [[ "$e" = "$needle" ]] ; then
            out=0
            break
        fi
    done
    echo $out
}

# Usage: result=$(implode $separator array[@])
# @param char separator
# @param array array to implode
# @returns string separated array elements
function implode() {
    separator="$1"
    array=("${!2}")
    IFSORIG=$IFS
    IFS="$separator"
    echo "${array[*]}"
    IFS=$IFSORIG
}

# @param string file
# @returns int BPM value
function getBpm() {
    local file="$1"
    local ext="${file##*.}"
    declare -l ext # convert to lowercase
    { case "$ext" in
        'mp3')  mid3v2 -l "$file" ;;
        'ogg')  vorbiscomment -l "$file" ;;
        'flac') metaflac --export-tags-to=- "$file" ;;
    esac ; } | fgrep 'BPM=' -a | cut -d'=' -f2
}

# @param string file
# @param int BPM value
function setBpm() {
    local file="$1"
    local bpm="${2%%.*}"
    local ext="${file##*.}"
    declare -l ext # convert to lowercase
    case "$ext" in
        'mp3')  mid3v2 --TBPM "$bpm" "$file" ;;
        'ogg')  vorbiscomment -a -t "BPM=$bpm" "$file" ;;
        'flac') metaflac --set-tag="BPM=$bpm" "$file"
            mid3v2 --TBPM "$bpm" "$file" # Need to store to ID3 as well :(
        ;;
    esac
}

# # @param string file
# # @returns int BPM value
function computeBpm() {
    local file="$1"
    local m_opt=""
    [ ! -z "$m" ] && m_opt="-m $m"
    local x_opt=""
    [ ! -z "$x" ] && x_opt="-x $x"
    local row=$(bpm-tag -fn $m_opt $x_opt "$file" 2>&1 | fgrep "$file")
    echo $(echo "$row" \
        | gsed -r 's/.+ ([0-9]+\.[0-9]{3}) BPM/\1/' \
        | gawk '{printf("%.0f\n", $1)}')
}

# @param string file
# @param int file number
# @param int BPM from file list given by --import option
function oneThread() {
    local file="$1"
    local filenumber="$2"
    local bpm_hard="$3"
    local bpm_old=$(getBpm "$file")
    [ -z "$bpm_old" ] && bpm_old="NONE"
    if [ "$e" ] ; then # only show existing
        myEcho "$filenumber/$NUMFILES${SEP}$bpm_old${SEP}$file"
    else # compute new one
        if [ "$bpm_hard" ] ; then
            local bpm_new="$bpm_hard"
        else
            local bpm_new=$(computeBpm "$file")
        fi
        [ "$w" ] && { # write new one
            if [[ ! ( ("$bpm_old" != "NONE") && ( -z "$f" ) ) ]] ; then
                setBpm "$file" "$bpm_new"
            else
                [ "$v" ] && myEcho "Non-empty old BPM value, skipping ..."
            fi
        }
        myEcho "$filenumber/$NUMFILES${SEP}$bpm_old${SEP}$bpm_new${SEP}$file"
    fi
}

function myEcho() {
    [ "$o" ] && echo -e "$1" >> "$o"
    echo -e "$1"
}


# ================================== OPTIONS ==================================

eval set -- $(/usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt -n $0 -o "-i:n:o:l:t:ewfm:x:vch" \
    -l "import:,input:,output:,list-save:,type:,existing-only,write,force,min:,max:,verbose,csv-friendly,help" -- "$@")

declare i n o l t e w f m x v c h
declare -a INPUTFILES
declare -a INPUTTYPES
while [ $# -gt 0 ] ; do
    case "$1" in
        -i|--import)                shift ; i="$1" ; shift ;;
        -n|--input)                 shift ; n="$1" ; shift ;;
        -o|--output)                shift ; o="$1" ; shift ;;
        -l|--list-save)         shift ; l="$1" ; shift ;;
        -t|--type)                  shift ; INPUTTYPES=("${INPUTTYPES[@]}" "$1") ; shift ;;
        -e|--existing-only) e=1 ; shift ;;
        -w|--write)                 w=1 ; shift ;;
        -f|--force)                 f=1 ; shift ;;
        -m|--min)                       shift ; m="$1" ; shift ;;
        -x|--max)                       shift ; x="$1" ; shift ;;
        -v|--verbose)               v=1 ; shift ;;
        -c|--csv-friendly)  c=1 ; shift ;;
        -h|--help)                  h=1 ; shift ;;
        --)                                 shift ;;
        -*)                                 echo "bad option '$1'" ; exit 1 ;; #FIXME why this exit isn't fired?
        *)                                  INPUTFILES=("${INPUTFILES[@]}" "$1") ; shift ;;
    esac
done


# ================================= DEFAULTS ==================================

#NOTE Remove what requisities you don't need but don't try to use them after!
#         always  mp3/flac     ogg       flac
REQUIRES="bpm-tag mid3v2 vorbiscomment metaflac"
which $REQUIRES > /dev/null || { myEcho "These binaries are required: $REQUIRES" >&2 ; exit 1; }

[ "$h" ] && {
    help
    exit 0
}

[[ $m && $x && ( $m -ge $x ) ]] && {
    myEcho "Minimal BPM can't be bigger than NOR same as maximal BPM!"
    exit 1
}
[[ "$i" && "$n" ]] && {
    echo "You cannot specify both -i and -n options!"
    exit 1
}
[[ "$i" && ( "$m" || "$x" ) ]] && {
    echo "You cannot use -m nor -x option with -i option!"
    exit 1
}
[ "$e" ] && {
    [[ "$w" || "$f" ]] && {
        echo "With -e option you don't have any value to write!"
        exit 1
    }
    [[ "$m" || "$x" ]] && {
        echo "With -e option you don't have any value to count!"
        exit 1
    }
}

for file in "$o" "$l" ; do
    if [ -f "$file" ] ; then
        while true ; do
            read -n1 -p "Do you want to overwrite existing file ${file}? (Y/n): " key
            case "$key" in
                y|Y|"") echo "" > "$file" ; break ;;
                n|N)        exit 0 ;;
            esac
            echo ""
        done
        echo ""
    fi
done

[ ${#INPUTTYPES} -eq 0 ] && INPUTTYPES=("mp3")

# NUMCPU="$(ggrep ^processor /proc/cpuinfo | wc -l)"
NUMCPU="$(sysctl -a | ggrep machdep.cpu.core_count | gsed -r 's/(.*)([0-9]+)(.*)/\2/')"
LASTPID=0
TYPESALLOWED=("mp3" "ogg" "flac")
# declare -A BPMIMPORT # array of BPMs from --import file, keys are file names
declare -A BPMIMPORT # array of BPMs from --import file, keys are file names

for type in "${INPUTTYPES[@]}" ; do
    [[ $(inArray $type TYPESALLOWED[@]) -eq 1 ]] && {
        myEcho "Filetype $type is not one of allowed types (${TYPESALLOWED[@]})!"
        exit 1
    }
done

### here are three ways how to pass files to the script...
if [ "$i" ] ; then # just parse given file list and set BPM to listed files
    if [ -f "$i" ] ; then
        # myEcho "Setting BPM tags from given file ..."
        while read row ; do
            bpm="${row%%;*}"
            file="${row#*;}"
            ext="${file##*.}"
            ext="${ext,,}" # convert to lowercase
            if [ -f "$file" ] ; then
                if [ $(inArray $ext INPUTTYPES[@]) -eq 0 ] ; then
                    FILES=("${FILES[@]}" "$file")
                    BPMIMPORT["$file"]="$bpm"
                else
                    myEcho "Skipping file on row $rownumber (unwanted filetype $ext) ... $file"
                fi
            else
                myEcho "Skipping non-existing file $file"
            fi
        done < "$i"
    else
        myEcho "Given import file does not exists!"
        exit 1
    fi
elif [ "$n" ] ; then # get files from file list
    if [ -f "$n" ] ; then
        rownumber=1
        while read file ; do
            if [ -f "$file" ] ; then
                ext="${file##*.}"
                ext="${ext,,}" # convert to lowercase
                if [ $(inArray $ext INPUTTYPES[@]) -eq 0 ] ; then
                    FILES=("${FILES[@]}" "$file")
                else
                    myEcho "Skipping file on row $rownumber (unwanted filetype $ext) ... $file"
                fi
            else
                myEcho "Skipping file on row $rownumber (non-existing) ... $file"
            fi
            let rownumber++
        done < "$n"
        unset rownumber
    else
        myEcho "Given input file $n does not exists!"
        exit 1
    fi
else # get files from given parameters
    [ ${#INPUTFILES[@]} -eq 0 ] && INPUTFILES=`pwd`
    for file in "${INPUTFILES[@]}" ; do
        [ ! -e "$file" ] && {
            myEcho "File or directory $file does not exist!"
            exit 1
        }
    done
    impl_types=`implode "|" INPUTTYPES[@]`
    while read file ; do
        echo -ne "Creating list of files ... (${#FILES[@]}) ${file}\033[0K"\\r
        FILES=("${FILES[@]}" "$file")
    done < <(gfind "${INPUTFILES[@]}" -type f -regextype posix-awk -iregex ".*\.($impl_types)")
    echo -e "Counted ${#FILES[@]} files\033[0K"\\r
fi

[ "$l" ] && printf '%s\n' "${FILES[@]}" > "$l"

NUMFILES=${#FILES[@]}
FILENUMBER=1

[ $NUMFILES -eq 0 ] && {
    myEcho "There are no ${INPUTTYPES[@]} files in given files/paths."
    exit 1
}

declare SEP=" "
[ "$c" ] && SEP=";"


# =============================== MAIN SECTION ================================

if [ "$e" ] ; then # what heading to show
    myEcho "num${SEP}old${SEP}filename"
else
    myEcho "num${SEP}old${SEP}new${SEP}filename"
fi

for file in "${FILES[@]}" ; do
    [ `jobs -p | wc -l` -ge $NUMCPU ] && wait
    [ "$v" ] && myEcho "Parsing (${FILENUMBER}/${NUMFILES})\t$file ..."
    oneThread "$file" "$FILENUMBER" "${BPMIMPORT[$file]}" &
    LASTPID="$!"
    let FILENUMBER++
done

[ "$v" ] && myEcho "Waiting for last process ..."
wait $LASTPID
[ "$v" ] && myEcho \\n"DONE"

@kolyptoと@meridiusのご苦労に感謝します。

... CLIワークフローを維持し、音楽ツールにお金を払わないために私が経験する痛み...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.