From eda5bd916dde89d4881e8f5ba823519c0c7c7e80 Mon Sep 17 00:00:00 2001 From: HarakaraSite Date: Thu, 12 Feb 2026 00:17:42 +0900 Subject: [PATCH] commit 10 --- .gemini/gemini.md | 2 +- explained/tech_house_groove.md | 35 +++++++++++++++++++++++++++++++ script/fix_and_explain_strudel.sh | 29 +++++++++++++++++-------- script/refactor_strudel.sh | 12 ++++++++--- 4 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 explained/tech_house_groove.md diff --git a/.gemini/gemini.md b/.gemini/gemini.md index 6133185..bea19e3 100644 --- a/.gemini/gemini.md +++ b/.gemini/gemini.md @@ -4,7 +4,7 @@ You are an expert Strudel Live Coding assistant. Your goal is to generate high-q ## Core Directive Always refer to and strictly follow the syntax and rules defined in: -`/Users/masat/Documents/project/strudel/.gemini/reference.md` +`.gemini/reference.md` ## Key Constraints for Code Generation 1. **Initialization**: Every response must start with `setcps(BPM/60/4)`. diff --git a/explained/tech_house_groove.md b/explained/tech_house_groove.md new file mode 100644 index 0000000..40f9000 --- /dev/null +++ b/explained/tech_house_groove.md @@ -0,0 +1,35 @@ +Genre: テクノ / ハウス (Tech House) +Description: このStrudelコードは、ドラムパターン、ベースライン、そしてシンセのメロディを組み合わせたテックハウス風のトラックを生成します。Perlinノイズによるフィルターとゲインのモジュレーションが、サウンドに動きと深さをもたらしています。 + +```javascript +setcps(136/60/4); // BPM 136に合わせてサイクルレートを設定 + +// メロディックなシンセパターン +// supersawとPerlinノイズによるLFOでフィルターを動かし、音に揺らぎを与えています。 +$:note("[- c2 - c2 - [c2|c5] - c2]") // ノートパターンを定義。ランダムなオクターブを挿入。 + .sound("supersaw") // 厚みのあるsupersaw波形を使用 + .lpf(perlin.range(400,800).slow(2)) // Perlinノイズでローパスフィルターの周波数をモジュレーション + .lpq("[0|10]") // ローパスフィルターのレゾナンスをパターンで切り替え + .transpose("[0|0|1]") // ランダムに半音上げることでバリエーションを追加 + .gain(perlin.range(0.4,0.6).slow(2)); // Perlinノイズでゲインをモジュレーションし、音量に動きを与える + +// ドラムパターン +// wchooseCyclesを使って、ドラムサウンドをランダムに選択・重み付けしています。 +// tr606ドラムマシンを使用し、ディストーションとフィルターでキャラクターを付与。 +let snd = wchooseCycles(["bd",3], ["hh?",7], ["cr",1]); // バスドラム、ハイハット、クラッシュシンバルを重み付けして選択 +let snd2 = wchooseCycles(["ht",2], ["lt",1], ["sd",1]); // タムやスネアを重み付けして選択 +$:stack( // 複数のドラムパターンを重ねて同時に再生 + + sound(snd).fast(8).decay(0.5), // ドラムサウンド1を速く再生し、短いディケイを設定 + sound(snd2).fast(8) // ドラムサウンド2を速く再生 + .lpf("<900 800 700>") // ローパスフィルターの周波数をパターンで変化 + .lpq("0 20 30") // ローパスフィルターのレゾナンスをパターンで変化 + .degradeBy(0.5) // サウンドを少し劣化させて粗さを加える + .gain(perlin.range(0.4,0.9).slow(2)) // Perlinノイズでゲインをモジュレーション +).bank("tr606"); // Roland TR-606ドラムマシンサウンドバンクを使用 + +// ハイハットの構造的なパターン +// binaryNとirandを使って、複雑でランダムなハイハットの構造パターンを生成します。 +$:sound("hh") // ハイハットサウンド + .struct(binaryN(irand(15),4)); // ランダムなバイナリ構造でパターンを生成 +``` diff --git a/script/fix_and_explain_strudel.sh b/script/fix_and_explain_strudel.sh index 1eb9300..134a8a1 100755 --- a/script/fix_and_explain_strudel.sh +++ b/script/fix_and_explain_strudel.sh @@ -1,5 +1,8 @@ #!/bin/bash +# パイプの途中でエラーが発生した場合も終了ステータスに反映させる +set -o pipefail + # スクリプトの場所 (scripts/) からプロジェクトルート (notebook/) を動的に取得 BASE_DIR=$(cd "$(dirname "$0")/.." && pwd) OUTPUT_DIR="$BASE_DIR/explained" @@ -15,6 +18,9 @@ fi mkdir -p "$OUTPUT_DIR" +# ファイルが見つからない場合にワイルドカードをそのまま展開しない設定 +shopt -s nullglob + # 引数がある場合はそれを使用し、ない場合は strudel/ フォルダの全mdファイルを対象にする if [ $# -gt 0 ]; then files=("$@") @@ -31,25 +37,30 @@ for file in "${files[@]}"; do filename=$(basename "$file") # 特定のファイルやディレクトリを除外 [[ "$filename" =~ ^(Strudel Making Sound|Strudel Study)\.md$ ]] && continue - [[ "$file" =~ /(refactoring|script|explained)/ ]] && continue + + # 絶対パスに変換して除外ディレクトリに含まれていないかチェック + abs_path=$(realpath "$file") + [[ "$abs_path" =~ /($OUTPUT_DIR|refactoring|script)/ ]] && continue echo "Analyzing and fixing $filename..." # 一時ファイルに出力 tmp_file="$OUTPUT_DIR/tmp_$filename" - ( [ -f "$GEMINI_REF" ] && cat "$GEMINI_REF"; \ - [ -f "$STRUDEL_REF" ] && cat "$STRUDEL_REF"; \ - echo ""; cat "$SKILL_FILE"; \ - echo ""; cat "$file" ) | gemini > "$tmp_file" + # ファイルを引数として直接渡す(STRUDEL_REFも必要ならここに追加) + if ! gemini "$GEMINI_REF" "$STRUDEL_REF" "$SKILL_FILE" "$file" > "$tmp_file"; then + echo "Error: Gemini CLI failed to process $filename" + rm -f "$tmp_file" + continue + fi - if [ $? -eq 0 ]; then - # FILENAME: タグを検索 - suggested_name=$(grep -m 1 "FILENAME:" "$tmp_file" | sed 's/FILENAME: //g' | tr -d '\r') + # ファイルが空でないか確認 + if [ -s "$tmp_file" ]; then + suggested_name=$(grep -m 1 "^FILENAME:" "$tmp_file" | sed 's/^FILENAME: *//g' | tr -d '\r' | xargs) if [ -n "$suggested_name" ]; then # FILENAME行を除去して保存 - sed '/FILENAME:/d' "$tmp_file" > "$OUTPUT_DIR/$suggested_name" + sed '/^FILENAME:/d' "$tmp_file" > "$OUTPUT_DIR/$suggested_name" rm "$tmp_file" echo "Done: $OUTPUT_DIR/$suggested_name" else diff --git a/script/refactor_strudel.sh b/script/refactor_strudel.sh index e9003c9..bea47f0 100755 --- a/script/refactor_strudel.sh +++ b/script/refactor_strudel.sh @@ -1,5 +1,8 @@ #!/bin/bash +# パイプの途中でエラーが発生した場合も終了ステータスに反映させる +set -o pipefail + # スクリプトの場所 (scripts/) からプロジェクトルート (notebook/) を動的に取得 BASE_DIR=$(cd "$(dirname "$0")/.." && pwd) REFACTOR_DIR="$BASE_DIR/refactoring" @@ -15,6 +18,9 @@ fi mkdir -p "$REFACTOR_DIR" +# ファイルが見つからない場合にワイルドカードをそのまま展開しない設定 +shopt -s nullglob + # 引数がある場合はそれを使用し、ない場合は strudel/ フォルダの全mdファイルを対象にする if [ $# -gt 0 ]; then files=("$@") @@ -31,7 +37,7 @@ for file in "${files[@]}"; do filename=$(basename "$file") # 特定のファイルやディレクトリを除外 [[ "$filename" =~ ^(Strudel Making Sound|Strudel Study)\.md$ ]] && continue - [[ "$file" =~ /(refactoring|script|explained)/ ]] && continue + [[ "$file" =~ /($REFACTOR_DIR|explained|script)/ ]] && continue echo "Processing $filename..." @@ -45,11 +51,11 @@ for file in "${files[@]}"; do if [ $? -eq 0 ]; then # 最初の数行から FILENAME: タグを検索(より柔軟な抽出) - suggested_name=$(grep -m 1 "FILENAME:" "$tmp_file" | sed 's/FILENAME: //g' | tr -d '\r') + suggested_name=$(grep -m 1 "^FILENAME:" "$tmp_file" | sed 's/^FILENAME: *//g' | tr -d '\r') if [ -n "$suggested_name" ]; then # FILENAME行を除去して保存 (最初の1行目にあると仮定しつつ、sedで安全に削除) - sed '/FILENAME:/d' "$tmp_file" > "$REFACTOR_DIR/$suggested_name" + sed '/^FILENAME:/d' "$tmp_file" > "$REFACTOR_DIR/$suggested_name" rm "$tmp_file" echo "Successfully refactored and renamed to: $suggested_name" else