From ed0f380f53429d26fb4389ef4ab3281fd226af4d Mon Sep 17 00:00:00 2001 From: Bruno de Lima Date: Wed, 12 Aug 2026 22:22:18 -0300 Subject: [PATCH 1/2] Add document about supported wave formats --- docs/wiki/supported_wav_formats.md | 57 ++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 docs/wiki/supported_wav_formats.md diff --git a/docs/wiki/supported_wav_formats.md b/docs/wiki/supported_wav_formats.md new file mode 100644 index 00000000..34b5a149 --- /dev/null +++ b/docs/wiki/supported_wav_formats.md @@ -0,0 +1,57 @@ +# Supported WAV formats + +Little Piggy Tracker loads samples as **16-bit PCM WAV** (`WAVE_FORMAT_PCM`, +compression code `1`). That is the format used by the classic tracker +sample pools and the one you should export to. + +## What works + +| Format | Compression code | Result | +|---------------------------------|------------------|-----------------------------------------| +| PCM 16-bit, mono | `1` | Full support | +| PCM 16-bit, stereo | `1` | Full support | +| PCM 16-bit with a `JUNK` chunk | `1` | Supported (the `JUNK` chunk is skipped) | +| PCM 8-bit, mono | `1` | Loads (expanded to 16-bit on load) | +| PCM 8-bit, stereo | `1` | Loads but the right channel is garbage | + +## What is rejected + +| Format | Compression code | Why | +|-------------------------|------------------|-------------------------------------------------| +| IEEE float (32-bit) | `3` | `Unsupported compression` — not PCM | +| ADPCM | `2` | `Unsupported compression` | +| µ-law / A-law | `6` / `7` | `Unsupported compression` | +| WAVE_FORMAT_EXTENSIBLE | `0xFFFE` | `Unsupported compression` — even if the sub-format is PCM | +| PCM 24-bit / 32-bit int | `1` | `Only 8/16 bit supported` | + +## Common gotchas + +- **WAVE_FORMAT_EXTENSIBLE** is what Windows exports when the "16-bit PCM" + option is picked from a save dialog. It looks like a normal 16-bit WAV + but carries compression code `0xFFFE` in the header, so the tracker + refuses it. Re-encode to plain PCM (`compression code 1`) to fix. +- **32-bit float** is the default export format of several DAWs and of + Audacity when "WAV (Float)" is selected. Export as WAV (PCM) 16-bit + instead. +- **24-bit** is common from audio interfaces. Not supported — convert. +- The `fmt ` chunk must declare exactly 8 or 16 bits per sample. + +## Converting a WAV + +With [sox](http://sox.sourceforge.net): + +```sh +sox in.wav out.wav # re-encodes to the input format +sox in.wav -b 16 out.wav # force 16-bit (default PCM) +``` + +With Audacity: *File → Export Audio → File type: WAV (Microsoft) → Encoding: +Signed 16-bit PCM*. + +## Where the parsing lives + +The checks live in `WavFile::Open()` +(`sources/Application/Instruments/WavFile.cpp`): + +- `comp != 1` → `"Unsupported compression"` +- `bitPerSample` not in `{8, 16}` → `"Only 8/16 bit supported"` From 86de4a65d5b6d27f43ac1a9b34b249c8ed9ad48d Mon Sep 17 00:00:00 2001 From: brunodles Date: Mon, 21 Sep 2026 06:46:04 +0000 Subject: [PATCH 2/2] Redesign ProjectView Values are not separate from the label. Labels are highlighted when the value is selected. --- CHANGELOG | 5 ++ sources/Application/Model/Project.h | 2 +- .../Views/BaseClasses/FieldView.cpp | 39 +++++++++ .../Application/Views/BaseClasses/FieldView.h | 4 + sources/Application/Views/BaseClasses/View.h | 3 + sources/Application/Views/ProjectView.cpp | 81 ++++++++++++------- 6 files changed, 102 insertions(+), 32 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d7ef511c..d83dccb5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +1.6.0-bacon21 + Redesign the Project View + * Values are not separate from the label + * Labels are highlighted when the value is selected + 1.6.0-bacon20 Fixed MIDI muting Added MIDI chord command (MCHD) diff --git a/sources/Application/Model/Project.h b/sources/Application/Model/Project.h index 38c43493..05d585c5 100644 --- a/sources/Application/Model/Project.h +++ b/sources/Application/Model/Project.h @@ -21,7 +21,7 @@ #define PROJECT_NUMBER "1" #define PROJECT_RELEASE "6" -#define BUILD_COUNT "0-bacon20" +#define BUILD_COUNT "0-bacon21" #define MAX_TAP 3 diff --git a/sources/Application/Views/BaseClasses/FieldView.cpp b/sources/Application/Views/BaseClasses/FieldView.cpp index af67d0d7..195ffcf3 100644 --- a/sources/Application/Views/BaseClasses/FieldView.cpp +++ b/sources/Application/Views/BaseClasses/FieldView.cpp @@ -289,3 +289,42 @@ int FieldView::GetFocusIndex() { } ; return focusIndex ; } + +/** + * Add highlight to labels if the index is selected + * + * This function will get the current focus index. + * Change the color. + * Change the impression mode to "invert". + * + * Print the string + * + */ +void FieldView::DrawLabel(int x, int y, int minIndex, int maxIndex, const char *txt) { + GUITextProperties props ; + int focusIndex = GetFocusIndex(); + if (focusIndex >= minIndex && focusIndex <= maxIndex) { + SetColor(CD_HILITE2); + props.invert_ = true; + } else { + SetColor(CD_COL_TITLE); + props.invert_ = false; + } + + DrawString(x,y, txt, props) ; + props.invert_ = false; +} + +/** + * Add highlight to labels if the index is selected + * + * This function will get the current focus index. + * Change the color. + * Change the impression mode to "invert". + * + * Print the string + * + */ +void FieldView::DrawLabel(int x, int y, int index, const char *txt) { + DrawLabel(x, y, index, index, txt); +} \ No newline at end of file diff --git a/sources/Application/Views/BaseClasses/FieldView.h b/sources/Application/Views/BaseClasses/FieldView.h index 00127462..a59fabe9 100644 --- a/sources/Application/Views/BaseClasses/FieldView.h +++ b/sources/Application/Views/BaseClasses/FieldView.h @@ -17,6 +17,10 @@ class FieldView: public View,public T_SimpleList { void ClearFocus() ; int GetFocusIndex() ; void SetSize(int size) ; + + virtual void DrawLabel(int x, int y, int index, const char *txt); + virtual void DrawLabel(int x, int y, int minIndex, int maxIndex, + const char *txt); private: T_SimpleList fieldList_ ; UIField *focus_ ; diff --git a/sources/Application/Views/BaseClasses/View.h b/sources/Application/Views/BaseClasses/View.h index b7edeca9..e5983d45 100644 --- a/sources/Application/Views/BaseClasses/View.h +++ b/sources/Application/Views/BaseClasses/View.h @@ -20,6 +20,9 @@ #define VU_METER_CLIP_LEVEL 7 #define VU_METER_WARN_LEVEL 5 +#define SCREEN_WIDTH 40 +#define SCREEN_HEIGHT 30 + enum GUIEventPadButtonMasks { EPBM_LEFT = 1, EPBM_DOWN = 2, diff --git a/sources/Application/Views/ProjectView.cpp b/sources/Application/Views/ProjectView.cpp index 590b684b..71c63aa4 100644 --- a/sources/Application/Views/ProjectView.cpp +++ b/sources/Application/Views/ProjectView.cpp @@ -1,4 +1,6 @@ #include "ProjectView.h" + +#include "../AppWindow.h" #include "Application/Mixer/MixerService.h" #include "Application/Model/ProjectDatas.h" #include "Application/Model/Scale.h" @@ -108,10 +110,11 @@ ProjectView::ProjectView(GUIWindow &w,ViewData *data):FieldView(w,data) { project_=data->project_ ; GUIPoint position=GetAnchor() ; - - Variable *v=project_->FindVariable(VAR_TEMPO) ; + position._x += 5; + + Variable *v=project_->FindVariable(VAR_TEMPO) ; UITempoField *f = new UITempoField(ACTION_TEMPO_CHANGED, position, *v, - "Tempo: %d [%2.2x] ", 60, 400, 1, 10); + "%d [%2.2x] ", 60, 400, 1, 10); T_SimpleList::Insert(f) ; f->AddObserver(*this) ; tempoField_=f ; @@ -119,29 +122,30 @@ ProjectView::ProjectView(GUIWindow &w,ViewData *data):FieldView(w,data) { v = project_->FindVariable(VAR_MASTERVOL); position._y += 1; UIIntVarField *field = - new UIIntVarField(position, *v, "Master: %d", 10, 100, 1, 10); + new UIIntVarField(position, *v, "%d", 10, 100, 1, 10); T_SimpleList::Insert(field); v = project_->FindVariable(VAR_PREGAIN); position._y += 2; - field = new UIIntVarField(position, *v, "Drive: %d", 10, 200, 1, 10); + field = new UIIntVarField(position, *v, "%d", 10, 200, 1, 10); T_SimpleList::Insert(field); position._y += 1; v = project_->FindVariable(VAR_SOFTCLIP); - field = new UIIntVarField(position, *v, "Type: %s", 0, 4, 1, 4); + field = new UIIntVarField(position, *v, "%s", 0, 4, 1, 4); T_SimpleList::Insert(field); v = project_->FindVariable(VAR_SOFTCLIP_GAIN); - position._x += 13; + position._x += 7; field = new UIIntVarField(position, *v, "%s", 0, 1, 1, 1); T_SimpleList::Insert(field); - position._x -= 13; + position._x -= 7; v = project_->FindVariable(VAR_TRANSPOSE); position._y += 2; - UIIntVarField *f2=new UIIntVarField(position,*v,"Transpose: %3.2d",-48,48,0x1,0xC) ; - T_SimpleList::Insert(f2) ; + UIIntVarField *f2 = + new UIIntVarField(position, *v, "%+3.2d", -48, 48, 0x1, 0xC); + T_SimpleList::Insert(f2) ; v = project_->FindVariable(VAR_SCALE); // if scale name is not found, set the default chromatic scale @@ -149,48 +153,47 @@ ProjectView::ProjectView(GUIWindow &w,ViewData *data):FieldView(w,data) { v->SetInt(0); } position._y += 1; - field = - new UIIntVarField(position, *v, "Scale: %s", 0, scaleCount - 1, 1, 10); + field = new UIIntVarField(position, *v, "%s", 0, scaleCount - 1, 1, 10); T_SimpleList::Insert(field); position._y += 2; - UIActionField *a1 = - new UIActionField("Compact Sequencer", ACTION_PURGE, position); + UIActionField *a1 = new UIActionField("Sequencer", ACTION_PURGE, position); a1->AddObserver(*this); T_SimpleList::Insert(a1); - position._y += 1; - a1 = new UIActionField("Compact Instruments", ACTION_PURGE_INSTRUMENT, - position); + position._x += 10; + a1 = new UIActionField("Instruments", ACTION_PURGE_INSTRUMENT, position); a1->AddObserver(*this); T_SimpleList::Insert(a1); + position._x -= 10; position._y += 2; - a1 = new UIActionField("Load Song", ACTION_LOAD, position); + a1 = new UIActionField("Load", ACTION_LOAD, position); a1->AddObserver(*this); T_SimpleList::Insert(a1); - position._y += 1; - a1 = new UIActionField("Save Song", ACTION_SAVE, position); + position._x += 5; + a1 = new UIActionField("Save", ACTION_SAVE, position); a1->AddObserver(*this); T_SimpleList::Insert(a1); - position._y += 1; - a1 = new UIActionField("Save Song As", ACTION_SAVE_AS, position); + position._x += 5; + a1 = new UIActionField("Save As", ACTION_SAVE_AS, position); a1->AddObserver(*this); T_SimpleList::Insert(a1); + position._x -= 10; v = project_->FindVariable(VAR_MIDIDEVICE); NAssert(v); position._y += 2; - field = new UIIntVarField(position, *v, "MIDI: %s", 0, + field = new UIIntVarField(position, *v, "%s", 0, MidiService::GetInstance()->Size(), 1, 1); T_SimpleList::Insert(field); position._y += 2; v = project_->FindVariable(VAR_RENDER); NAssert(v); - field = new UIIntVarField(position, *v, "Render: %s", 0, + field = new UIIntVarField(position, *v, "%s", 0, project_->MAX_RENDER_MODE - 1, 1, 2); T_SimpleList::Insert(field); @@ -243,14 +246,30 @@ void ProjectView::DrawView() { GUITextProperties props ; GUIPoint pos=GetTitlePosition() ; -// Draw title - - char projectString[80] ; - sprintf(projectString, "Project (Build %s.%s.%s)", PROJECT_NUMBER, - PROJECT_RELEASE, BUILD_COUNT); - + // Draw title SetColor(CD_NORMAL); - DrawString(pos._x,pos._y,projectString,props) ; + DrawString(pos._x, pos._y, "Project", props); + + // Draw Row labels + pos=GetAnchor(); + SetColor(CD_COL_TITLE); + DrawLabel(pos._x-1, pos._y, 0,"Tempo") ; + DrawLabel(pos._x-2,pos._y+1, 1,"Master") ; + DrawLabel(pos._x-1,pos._y+3, 2,"Drive") ; + DrawLabel(pos._x, pos._y+4, 3,4,"Type") ; + DrawLabel(pos._x-5,pos._y+6, 5,"Transpose") ; + DrawLabel(pos._x-1,pos._y+7, 6,"Scale") ; + DrawLabel(pos._x-3,pos._y+9, 7,8,"Compact") ; + DrawLabel(pos._x-3,pos._y+11,9,11, "Project") ; + DrawLabel(pos._x, pos._y+13,12, "Midi") ; + DrawLabel(pos._x-2,pos._y+15,13, "Render") ; + + // Draw version + SetColor(CD_SONGVIEWFE); + char projectString[80] ; + sprintf(projectString, "Build %s.%s.%s", + PROJECT_NUMBER, PROJECT_RELEASE, BUILD_COUNT); + DrawString(SCREEN_WIDTH - strlen(projectString), SCREEN_HEIGHT - 1 , projectString, props); FieldView::Redraw(); drawMap();