runapi-suno 0.2.4 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +45 -0
- data/lib/runapi/suno/client.rb +57 -9
- data/lib/runapi/suno/resources/add_instrumental.rb +1 -0
- data/lib/runapi/suno/resources/add_vocals.rb +1 -0
- data/lib/runapi/suno/resources/boost_style.rb +1 -0
- data/lib/runapi/suno/resources/check_voice.rb +31 -0
- data/lib/runapi/suno/resources/convert_audio.rb +1 -0
- data/lib/runapi/suno/resources/cover_audio.rb +1 -0
- data/lib/runapi/suno/resources/create_mashup.rb +1 -0
- data/lib/runapi/suno/resources/extend_music.rb +1 -0
- data/lib/runapi/suno/resources/generate_artwork.rb +1 -0
- data/lib/runapi/suno/resources/generate_lyrics.rb +1 -0
- data/lib/runapi/suno/resources/generate_midi.rb +1 -0
- data/lib/runapi/suno/resources/generate_persona.rb +1 -0
- data/lib/runapi/suno/resources/generate_voice.rb +41 -0
- data/lib/runapi/suno/resources/get_timestamped_lyrics.rb +1 -0
- data/lib/runapi/suno/resources/regenerate_validation_phrase.rb +41 -0
- data/lib/runapi/suno/resources/replace_section.rb +1 -0
- data/lib/runapi/suno/resources/separate_audio_stems.rb +1 -0
- data/lib/runapi/suno/resources/text_to_music.rb +1 -0
- data/lib/runapi/suno/resources/text_to_sound.rb +1 -0
- data/lib/runapi/suno/resources/visualize_music.rb +1 -0
- data/lib/runapi/suno/resources/voice_to_validation_phrase.rb +41 -0
- data/lib/runapi/suno/types.rb +108 -26
- data/lib/runapi/suno/validators.rb +88 -26
- data/lib/runapi/suno.rb +4 -0
- metadata +16 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7408c126663eb2e648020669baa1dc31570c6df7eb74a2d38856c8ba25eb7d3e
|
|
4
|
+
data.tar.gz: 69968db8a1c4d03cafe72847d036be448f8eadb2edc7797445660371c700807a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3cfaaa5a15a681d6ce11f36c8c04d116a245191f2148da349d71b0429fc931421e315d9bfe81faebabde0dc077afe7779969fa1eccc728510d43c5f3dda280f6
|
|
7
|
+
data.tar.gz: 0c40c4d0cd2e6a45dc2c30614217b994caf48ce3e6871f3c8945e918bbae174f66b0fae6e3a11452f5dadcf48093f721e2045dca0c9014972395d8e3c34b652b
|
data/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Suno AI API Ruby SDK for RunAPI
|
|
2
|
+
|
|
3
|
+
The suno ai api Ruby SDK is the language-specific package for Suno on RunAPI. Use this suno ai api package for song generation, lyrics, vocal, extension, and audio transformation flows when your application needs JSON request bodies, task status lookup, and consistent RunAPI errors in Ruby.
|
|
4
|
+
|
|
5
|
+
This suno ai api README is the Ruby package guide inside the public `suno-sdk` repository. For the repository overview, start at `../README.md`; for model details, use https://runapi.ai/models/suno; for API reference, use https://runapi.ai/docs#suno; for SDK docs, use https://runapi.ai/docs#sdk-suno.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
gem install runapi-suno
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
require "runapi-suno"
|
|
17
|
+
|
|
18
|
+
client = RunApi::Suno::Client.new
|
|
19
|
+
task = client.generations.create(
|
|
20
|
+
# Pass the Suno JSON request body from https://runapi.ai/docs#suno.
|
|
21
|
+
)
|
|
22
|
+
status = client.generations.get(task.id)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Use `create` when you want to submit a task and return quickly, `get` when you need the latest task state, and `run` when a script should create and poll until completion. In web request handlers, prefer `create` plus webhook or later `get` polling so a worker is not held open.
|
|
26
|
+
|
|
27
|
+
RunAPI-generated file URLs are temporary. Download and store generated images, videos, audio, or other files in your own durable storage within 7 days; do not treat returned URLs as long-term assets.
|
|
28
|
+
|
|
29
|
+
## Language notes
|
|
30
|
+
|
|
31
|
+
Use Ruby keyword arguments and the `RunApi::Suno` error classes when building music jobs, Rails workers, or scripts. The available resources include generations, extensions, upload and extensions, covers, upload and covers, instrumentals, vocals, vocal removals, midi, wav conversions, music videos, lyrics, timestamped lyrics, section replacements, mashups, sounds, personas, and styles. Keep `RUNAPI_API_KEY` in the environment or your secret manager; never commit API keys or callback secrets.
|
|
32
|
+
|
|
33
|
+
## Links
|
|
34
|
+
|
|
35
|
+
- Model page: https://runapi.ai/models/suno
|
|
36
|
+
- SDK docs: https://runapi.ai/docs#sdk-suno
|
|
37
|
+
- Product docs: https://runapi.ai/docs#suno
|
|
38
|
+
- Pricing and rate limits: https://runapi.ai/models/suno/v4
|
|
39
|
+
- Provider comparison: https://runapi.ai/providers/suno
|
|
40
|
+
- Full catalog: https://runapi.ai/models
|
|
41
|
+
- Repository: https://github.com/runapi-ai/suno-sdk
|
|
42
|
+
|
|
43
|
+
## License
|
|
44
|
+
|
|
45
|
+
Licensed under the Apache License, Version 2.0.
|
data/lib/runapi/suno/client.rb
CHANGED
|
@@ -2,17 +2,61 @@
|
|
|
2
2
|
|
|
3
3
|
module RunApi
|
|
4
4
|
module Suno
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
# Suno music platform client covering song generation, extension, covers, stems,
|
|
6
|
+
# MIDI, lyrics, mashups, sound effects, visualization, personas, and voice cloning.
|
|
7
|
+
#
|
|
8
|
+
# @example Generate a song from a text prompt
|
|
9
|
+
# client = RunApi::Suno::Client.new(api_key: "sk-your-api-key")
|
|
10
|
+
# result = client.text_to_music.run(
|
|
11
|
+
# prompt: "A chill lo-fi beat with soft vocals",
|
|
12
|
+
# model: "suno-v4.5-plus"
|
|
13
|
+
# )
|
|
14
|
+
class Client < RunApi::Core::Client
|
|
15
|
+
# @return [Resources::TextToMusic] generates songs from a text prompt with configurable vocal mode, style, and persona
|
|
16
|
+
attr_reader :text_to_music
|
|
17
|
+
# @return [Resources::ExtendMusic] continues an existing track from a specified timestamp
|
|
18
|
+
attr_reader :extend_music
|
|
19
|
+
# @return [Resources::GenerateArtwork] creates cover artwork for an existing music task
|
|
20
|
+
attr_reader :generate_artwork
|
|
21
|
+
# @return [Resources::CoverAudio] re-records vocals over an uploaded audio file with a new style or voice
|
|
22
|
+
attr_reader :cover_audio
|
|
23
|
+
# @return [Resources::AddInstrumental] generates and adds an instrumental backing track to uploaded audio
|
|
24
|
+
attr_reader :add_instrumental
|
|
25
|
+
# @return [Resources::AddVocals] generates and adds vocals to an uploaded instrumental track
|
|
26
|
+
attr_reader :add_vocals
|
|
27
|
+
# @return [Resources::SeparateAudioStems] splits a track into individual instrument stems
|
|
28
|
+
attr_reader :separate_audio_stems
|
|
29
|
+
# @return [Resources::GenerateMidi] extracts per-instrument MIDI note data from a generated track
|
|
30
|
+
attr_reader :generate_midi
|
|
31
|
+
# @return [Resources::ConvertAudio] converts a generated track to WAV format
|
|
32
|
+
attr_reader :convert_audio
|
|
33
|
+
# @return [Resources::VisualizeMusic] generates a music visualization video from an existing track
|
|
34
|
+
attr_reader :visualize_music
|
|
35
|
+
# @return [Resources::GenerateLyrics] produces AI-generated lyrics from a text prompt
|
|
36
|
+
attr_reader :generate_lyrics
|
|
37
|
+
# @return [Resources::GetTimestampedLyrics] retrieves word-level timing alignment for a track (synchronous)
|
|
38
|
+
attr_reader :get_timestamped_lyrics
|
|
39
|
+
# @return [Resources::ReplaceSection] re-generates a time range within an existing track
|
|
40
|
+
attr_reader :replace_section
|
|
41
|
+
# @return [Resources::CreateMashup] blends two audio tracks into a single new composition
|
|
42
|
+
attr_reader :create_mashup
|
|
43
|
+
# @return [Resources::TextToSound] generates sound effects from a text description
|
|
44
|
+
attr_reader :text_to_sound
|
|
45
|
+
# @return [Resources::VoiceToValidationPhrase] step 1 of voice cloning: extracts a validation phrase
|
|
46
|
+
attr_reader :voice_to_validation_phrase
|
|
47
|
+
# @return [Resources::RegenerateValidationPhrase] step 2 (optional) of voice cloning: requests a new phrase
|
|
48
|
+
attr_reader :regenerate_validation_phrase
|
|
49
|
+
# @return [Resources::GenerateVoice] step 3 of voice cloning: trains a custom voice
|
|
50
|
+
attr_reader :generate_voice
|
|
51
|
+
# @return [Resources::CheckVoice] step 4 of voice cloning: checks whether a custom voice is ready (synchronous)
|
|
52
|
+
attr_reader :check_voice
|
|
53
|
+
# @return [Resources::GeneratePersona] creates a reusable style or voice persona from a track's vocals (synchronous)
|
|
54
|
+
attr_reader :generate_persona
|
|
55
|
+
# @return [Resources::BoostStyle] generates style/genre tags from a text description (synchronous)
|
|
56
|
+
attr_reader :boost_style
|
|
10
57
|
|
|
11
58
|
def initialize(api_key: nil, **options)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
client_options = Core::ClientOptions.new(api_key: @api_key, **options)
|
|
15
|
-
http = client_options.http_client || Core::HttpClient.new(client_options)
|
|
59
|
+
super
|
|
16
60
|
|
|
17
61
|
@text_to_music = Resources::TextToMusic.new(http)
|
|
18
62
|
@extend_music = Resources::ExtendMusic.new(http)
|
|
@@ -29,6 +73,10 @@ module RunApi
|
|
|
29
73
|
@replace_section = Resources::ReplaceSection.new(http)
|
|
30
74
|
@create_mashup = Resources::CreateMashup.new(http)
|
|
31
75
|
@text_to_sound = Resources::TextToSound.new(http)
|
|
76
|
+
@voice_to_validation_phrase = Resources::VoiceToValidationPhrase.new(http)
|
|
77
|
+
@regenerate_validation_phrase = Resources::RegenerateValidationPhrase.new(http)
|
|
78
|
+
@generate_voice = Resources::GenerateVoice.new(http)
|
|
79
|
+
@check_voice = Resources::CheckVoice.new(http)
|
|
32
80
|
@generate_persona = Resources::GeneratePersona.new(http)
|
|
33
81
|
@boost_style = Resources::BoostStyle.new(http)
|
|
34
82
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RunApi
|
|
4
|
+
module Suno
|
|
5
|
+
module Resources
|
|
6
|
+
# Step 4 of voice cloning: checks whether a custom voice is ready for use. Synchronous (run only).
|
|
7
|
+
class CheckVoice
|
|
8
|
+
include RunApi::Core::ResourceHelpers
|
|
9
|
+
|
|
10
|
+
ENDPOINT = "/api/v1/suno/check_voice"
|
|
11
|
+
RESPONSE_CLASS = Types::CheckVoiceResponse
|
|
12
|
+
|
|
13
|
+
def initialize(http)
|
|
14
|
+
@http = http
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def run(**params)
|
|
18
|
+
params = compact_params(params)
|
|
19
|
+
validate_params!(params)
|
|
20
|
+
request(:post, ENDPOINT, body: params)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def validate_params!(params)
|
|
26
|
+
Validators.validate_check_voice!(params, self)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RunApi
|
|
4
|
+
module Suno
|
|
5
|
+
module Resources
|
|
6
|
+
# Step 3 of voice cloning: trains a custom voice from the user's recording of the validation phrase.
|
|
7
|
+
class GenerateVoice
|
|
8
|
+
include RunApi::Core::ResourceHelpers
|
|
9
|
+
|
|
10
|
+
ENDPOINT = "/api/v1/suno/generate_voice"
|
|
11
|
+
RESPONSE_CLASS = Types::VoiceGenerationResponse
|
|
12
|
+
COMPLETED_RESPONSE_CLASS = Types::CompletedVoiceGenerationResponse
|
|
13
|
+
|
|
14
|
+
def initialize(http)
|
|
15
|
+
@http = http
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def run(**params)
|
|
19
|
+
task = create(**params)
|
|
20
|
+
poll_until_complete { get(task.id) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def create(**params)
|
|
24
|
+
params = compact_params(params)
|
|
25
|
+
validate_params!(params)
|
|
26
|
+
request(:post, ENDPOINT, body: params)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def get(id)
|
|
30
|
+
request(:get, "#{ENDPOINT}/#{id}")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def validate_params!(params)
|
|
36
|
+
Validators.validate_generate_voice!(params, self)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RunApi
|
|
4
|
+
module Suno
|
|
5
|
+
module Resources
|
|
6
|
+
# Step 2 (optional) of voice cloning: requests a new, easier validation phrase.
|
|
7
|
+
class RegenerateValidationPhrase
|
|
8
|
+
include RunApi::Core::ResourceHelpers
|
|
9
|
+
|
|
10
|
+
ENDPOINT = "/api/v1/suno/regenerate_validation_phrase"
|
|
11
|
+
RESPONSE_CLASS = Types::ValidationPhraseResponse
|
|
12
|
+
COMPLETED_RESPONSE_CLASS = Types::CompletedValidationPhraseResponse
|
|
13
|
+
|
|
14
|
+
def initialize(http)
|
|
15
|
+
@http = http
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def run(**params)
|
|
19
|
+
task = create(**params)
|
|
20
|
+
poll_until_complete { get(task.id) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def create(**params)
|
|
24
|
+
params = compact_params(params)
|
|
25
|
+
validate_params!(params)
|
|
26
|
+
request(:post, ENDPOINT, body: params)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def get(id)
|
|
30
|
+
request(:get, "#{ENDPOINT}/#{id}")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def validate_params!(params)
|
|
36
|
+
Validators.validate_regenerate_validation_phrase!(params, self)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RunApi
|
|
4
|
+
module Suno
|
|
5
|
+
module Resources
|
|
6
|
+
# Step 1 of voice cloning: extracts a validation phrase from a voice recording for the user to re-record.
|
|
7
|
+
class VoiceToValidationPhrase
|
|
8
|
+
include RunApi::Core::ResourceHelpers
|
|
9
|
+
|
|
10
|
+
ENDPOINT = "/api/v1/suno/voice_to_validation_phrase"
|
|
11
|
+
RESPONSE_CLASS = Types::ValidationPhraseResponse
|
|
12
|
+
COMPLETED_RESPONSE_CLASS = Types::CompletedValidationPhraseResponse
|
|
13
|
+
|
|
14
|
+
def initialize(http)
|
|
15
|
+
@http = http
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def run(**params)
|
|
19
|
+
task = create(**params)
|
|
20
|
+
poll_until_complete { get(task.id) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def create(**params)
|
|
24
|
+
params = compact_params(params)
|
|
25
|
+
validate_params!(params)
|
|
26
|
+
request(:post, ENDPOINT, body: params)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def get(id)
|
|
30
|
+
request(:get, "#{ENDPOINT}/#{id}")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def validate_params!(params)
|
|
36
|
+
Validators.validate_voice_to_validation_phrase!(params, self)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/runapi/suno/types.rb
CHANGED
|
@@ -2,18 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
module RunApi
|
|
4
4
|
module Suno
|
|
5
|
+
# Suno type definitions, response models, and enum constants.
|
|
5
6
|
module Types
|
|
6
|
-
|
|
7
|
+
# Suno music generation engine versions. V5.5 has highest quality; V4 is the earliest available.
|
|
8
|
+
MODELS = %w[suno-v5.5 suno-v5 suno-v4.5-plus suno-v4.5-all suno-v4.5 suno-v4].freeze
|
|
9
|
+
# Model versions that support sound effect generation (subset of MODELS).
|
|
7
10
|
SOUND_MODELS = %w[suno-v5 suno-v5.5].freeze
|
|
11
|
+
# Musical keys (major and minor) for sound effect generation.
|
|
8
12
|
SOUND_KEYS = %w[
|
|
9
13
|
Cm C#m Dm D#m Em Fm F#m Gm G#m Am A#m Bm
|
|
10
14
|
C C# D D# E F F# G G# A A# B
|
|
11
15
|
].freeze
|
|
12
|
-
VOCAL_GENDERS = %w[
|
|
13
|
-
|
|
16
|
+
VOCAL_GENDERS = %w[female male].freeze
|
|
17
|
+
# "style" applies genre/mood without changing voice; "voice" applies cloned voice characteristics.
|
|
18
|
+
PERSONA_TYPES = %w[style voice].freeze
|
|
19
|
+
# "source" inherits settings from the original track; "custom" requires explicit values.
|
|
20
|
+
PARAMETER_MODES = %w[source custom].freeze
|
|
21
|
+
# auto_lyrics: generates from prompt; exact_lyrics: sings literal lyrics; instrumental: no vocals.
|
|
22
|
+
VOCAL_MODES = %w[auto_lyrics exact_lyrics instrumental].freeze
|
|
23
|
+
# separate_vocal: isolates vocals+instrumental; split_stem: splits into all individual instruments.
|
|
14
24
|
SEPARATE_AUDIO_STEMS_TYPES = %w[separate_vocal split_stem].freeze
|
|
25
|
+
# Language for the voice-cloning validation phrase the user must read back.
|
|
26
|
+
VALIDATION_PHRASE_LANGUAGES = %w[en zh es fr pt de ja ko hi ru].freeze
|
|
27
|
+
# Singing ability of the voice being cloned; calibrates model expectations.
|
|
28
|
+
SINGER_SKILL_LEVELS = %w[beginner intermediate advanced professional].freeze
|
|
15
29
|
|
|
30
|
+
# Metadata and URLs for a generated music track.
|
|
16
31
|
class Audio < RunApi::Core::BaseModel
|
|
32
|
+
optional :id, String
|
|
33
|
+
optional :audio_url, String
|
|
34
|
+
optional :stream_audio_url, String
|
|
35
|
+
optional :image_url, String
|
|
36
|
+
optional :lyrics, String
|
|
37
|
+
optional :model_name, String
|
|
38
|
+
optional :title, String
|
|
39
|
+
optional :tags, [String]
|
|
40
|
+
optional :duration, Numeric
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Metadata and URLs for a generated sound effect (distinct from music Audio).
|
|
44
|
+
class SoundAudio < RunApi::Core::BaseModel
|
|
17
45
|
optional :id, String
|
|
18
46
|
optional :audio_url, String
|
|
19
47
|
optional :stream_audio_url, String
|
|
@@ -21,14 +49,16 @@ module RunApi
|
|
|
21
49
|
optional :prompt, String
|
|
22
50
|
optional :model_name, String
|
|
23
51
|
optional :title, String
|
|
24
|
-
optional :tags, [
|
|
52
|
+
optional :tags, [String]
|
|
25
53
|
optional :duration, Numeric
|
|
26
54
|
end
|
|
27
55
|
|
|
56
|
+
# A URL to a generated cover artwork image.
|
|
28
57
|
class Cover < RunApi::Core::BaseModel
|
|
29
58
|
required :url, String
|
|
30
59
|
end
|
|
31
60
|
|
|
61
|
+
# Word-level timing alignment for a single word in a track.
|
|
32
62
|
class AlignedWord < RunApi::Core::BaseModel
|
|
33
63
|
required :word, String
|
|
34
64
|
required :success
|
|
@@ -37,6 +67,7 @@ module RunApi
|
|
|
37
67
|
required :palign, Numeric
|
|
38
68
|
end
|
|
39
69
|
|
|
70
|
+
# URLs for each isolated instrument stem after separation. Only populated stems have URLs.
|
|
40
71
|
class SeparatedAudio < RunApi::Core::BaseModel
|
|
41
72
|
optional :vocal_url, String
|
|
42
73
|
optional :instrumental_url, String
|
|
@@ -54,6 +85,7 @@ module RunApi
|
|
|
54
85
|
optional :woodwinds_url, String
|
|
55
86
|
end
|
|
56
87
|
|
|
88
|
+
# A single MIDI note event within an instrument track.
|
|
57
89
|
class MidiNote < RunApi::Core::BaseModel
|
|
58
90
|
required :pitch, Numeric
|
|
59
91
|
required :start_time, Numeric
|
|
@@ -61,22 +93,26 @@ module RunApi
|
|
|
61
93
|
required :velocity, Numeric
|
|
62
94
|
end
|
|
63
95
|
|
|
96
|
+
# All notes for a single instrument extracted from a track.
|
|
64
97
|
class MidiInstrument < RunApi::Core::BaseModel
|
|
65
98
|
required :name, String
|
|
66
|
-
optional :notes, [
|
|
99
|
+
optional :notes, [-> { MidiNote }]
|
|
67
100
|
end
|
|
68
101
|
|
|
102
|
+
# A section of generated lyrics with an optional section title (e.g. "Chorus", "Verse 1").
|
|
69
103
|
class Lyric < RunApi::Core::BaseModel
|
|
70
104
|
optional :title, String
|
|
71
105
|
required :text, String
|
|
72
106
|
end
|
|
73
107
|
|
|
108
|
+
# A reusable style or voice persona, referenced by ID in generation params.
|
|
74
109
|
class Persona < RunApi::Core::BaseModel
|
|
75
110
|
required :id, String
|
|
76
111
|
required :name, String
|
|
77
112
|
required :description, String
|
|
78
113
|
end
|
|
79
114
|
|
|
115
|
+
# Base response for all Suno async tasks, carrying lifecycle status and generation progress.
|
|
80
116
|
class AsyncTaskResponse < RunApi::Core::TaskResponse
|
|
81
117
|
required :id, String
|
|
82
118
|
required :status, String, enum: -> { RunApi::Core::TaskResponse::Status::ALL }
|
|
@@ -84,99 +120,137 @@ module RunApi
|
|
|
84
120
|
optional :error, String
|
|
85
121
|
end
|
|
86
122
|
|
|
123
|
+
# Result of a text-to-music generation task.
|
|
87
124
|
class TextToMusicResponse < AsyncTaskResponse
|
|
88
|
-
optional :audios, [
|
|
125
|
+
optional :audios, [-> { Audio }]
|
|
89
126
|
optional :audio_url, String
|
|
90
127
|
end
|
|
91
128
|
|
|
129
|
+
# Result of a music extension task. +original_task_id+ references the source track.
|
|
92
130
|
class ExtendMusicResponse < AsyncTaskResponse
|
|
93
|
-
optional :audios, [
|
|
131
|
+
optional :audios, [-> { Audio }]
|
|
94
132
|
optional :original_task_id, String
|
|
95
133
|
end
|
|
96
134
|
|
|
135
|
+
# Result of an artwork generation task containing cover image URLs.
|
|
97
136
|
class GenerateArtworkResponse < AsyncTaskResponse
|
|
98
|
-
optional :covers, [
|
|
137
|
+
optional :covers, [-> { Cover }]
|
|
99
138
|
end
|
|
100
139
|
|
|
140
|
+
# Result of a cover audio task.
|
|
101
141
|
class CoverAudioResponse < AsyncTaskResponse
|
|
102
|
-
optional :audios, [
|
|
142
|
+
optional :audios, [-> { Audio }]
|
|
103
143
|
end
|
|
104
144
|
|
|
145
|
+
# Result of adding an instrumental backing track.
|
|
105
146
|
class AddInstrumentalResponse < TextToMusicResponse; end
|
|
147
|
+
# Result of adding vocals to a track.
|
|
106
148
|
class AddVocalsResponse < TextToMusicResponse; end
|
|
107
|
-
class TextToSoundResponse < TextToMusicResponse; end
|
|
108
149
|
|
|
150
|
+
# Result of a sound effect generation task (uses SoundAudio instead of Audio).
|
|
151
|
+
class TextToSoundResponse < AsyncTaskResponse
|
|
152
|
+
optional :audios, [-> { SoundAudio }]
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Result of a stem separation task.
|
|
109
156
|
class SeparateAudioStemsResponse < AsyncTaskResponse
|
|
110
157
|
optional :separated_audios, -> { SeparatedAudio }
|
|
111
158
|
end
|
|
112
159
|
|
|
160
|
+
# Result of a MIDI extraction task with per-instrument note data.
|
|
113
161
|
class GenerateMidiResponse < AsyncTaskResponse
|
|
114
|
-
optional :instruments, [
|
|
162
|
+
optional :instruments, [-> { MidiInstrument }]
|
|
115
163
|
end
|
|
116
164
|
|
|
165
|
+
# Result of a WAV conversion task.
|
|
117
166
|
class ConvertAudioResponse < AsyncTaskResponse
|
|
118
167
|
optional :wav_url, String
|
|
119
168
|
optional :original_task_id, String
|
|
120
169
|
end
|
|
121
170
|
|
|
171
|
+
# Result of a music visualization task containing the generated video URL.
|
|
122
172
|
class VisualizeMusicResponse < AsyncTaskResponse
|
|
123
173
|
optional :video_url, String
|
|
124
174
|
optional :original_task_id, String
|
|
125
175
|
end
|
|
126
176
|
|
|
177
|
+
# Result of a lyrics generation task with sectioned lyrics.
|
|
127
178
|
class GenerateLyricsResponse < AsyncTaskResponse
|
|
128
|
-
optional :lyrics, [
|
|
179
|
+
optional :lyrics, [-> { Lyric }]
|
|
129
180
|
end
|
|
130
181
|
|
|
182
|
+
# Synchronous response containing word-level timing data and waveform for a track.
|
|
131
183
|
class GetTimestampedLyricsResponse < RunApi::Core::BaseModel
|
|
132
|
-
optional :aligned_words, [
|
|
133
|
-
optional :waveform_data, [
|
|
184
|
+
optional :aligned_words, [-> { AlignedWord }]
|
|
185
|
+
optional :waveform_data, [Numeric]
|
|
134
186
|
optional :hoot_cer, Numeric
|
|
135
187
|
optional :is_streamed
|
|
136
188
|
end
|
|
137
189
|
|
|
190
|
+
# Result of a section replacement task.
|
|
138
191
|
class ReplaceSectionResponse < AsyncTaskResponse
|
|
139
192
|
optional :track, -> { Audio }
|
|
140
|
-
optional :audios, [
|
|
193
|
+
optional :audios, [-> { Audio }]
|
|
141
194
|
end
|
|
142
195
|
|
|
196
|
+
# Synchronous result of persona creation.
|
|
143
197
|
class GeneratePersonaResponse < RunApi::Core::BaseModel
|
|
144
198
|
required :persona, -> { Persona }
|
|
145
199
|
optional :error, String
|
|
146
200
|
end
|
|
147
201
|
|
|
202
|
+
# Synchronous result of style tag generation. +style+ contains the generated tags string.
|
|
148
203
|
class BoostStyleResponse < RunApi::Core::BaseModel
|
|
149
204
|
optional :style, String
|
|
150
205
|
optional :error, String
|
|
151
206
|
end
|
|
152
207
|
|
|
208
|
+
# Result of a mashup task.
|
|
153
209
|
class CreateMashupResponse < AsyncTaskResponse
|
|
154
210
|
optional :audio, -> { Audio }
|
|
155
|
-
optional :audios, [
|
|
211
|
+
optional :audios, [-> { Audio }]
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Result of a voice-cloning validation phrase task. The user must re-record this phrase.
|
|
215
|
+
class ValidationPhraseResponse < AsyncTaskResponse
|
|
216
|
+
optional :provider_status, String
|
|
217
|
+
optional :validation_phrase, String
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Result of a voice generation (training) task. +voice_id+ is usable in subsequent generation params.
|
|
221
|
+
class VoiceGenerationResponse < AsyncTaskResponse
|
|
222
|
+
optional :provider_status, String
|
|
223
|
+
optional :voice_id, String
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Synchronous result indicating whether a custom voice is ready for use.
|
|
227
|
+
class CheckVoiceResponse < RunApi::Core::BaseModel
|
|
228
|
+
optional :is_available
|
|
229
|
+
optional :error, String
|
|
156
230
|
end
|
|
157
231
|
|
|
158
232
|
class CompletedTextToMusicResponse < TextToMusicResponse
|
|
159
|
-
required :audios, [
|
|
233
|
+
required :audios, [-> { Audio }]
|
|
160
234
|
end
|
|
161
235
|
|
|
162
236
|
class CompletedExtendMusicResponse < ExtendMusicResponse
|
|
163
|
-
required :audios, [
|
|
237
|
+
required :audios, [-> { Audio }]
|
|
164
238
|
end
|
|
165
239
|
|
|
166
240
|
class CompletedGenerateArtworkResponse < GenerateArtworkResponse
|
|
167
|
-
required :covers, [
|
|
241
|
+
required :covers, [-> { Cover }]
|
|
168
242
|
end
|
|
169
243
|
|
|
170
244
|
class CompletedCoverAudioResponse < CoverAudioResponse
|
|
171
|
-
required :audios, [
|
|
245
|
+
required :audios, [-> { Audio }]
|
|
172
246
|
end
|
|
173
247
|
|
|
174
248
|
class CompletedAddInstrumentalResponse < AddInstrumentalResponse
|
|
175
|
-
required :audios, [
|
|
249
|
+
required :audios, [-> { Audio }]
|
|
176
250
|
end
|
|
177
251
|
|
|
178
252
|
class CompletedAddVocalsResponse < AddVocalsResponse
|
|
179
|
-
required :audios, [
|
|
253
|
+
required :audios, [-> { Audio }]
|
|
180
254
|
end
|
|
181
255
|
|
|
182
256
|
class CompletedSeparateAudioStemsResponse < SeparateAudioStemsResponse
|
|
@@ -184,7 +258,7 @@ module RunApi
|
|
|
184
258
|
end
|
|
185
259
|
|
|
186
260
|
class CompletedGenerateMidiResponse < GenerateMidiResponse
|
|
187
|
-
required :instruments, [
|
|
261
|
+
required :instruments, [-> { MidiInstrument }]
|
|
188
262
|
end
|
|
189
263
|
|
|
190
264
|
class CompletedConvertAudioResponse < ConvertAudioResponse
|
|
@@ -196,7 +270,7 @@ module RunApi
|
|
|
196
270
|
end
|
|
197
271
|
|
|
198
272
|
class CompletedGenerateLyricsResponse < GenerateLyricsResponse
|
|
199
|
-
required :lyrics, [
|
|
273
|
+
required :lyrics, [-> { Lyric }]
|
|
200
274
|
end
|
|
201
275
|
|
|
202
276
|
class CompletedReplaceSectionResponse < ReplaceSectionResponse
|
|
@@ -204,11 +278,19 @@ module RunApi
|
|
|
204
278
|
end
|
|
205
279
|
|
|
206
280
|
class CompletedCreateMashupResponse < CreateMashupResponse
|
|
207
|
-
required :audios, [
|
|
281
|
+
required :audios, [-> { Audio }]
|
|
208
282
|
end
|
|
209
283
|
|
|
210
284
|
class CompletedTextToSoundResponse < TextToSoundResponse
|
|
211
|
-
required :audios, [
|
|
285
|
+
required :audios, [-> { SoundAudio }]
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
class CompletedValidationPhraseResponse < ValidationPhraseResponse
|
|
289
|
+
required :validation_phrase, String
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
class CompletedVoiceGenerationResponse < VoiceGenerationResponse
|
|
293
|
+
required :voice_id, String
|
|
212
294
|
end
|
|
213
295
|
end
|
|
214
296
|
end
|
|
@@ -5,34 +5,34 @@ module RunApi
|
|
|
5
5
|
module Validators
|
|
6
6
|
module_function
|
|
7
7
|
|
|
8
|
+
MUSIC_PROMPT_SHAPE_ERROR = "choose a valid vocal_mode: auto_lyrics, exact_lyrics, or instrumental"
|
|
9
|
+
|
|
8
10
|
def validate_text_to_music!(params, resource)
|
|
9
|
-
|
|
10
|
-
require_param!(resource, params, :style)
|
|
11
|
-
require_param!(resource, params, :title)
|
|
12
|
-
else
|
|
13
|
-
require_param!(resource, params, :prompt)
|
|
14
|
-
end
|
|
11
|
+
validate_music_prompt_shape!(params, resource)
|
|
15
12
|
require_param!(resource, params, :model)
|
|
13
|
+
validate_optional!(resource, params, :vocal_mode, Types::VOCAL_MODES)
|
|
16
14
|
validate_optional!(resource, params, :model, Types::MODELS)
|
|
17
15
|
validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
|
|
18
|
-
validate_optional!(resource, params, :
|
|
16
|
+
validate_optional!(resource, params, :persona_type, Types::PERSONA_TYPES)
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
def validate_extend_music!(params, resource)
|
|
22
20
|
unless %i[task_id audio_id audio_url upload_url].any? { |key| param(resource, params, key) }
|
|
23
21
|
raise Core::ValidationError, "task_id, audio_id, audio_url, or upload_url is required"
|
|
24
22
|
end
|
|
25
|
-
require_param!(resource, params, :
|
|
23
|
+
require_param!(resource, params, :parameter_mode)
|
|
26
24
|
require_param!(resource, params, :model)
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
validate_optional!(resource, params, :parameter_mode, Types::PARAMETER_MODES)
|
|
27
|
+
if param(resource, params, :parameter_mode) == "custom"
|
|
29
28
|
require_param!(resource, params, :style)
|
|
30
29
|
require_param!(resource, params, :title)
|
|
31
30
|
require_param!(resource, params, :continue_at)
|
|
32
31
|
end
|
|
32
|
+
validate_extend_music_prompt_shape!(params, resource)
|
|
33
33
|
validate_optional!(resource, params, :model, Types::MODELS)
|
|
34
34
|
validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
|
|
35
|
-
validate_optional!(resource, params, :
|
|
35
|
+
validate_optional!(resource, params, :persona_type, Types::PERSONA_TYPES)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def validate_generate_artwork!(params, resource)
|
|
@@ -42,15 +42,11 @@ module RunApi
|
|
|
42
42
|
def validate_cover_audio!(params, resource)
|
|
43
43
|
require_param!(resource, params, :upload_url)
|
|
44
44
|
require_param!(resource, params, :model)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
require_param!(resource, params, :title)
|
|
48
|
-
else
|
|
49
|
-
require_param!(resource, params, :prompt)
|
|
50
|
-
end
|
|
45
|
+
validate_music_prompt_shape!(params, resource)
|
|
46
|
+
validate_optional!(resource, params, :vocal_mode, Types::VOCAL_MODES)
|
|
51
47
|
validate_optional!(resource, params, :model, Types::MODELS)
|
|
52
48
|
validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
|
|
53
|
-
validate_optional!(resource, params, :
|
|
49
|
+
validate_optional!(resource, params, :persona_type, Types::PERSONA_TYPES)
|
|
54
50
|
end
|
|
55
51
|
|
|
56
52
|
def validate_add_instrumental!(params, resource)
|
|
@@ -60,7 +56,7 @@ module RunApi
|
|
|
60
56
|
end
|
|
61
57
|
|
|
62
58
|
def validate_add_vocals!(params, resource)
|
|
63
|
-
require_all!(resource, params, :upload_url, :
|
|
59
|
+
require_all!(resource, params, :upload_url, :lyrics, :title, :negative_tags, :style, :model)
|
|
64
60
|
validate_optional!(resource, params, :model, Types::MODELS)
|
|
65
61
|
validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
|
|
66
62
|
end
|
|
@@ -91,7 +87,7 @@ module RunApi
|
|
|
91
87
|
end
|
|
92
88
|
|
|
93
89
|
def validate_replace_section!(params, resource)
|
|
94
|
-
require_all!(resource, params, :task_id, :audio_id, :
|
|
90
|
+
require_all!(resource, params, :task_id, :audio_id, :lyrics, :tags, :title, :infill_start_time, :infill_end_time)
|
|
95
91
|
if param(resource, params, :infill_end_time).to_f <= param(resource, params, :infill_start_time).to_f
|
|
96
92
|
raise Core::ValidationError, "infill_end_time must be greater than infill_start_time"
|
|
97
93
|
end
|
|
@@ -103,14 +99,11 @@ module RunApi
|
|
|
103
99
|
raise Core::ValidationError, "upload_url_list must contain exactly 2 URLs"
|
|
104
100
|
end
|
|
105
101
|
require_param!(resource, params, :model)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
require_param!(resource, params, :prompt) unless truthy?(param(resource, params, :instrumental))
|
|
109
|
-
else
|
|
110
|
-
require_param!(resource, params, :prompt)
|
|
111
|
-
end
|
|
102
|
+
validate_music_prompt_shape!(params, resource)
|
|
103
|
+
validate_optional!(resource, params, :vocal_mode, Types::VOCAL_MODES)
|
|
112
104
|
validate_optional!(resource, params, :model, Types::MODELS)
|
|
113
105
|
validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
|
|
106
|
+
validate_optional!(resource, params, :persona_type, Types::PERSONA_TYPES)
|
|
114
107
|
end
|
|
115
108
|
|
|
116
109
|
def validate_text_to_sound!(params, resource)
|
|
@@ -123,6 +116,30 @@ module RunApi
|
|
|
123
116
|
end
|
|
124
117
|
end
|
|
125
118
|
|
|
119
|
+
def validate_voice_to_validation_phrase!(params, resource)
|
|
120
|
+
require_all!(resource, params, :voice_url, :vocal_start_seconds, :vocal_end_seconds)
|
|
121
|
+
validate_optional!(resource, params, :language, Types::VALIDATION_PHRASE_LANGUAGES)
|
|
122
|
+
|
|
123
|
+
start_seconds = param(resource, params, :vocal_start_seconds).to_i
|
|
124
|
+
end_seconds = param(resource, params, :vocal_end_seconds).to_i
|
|
125
|
+
return if end_seconds > start_seconds
|
|
126
|
+
|
|
127
|
+
raise Core::ValidationError, "vocal_end_seconds must be greater than vocal_start_seconds"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def validate_regenerate_validation_phrase!(params, resource)
|
|
131
|
+
require_param!(resource, params, :task_id)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def validate_generate_voice!(params, resource)
|
|
135
|
+
require_all!(resource, params, :task_id, :verify_url)
|
|
136
|
+
validate_optional!(resource, params, :singer_skill_level, Types::SINGER_SKILL_LEVELS)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def validate_check_voice!(params, resource)
|
|
140
|
+
require_param!(resource, params, :task_id)
|
|
141
|
+
end
|
|
142
|
+
|
|
126
143
|
def validate_generate_persona!(params, resource)
|
|
127
144
|
require_all!(resource, params, :task_id, :audio_id, :name, :description)
|
|
128
145
|
end
|
|
@@ -131,6 +148,45 @@ module RunApi
|
|
|
131
148
|
require_param!(resource, params, :description)
|
|
132
149
|
end
|
|
133
150
|
|
|
151
|
+
def validate_music_prompt_shape!(params, resource)
|
|
152
|
+
mode = param(resource, params, :vocal_mode).to_s
|
|
153
|
+
has_prompt = truthy_presence?(param(resource, params, :prompt))
|
|
154
|
+
has_lyrics = truthy_presence?(param(resource, params, :lyrics))
|
|
155
|
+
has_style = truthy_presence?(param(resource, params, :style))
|
|
156
|
+
has_title = truthy_presence?(param(resource, params, :title))
|
|
157
|
+
|
|
158
|
+
valid_shape = case mode
|
|
159
|
+
when "auto_lyrics"
|
|
160
|
+
has_prompt && !has_lyrics && !has_style && !has_title
|
|
161
|
+
when "exact_lyrics"
|
|
162
|
+
!has_prompt && has_lyrics && has_style && has_title
|
|
163
|
+
when "instrumental"
|
|
164
|
+
!has_prompt && !has_lyrics && has_style && has_title
|
|
165
|
+
else
|
|
166
|
+
false
|
|
167
|
+
end
|
|
168
|
+
return if valid_shape
|
|
169
|
+
|
|
170
|
+
raise Core::ValidationError, MUSIC_PROMPT_SHAPE_ERROR
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def validate_extend_music_prompt_shape!(params, resource)
|
|
174
|
+
return unless truthy_presence?(param(resource, params, :lyrics))
|
|
175
|
+
|
|
176
|
+
if truthy_presence?(param(resource, params, :prompt))
|
|
177
|
+
raise Core::ValidationError, "prompt cannot be combined with lyrics"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
if truthy?(param(resource, params, :instrumental))
|
|
181
|
+
raise Core::ValidationError, "lyrics cannot be used when instrumental is true"
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
upload_mode = %i[audio_url upload_url].any? { |key| truthy_presence?(param(resource, params, key)) }
|
|
185
|
+
return if param(resource, params, :parameter_mode) == "custom" && upload_mode
|
|
186
|
+
|
|
187
|
+
raise Core::ValidationError, "lyrics can only be used when extending uploaded audio with custom parameters"
|
|
188
|
+
end
|
|
189
|
+
|
|
134
190
|
def require_all!(resource, params, *keys)
|
|
135
191
|
keys.each { |key| require_param!(resource, params, key) }
|
|
136
192
|
end
|
|
@@ -148,7 +204,13 @@ module RunApi
|
|
|
148
204
|
end
|
|
149
205
|
|
|
150
206
|
def truthy?(value)
|
|
151
|
-
[
|
|
207
|
+
[true, 1, "1", "true", "TRUE", "True"].include?(value)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def truthy_presence?(value)
|
|
211
|
+
return !value.empty? if value.respond_to?(:empty?)
|
|
212
|
+
|
|
213
|
+
!value.nil?
|
|
152
214
|
end
|
|
153
215
|
end
|
|
154
216
|
end
|
data/lib/runapi/suno.rb
CHANGED
|
@@ -18,6 +18,10 @@ require_relative "suno/resources/get_timestamped_lyrics"
|
|
|
18
18
|
require_relative "suno/resources/replace_section"
|
|
19
19
|
require_relative "suno/resources/create_mashup"
|
|
20
20
|
require_relative "suno/resources/text_to_sound"
|
|
21
|
+
require_relative "suno/resources/voice_to_validation_phrase"
|
|
22
|
+
require_relative "suno/resources/regenerate_validation_phrase"
|
|
23
|
+
require_relative "suno/resources/generate_voice"
|
|
24
|
+
require_relative "suno/resources/check_voice"
|
|
21
25
|
require_relative "suno/resources/generate_persona"
|
|
22
26
|
require_relative "suno/resources/boost_style"
|
|
23
27
|
require_relative "suno/client"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: runapi-suno
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- RunAPI
|
|
@@ -15,28 +15,34 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.2.
|
|
18
|
+
version: 0.2.6
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.2.
|
|
26
|
-
description:
|
|
25
|
+
version: 0.2.6
|
|
26
|
+
description: The suno ai api Ruby SDK is the language-specific package for Suno on
|
|
27
|
+
RunAPI. Use this suno ai api package for song generation, lyrics, vocal, extension,
|
|
28
|
+
and audio transformation flows when your application needs JSON request bodies,
|
|
29
|
+
task status lookup, and consistent RunAPI errors in Ruby.
|
|
27
30
|
email:
|
|
28
31
|
- contact@runapi.ai
|
|
29
32
|
executables: []
|
|
30
33
|
extensions: []
|
|
31
|
-
extra_rdoc_files:
|
|
34
|
+
extra_rdoc_files:
|
|
35
|
+
- README.md
|
|
32
36
|
files:
|
|
33
37
|
- LICENSE
|
|
38
|
+
- README.md
|
|
34
39
|
- lib/runapi-suno.rb
|
|
35
40
|
- lib/runapi/suno.rb
|
|
36
41
|
- lib/runapi/suno/client.rb
|
|
37
42
|
- lib/runapi/suno/resources/add_instrumental.rb
|
|
38
43
|
- lib/runapi/suno/resources/add_vocals.rb
|
|
39
44
|
- lib/runapi/suno/resources/boost_style.rb
|
|
45
|
+
- lib/runapi/suno/resources/check_voice.rb
|
|
40
46
|
- lib/runapi/suno/resources/convert_audio.rb
|
|
41
47
|
- lib/runapi/suno/resources/cover_audio.rb
|
|
42
48
|
- lib/runapi/suno/resources/create_mashup.rb
|
|
@@ -45,12 +51,15 @@ files:
|
|
|
45
51
|
- lib/runapi/suno/resources/generate_lyrics.rb
|
|
46
52
|
- lib/runapi/suno/resources/generate_midi.rb
|
|
47
53
|
- lib/runapi/suno/resources/generate_persona.rb
|
|
54
|
+
- lib/runapi/suno/resources/generate_voice.rb
|
|
48
55
|
- lib/runapi/suno/resources/get_timestamped_lyrics.rb
|
|
56
|
+
- lib/runapi/suno/resources/regenerate_validation_phrase.rb
|
|
49
57
|
- lib/runapi/suno/resources/replace_section.rb
|
|
50
58
|
- lib/runapi/suno/resources/separate_audio_stems.rb
|
|
51
59
|
- lib/runapi/suno/resources/text_to_music.rb
|
|
52
60
|
- lib/runapi/suno/resources/text_to_sound.rb
|
|
53
61
|
- lib/runapi/suno/resources/visualize_music.rb
|
|
62
|
+
- lib/runapi/suno/resources/voice_to_validation_phrase.rb
|
|
54
63
|
- lib/runapi/suno/types.rb
|
|
55
64
|
- lib/runapi/suno/validators.rb
|
|
56
65
|
homepage: https://runapi.ai/models/suno
|
|
@@ -58,7 +67,7 @@ licenses:
|
|
|
58
67
|
- Apache-2.0
|
|
59
68
|
metadata:
|
|
60
69
|
homepage_uri: https://runapi.ai/models/suno
|
|
61
|
-
documentation_uri: https://github.com/runapi-ai/suno-sdk/blob/main/README.md
|
|
70
|
+
documentation_uri: https://github.com/runapi-ai/suno-sdk/blob/main/ruby/README.md
|
|
62
71
|
source_code_uri: https://github.com/runapi-ai/suno-sdk
|
|
63
72
|
changelog_uri: https://github.com/runapi-ai/suno-sdk/blob/main/CHANGELOG.md
|
|
64
73
|
rdoc_options: []
|
|
@@ -77,5 +86,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
77
86
|
requirements: []
|
|
78
87
|
rubygems_version: 4.0.10
|
|
79
88
|
specification_version: 4
|
|
80
|
-
summary: Suno API
|
|
89
|
+
summary: Suno AI API Ruby SDK for RunAPI
|
|
81
90
|
test_files: []
|