ruby_dsp 0.0.8 → 0.0.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d0352100ed3bc4d5984dd4b59ca7540eea006a7234eb2ed9a87ca88c61af3c91
4
- data.tar.gz: 94b1b8182701c588618dbbe6e44f9135a73c62c9b8f174d745f5e807df379145
3
+ metadata.gz: d044ff97e82f0fdedd8749cfa07573fd350cd793094d9274700e623caf35e098
4
+ data.tar.gz: 2559e81b76c114cfa10dff50aa422bb29a933def9b75a2893c8f53c12a76f619
5
5
  SHA512:
6
- metadata.gz: 17e977dd018f850f37210a0d4cc9abd209ad276f51f62792fb240ccb94a8d096f8f8ff7d59a201b21cab38e048b901ed93e4ff9c89809c281d2b923816bb2641
7
- data.tar.gz: d807466791df6a0f6cac661dc77e763cd03c5aeb2dd251d969054ff2bda5d0321735f4615819233f9ed9fdb9bb51f3b8b0eaf2e886d7269f29c1595aa616bc0d
6
+ metadata.gz: 97c853452400908572b918d94460ded68831dbb7d550f648a8291147d6fbdcee5e75e8ba36715622ed0dd90f978b1547a9661523c1d80b93b1f0b8ed2139bd66
7
+ data.tar.gz: 1d6a9728f02760fa579858c83e2a81c28c486cfcd9dc556cf0f8d6106389a373c2f4444364b5a6acacb3821a16cabad396e7e9c9cc30f9c046dc4b91fa06f70d
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # [RubyDSP](https://github.com/cichrrad/rubyDSP) | [Documentation](https://www.rubydoc.info/gems/ruby_dsp/0.0.8)
1
+ # [RubyDSP](https://github.com/cichrrad/rubyDSP) | [Documentation](https://www.rubydoc.info/gems/ruby_dsp/0.0.9)
2
2
 
3
3
  [![Ruby CI](https://github.com/cichrrad/rubyDSP/actions/workflows/test.yml/badge.svg)](https://github.com/cichrrad/rubyDSP/actions/workflows/test.yml)
4
4
 
5
- > 🚧 **Status:** This (***HOBBY***) project is currently in early development. It is hopefully functional, but API changes are expected. There is no warranty regarding anything 🗿.
5
+ > 🚧 **Status:** This (***HOBBY***) project is currently in early development. It is functional, but API changes are expected. There is no warranty regarding anything 🗿.
6
6
 
7
7
  ---
8
8
 
@@ -30,7 +30,7 @@ I made this gem to try hands-on binding these two languages together, as I would
30
30
 
31
31
  ## Overview of Capabilities
32
32
 
33
- * **File Operations:** `save_track`
33
+ * **File Operations:** `save_track`, `dup`
34
34
  * **Mutations:** `to_mono!`, `resample!`, `trim_silence!`, `normalize!`, `fade_in!`, `fade_out!`, `pad!`, `pad_to_duration!`, `clip!`
35
35
  * **DSP Filters:** `low_pass!`, `high_pass!`, `band_pass!`, `notch!`, `peak_eq!`, `low_shelf!`, `high_shelf!`
36
36
  * **Synthesis:** `add_wave!`
@@ -34,9 +34,33 @@ struct AudioTrack
34
34
  std::vector<float> samples;
35
35
  unsigned long long sample_count = 0;
36
36
 
37
- AudioTrack(std::string f, unsigned int target_channels = 0, unsigned int target_sample_rate = 0) : filename(f)
37
+ // static float get_file_duration(std::string filename)
38
+ // {
39
+ // if (filename.empty())
40
+ // return 0.0f;
41
+
42
+ // ma_decoder decoder;
43
+ // // NULL config means it reads the file's native format/rate
44
+ // if (ma_decoder_init_file(filename.c_str(), NULL, &decoder) != MA_SUCCESS)
45
+ // {
46
+ // throw std::runtime_error("RubyDSP: Could not process audio file for duration: " + filename);
47
+ // }
48
+
49
+ // ma_uint64 totalFrames;
50
+ // if (ma_decoder_get_length_in_pcm_frames(&decoder, &totalFrames) != MA_SUCCESS)
51
+ // {
52
+ // ma_decoder_uninit(&decoder);
53
+ // throw std::runtime_error("RubyDSP: Could not determine track length.");
54
+ // }
55
+
56
+ // int sample_rate = decoder.outputSampleRate;
57
+ // ma_decoder_uninit(&decoder);
58
+
59
+ // return (float)totalFrames / sample_rate;
60
+ // }
61
+
62
+ AudioTrack(std::string f, unsigned int target_channels = 0, unsigned int target_sample_rate = 0, float start_sec = 0.0f, float duration_sec = 0.0f) : filename(f)
38
63
  {
39
-
40
64
  // empty constructor
41
65
  if (filename.empty())
42
66
  {
@@ -70,14 +94,49 @@ struct AudioTrack
70
94
  throw std::runtime_error("RubyDSP: Could not determine track length.");
71
95
  }
72
96
 
73
- sample_count = totalFrames * channels;
97
+ ma_uint64 start_frame = (ma_uint64)(start_sec * sample_rate);
98
+ if (start_frame > totalFrames)
99
+ {
100
+ start_frame = totalFrames; // Prevent seeking past EOF
101
+ }
102
+
103
+ if (start_frame > 0)
104
+ {
105
+ if (ma_decoder_seek_to_pcm_frame(&decoder, start_frame) != MA_SUCCESS)
106
+ {
107
+ ma_decoder_uninit(&decoder);
108
+ throw std::runtime_error("RubyDSP: Could not seek to start frame.");
109
+ }
110
+ }
111
+
112
+ ma_uint64 framesToRead = totalFrames - start_frame;
113
+ if (duration_sec > 0.0f)
114
+ {
115
+ ma_uint64 requestedFrames = (ma_uint64)(duration_sec * sample_rate);
116
+ if (requestedFrames < framesToRead)
117
+ {
118
+ framesToRead = requestedFrames;
119
+ }
120
+ }
121
+
122
+ sample_count = framesToRead * channels;
74
123
  samples.resize(sample_count);
75
124
 
76
- ma_uint64 framesRead;
77
- if (ma_decoder_read_pcm_frames(&decoder, samples.data(), totalFrames, &framesRead) != MA_SUCCESS)
125
+ if (framesToRead > 0)
78
126
  {
79
- ma_decoder_uninit(&decoder);
80
- throw std::runtime_error("RubyDSP: Failed to read PCM data.");
127
+ ma_uint64 framesRead;
128
+ if (ma_decoder_read_pcm_frames(&decoder, samples.data(), framesToRead, &framesRead) != MA_SUCCESS)
129
+ {
130
+ ma_decoder_uninit(&decoder);
131
+ throw std::runtime_error("RubyDSP: Failed to read PCM data.");
132
+ }
133
+
134
+ // Shrink vector if we hit EOF earlier than expected
135
+ if (framesRead < framesToRead)
136
+ {
137
+ sample_count = framesRead * channels;
138
+ samples.resize(sample_count);
139
+ }
81
140
  }
82
141
 
83
142
  ma_decoder_uninit(&decoder);
@@ -904,6 +963,11 @@ struct AudioTrack
904
963
  << sample_rate << "Hz sample rate]";
905
964
  return stream.str();
906
965
  }
966
+
967
+ AudioTrack dup()
968
+ {
969
+ return *this;
970
+ }
907
971
  };
908
972
 
909
973
  extern "C"
@@ -916,10 +980,12 @@ extern "C"
916
980
  {
917
981
  Module rb_mRubyDSP = define_module("RubyDSP");
918
982
  Data_Type<AudioTrack> rb_cAudioTrack = define_class_under<AudioTrack>(rb_mRubyDSP, "AudioTrack")
919
- .define_constructor(Constructor<AudioTrack, std::string, unsigned int, unsigned int>(),
983
+ .define_constructor(Constructor<AudioTrack, std::string, unsigned int, unsigned int, float, float>(),
920
984
  Arg("file_name") = (std::string) "",
921
985
  Arg("target_channels") = (unsigned int)0,
922
- Arg("target_sample_rate") = (unsigned int)0)
986
+ Arg("target_sample_rate") = (unsigned int)0,
987
+ Arg("start_sec") = 0.0f,
988
+ Arg("duration_sec") = 0.0f)
923
989
  // attributes
924
990
  .define_attr("file_name", &AudioTrack::filename, Rice::AttrAccess::Read)
925
991
  .define_attr("channels", &AudioTrack::channels, Rice::AttrAccess::Read)
@@ -991,5 +1057,7 @@ extern "C"
991
1057
  Arg("cutoff_freq"),
992
1058
  Arg("gain_db"),
993
1059
  Arg("q") = 0.707)
994
- .define_method("to_s", &AudioTrack::to_s);
1060
+ .define_method("to_s", &AudioTrack::to_s)
1061
+ .define_method("dup", &AudioTrack::dup)
1062
+ .define_method("clone", &AudioTrack::dup);
995
1063
  }