{"id":16218078,"url":"https://github.com/quasilyte/xm","last_synced_at":"2025-10-06T21:54:01.221Z","repository":{"id":201167592,"uuid":"707116408","full_name":"quasilyte/xm","owner":"quasilyte","description":"XM package provides Ebitengine-compatible mod music decoder","archived":false,"fork":false,"pushed_at":"2025-09-06T06:51:14.000Z","size":78,"stargazers_count":22,"open_issues_count":2,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-09-06T08:35:36.917Z","etag":null,"topics":["audio","ebiten","ebitengine","gamedev","go","golang","music","parser","pcm","player","stream","xm","xm-files"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quasilyte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-10-19T08:56:20.000Z","updated_at":"2025-09-06T06:51:18.000Z","dependencies_parsed_at":"2023-10-29T20:29:58.798Z","dependency_job_id":"317320da-7ecb-418f-a3e5-17d8b6cef4a1","html_url":"https://github.com/quasilyte/xm","commit_stats":null,"previous_names":["quasilyte/xm"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/quasilyte/xm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasilyte%2Fxm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasilyte%2Fxm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasilyte%2Fxm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasilyte%2Fxm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quasilyte","download_url":"https://codeload.github.com/quasilyte/xm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasilyte%2Fxm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278686638,"owners_count":26028325,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio","ebiten","ebitengine","gamedev","go","golang","music","parser","pcm","player","stream","xm","xm-files"],"created_at":"2024-10-10T11:48:26.216Z","updated_at":"2025-10-06T21:54:01.188Z","avatar_url":"https://github.com/quasilyte.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# xm\n\n![Build Status](https://github.com/quasilyte/xm/workflows/Go/badge.svg)\n[![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/quasilyte/xm)](https://pkg.go.dev/mod/github.com/quasilyte/xm)\n\nThis package is intended to be used in game development in Go with [Ebitengine](https://github.com/hajimehoshi/ebiten/).\n\nIf you just need to parse an XM file, you can use the `xm/xmfile` package without importing the `xm` package itself.\n\nThe `xm` package provides an XM music stream that produces 16-bit signed PCM LE data. This process can be describes as:\n\n1. Read and decode the XM file (`xmfile` package)\n2. Convert XM file data into something optimized for playing\n3. Create a player object that can go through this data and produce PCM chunks\n\nThis package implements some of the common XM effects. Feel free to submit a PR to fill the feature gap.\n\nWhy would you even need an XM player in your game? The answer is simple: size. This is very important in web exports of your game. An average OGG file can have a size of 6-8mb while the same song in XM can fit in ~300kb or even less.\n\n## Installation\n\n```bash\ngo get github.com/quasilyte/xm\n```\n\n## Quick Start\n\n1. Create a parser to decode XM files into Go objects.\n\n```go\n// import \"github.com/quasilyte/xm/xmfile\"\n// See ParserConfig docs to learn the options available.\nxmParser := xmfile.NewParser(xmfile.ParserConfig{})\n```\n\n2. Decode the XM files that you want to work with.\n\n```go\n// xmModule can be manipulated as needed, it's just data after all.\n// You can add some effects to the module, or mute some instruments, etc.\n//\n// There is also a Parse method that uses an io.Reader instead of []byte.\nxmData, _ := os.ReadFile(\"path/to/music.xm\")\nxmModule, err := xmParser.ParseFromBytes(xmData)\n```\n\n3. Compile an XM module into a playable stream.\n\n```go\n// import \"github.com/quasilyte/xm\"\n// You can re-load a module into a stream by using LoadModule again.\n// See LoadModuleConfig docs to learn the options available.\nxmStream := xm.NewStream()\nerr := xmStream.LoadModule(xmModule, xm.LoadModuleConfig{})\n```\n\n4. Use some audio driver to play the PCM data.\n\n```go\n// This example uses Ebitengine audio.\n// This library produces 16-bit signed PCM LE data.\nsampleRate := 44100\naudioContext := audio.NewContext(sampleRate)\nplayer, err := audioContext.NewPlayer(xmStream)\n\n// Now player object can be used to play the XM track.\n```\n\nThere is an XM event listener API available too.\n\nYou don't have to use Ebitengine, but this library was created with Ebitengine in mind.\n\nSee [cmd/ebitengine-example](cmd/ebitengine-example/main.go) for a full example.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquasilyte%2Fxm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquasilyte%2Fxm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquasilyte%2Fxm/lists"}